At least one entry for DB

Rails 3.1.3

I have models and their association like,

Video 1: -------- n: Script

When users newly create a Video, I want it to create the very first
Script entry together.

I have put

@script = Script.new(:video_id => @video.id, :startp => 0, :text =>

'ToDo: ')

in Video controller, ‘new’ action, but it doesn’t work (:startp value is
determined for the first one).

How can I create a Script entity together with Video?

Also, if possible, I want that first Script entry to be undestroyable.
Do you think I can do it?

Thanks in advance,

soichi

El mircoles 7 de marzo de 2012 10:01:30 UTC+1, Ruby-Forum.com User
escribi:

I have put
Do you think I can do it?

Thanks in advance,

soichi


Posted via http://www.ruby-forum.com/.

You can use either an after_create on the model or an observer which
observes a Video creation.
Personally, I usually prefer observers which seem less intrusive to me,
giving a better to make it active or unactive, but some people think the
other way.

To make your first script undestroyable, you can add a column to the
model
or a ‘before_destroy’ which checks if its the first Script created for a
given Video, a method to check this same condition and hide ‘destroy’
links… there is a lot of ways to do this.

Thanks for your answer.

I will try after_create.

I have put

after_create :create_first_script

def create_first_script
@video = Video.new(params[:video])
@script = Script.new(:video_id => @video.id, :startp => 0, :text =>
'ToDo: ')
end

in video.rb.
But I need to pass params[:video] somehow…

/videos/_form.html.erb (generated by scaffold) should do it, correct?

<%= form_for(@video) do |f| %>

<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :url %>
<%= f.text_field :url %>
<%= f.submit %>
<% end %>

I am not sure how to pass the video object from here.
Could anyone give me tips?

soichi

Thanks for you answer.

You have to first save the @video before accessing the id, that is when
the
after_create or after_save is triggered.
In your Video class, the after save has access to the @video instance
through the self keyword (self.id in your case).

I need to clarify this point.

When videos_controller.rb calls for ‘create’ action, a new instance gets
persisted, correct?
When doing so, ‘after_create’ is called as well. It seems to me that
when ‘after_create’ is called, the new video instance is already
created. Please correct me, if I’m wrong.

I tried this. but no good ( I knew it! )

after_create :create_first_script

def create_first_script
@script = Script.new(:video_id => self.id, :startp => 0, :text =>
'ToDo: ')
end

soichi

On 9 March 2012 02:15, Soichi I. [email protected] wrote:

When videos_controller.rb calls for ‘create’ action, a new instance gets
persisted, correct?
When doing so, ‘after_create’ is called as well. It seems to me that
when ‘after_create’ is called, the new video instance is already
created. Please correct me, if I’m wrong.

Calling the create action in the controller does not create it in the
database, it is the call of ‘save’ within the create action that saves
it to the database. The after_save callback will be called from
within save, after it is saved to the db and then the id will be
valid.

I tried this. but no good ( I knew it! )

after_create :create_first_script

def create_first_script
@script = Script.new(:video_id => self.id, :startp => 0, :text =>
'ToDo: ')
end

What do you think that code does? It creates a new object in memory,
but you have not saved it to the database, so after the method is
called your new object is immediately lost.

Colin

Hey,

The @video.id you are referring to is not yet existing as the @video
object
is not yet persisted into the db.
You have to first save the @video before accessing the id, that is when
the
after_create or after_save is triggered.
In your Video class, the after save has access to the @video instance
through the self keyword (self.id in your case).

Another solution to your problem would be to use nested attributes (see
accepts_nested_attributes_for in the rails docs)

I hope this helps.

Regards

Geoffroy

Op donderdag 8 maart 2012 03:41:40 UTC+1 schreef Ruby-Forum.com User het
volgende:

Indeed, you should save (persist) your object (script) after creating it
or
use the create (or create!) method instead or new:
@script = Script.new(:video_id => self.id, :startp => 0, :text => 'ToDo:
')
@scipt.save

or

@script = Script.create(:video_id => self.id, :startp => 0, :text =>
'ToDo:
')

regards

Geoffroy

Thanks! Finally I got it done.

after_save :create_first_script

private
def create_first_script
@script = Script.new(:video_id => self.id, :startp => 0, :text =>
'ToDo: ')
@script.save
end

soichi

But something like

@video = Video.new({…})
@script = @video.scripts.build({ :startp => 0, :text => 'ToDo: '})
@video.save

doesn’t work?

Il giorno mercoled 7 marzo 2012 10:01:30 UTC+1, Ruby-Forum.com User ha
scritto: