ActiveRecord#create and associations

This is a dumb question, but I just want to double check and can't find an explicit reference online...

#So. say I have

class Person < ActiveRecord::Base

  belongs_to :phonebook ... end

#Let's say I have pb = to an instance of PhoneBook, then

#will this in general work?

x = Person.create(:phonebook => pb, ...)

# or do I have to do this:

x = Person.create(...) x.phonebook = pb x.save!

# or this:

x = Person.create(:phonebook_id => pb.id, ...)

Thanks!

-- Pito

Yes, either of those will work. Assuming Phonebook has_many :people as well, you should also be able to do:

pb.people.create(…)

The rails console is a great way to test these out and see if they will work within a few moments… :slight_smile:

Phil

the way to usually do it is ,

@person.phonebooks.new(params[:phonebook])

it will automatically associates the phonebook to the user, it is also an easy way of accessing associations in test.

Thanks... And the reason:

x = Person.create(:phonebook => pb, ...)

does not work is that the hash params for create have to be actual attributes of the model, and not associations?

-- Pito

Thanks… And the reason:

x = Person.create(:phonebook => pb, …)

does not work is that the hash params for create have to be actual

attributes of the model, and not associations?

It will work. You can do it any one of the ways that were mentioned.

redhames example is of creating a phonebook when you already have a Person; I thought you were speaking of creating a Person when you already have a Phonebook (pb) …? At any rate, all these example will work fine. Use the one that makes the most sense to you. :slight_smile:

x = Person.create(:phonebook => pb, ...)

does not work is that the hash params for create have to be actual attributes of the model, and not associations?

It _will_ work. You can do it any one of the ways that were mentioned.

Hmm, my test in script/console has it not working unless I specify the 'id', that is, unless I do this:

# specify id explicitly: x = Person.create(:phonebook_id => pb.id) x.save # works

# but # rely on association: x = Person.create(:phonebook => pb, ...) x.save # fails with a validation error: phonebook cannot be blank

is something more/or else messed up?

Pito

x = Person.create(:phonebook => pb, …)

does not work is that the hash params for create have to be actual

attributes of the model, and not associations?

It will work. You can do it any one of the ways that were mentioned.

Hmm, my test in script/console has it not working unless I specify the

‘id’, that is, unless I do this:

specify id explicitly:

x = Person.create(:phonebook_id => pb.id)

x.save # works

but

rely on association:

x = Person.create(:phonebook => pb, …)

x.save # fails with a validation error: phonebook cannot be blank

is something more/or else messed up?

Here’s a guess, after relooking over your code above. The problem could naming conventions.

When you say belongs_to :phonebook, Rails expects to look for a class named Phonebook (lowercase ‘b’), not PhoneBook

If your model is named PhoneBook, the association should be: belongs_to :phone_book

You can override the default behavior with something like:

belongs_to :phonebook, :class_name => ‘PhoneBook’

but it’s usually easier to do things the way Rails expects them to be done, unless there is an important reason to use different naming conventions.

Unless your model is not really PhoneBook…? the point is, the difference between PhoneBook and Phonebook, and phonebook or phone_book, is actually significant, and will cause you bugs and headaches if you don’t use the one rails will use by default.