Thank you Jason and David for your replies!
David said:
org = Organisation.new
org.name = "Aces High Inc."
person = NaturalPerson.new
person.name = "Fred Flinstone"
org.contact << person
NoMethodError: You have a nil object when you didn't expect it!
The << is only for collections, where you're adding one to many (like
library.books << some_book). Here there's only one of everything.
Brilliant! That's a bit of info that I didn't have.
The method you call on the object, for an association, is always the
name of the association itself. You have no association called
"contact":
My Organisation model looks like this:
class Organisation < ActiveRecord::Base
belongs_to :org_structure
belongs_to :natural_person, {:foreign_key => "contact"}
has_many :natural_people, :through => :associates
validates_associated :org_structure
end
OK, this sentence had to make me re-evaluate my understanding of what was going on!
I have defined a field "contact" in my table "organisations" and I was expecting this statement do set up the association:
belongs_to :natural_person, :foreign_key => "contact"
In my mind I was saying "Right, it's going to derive the class name from the association, so it will correctly get the NaturalPerson class and I've stated that the foreign key is called 'contact' so I can access that class through the 'contact' member".
OK, so that is wrong!
if you want to use org.contact, you need to change the
natural_person association to this:
belongs_to :contact,
:class_name => "NaturalPerson",
:foreign_key => "contact_id"
and make any corresponding changes in natural_person.rb
I do want to use org.contact, so I changed my model as per what you've put above:
class Organisation < ActiveRecord::Base
belongs_to :contact, {:class_name => "NaturalPerson", :foreign_key
=> "contact"}
The thing that hasn't clicked in my mind yet is that the association and foreign key have the same value - they are redundant (in my particular case). So I thought "Maybe the association name is the same as the field name by convention, but I could actually use any arbitrary name". So I tried this:
class Organisation < ActiveRecord::Base
belongs_to :foo, {:class_name => "NaturalPerson", :foreign_key =>
"contact"}
So if my presumption is correct, I can update the "contact" field in the database by playing with the "foo" association in the ActiveRecord.
>> org = Organisation.new
>> org.name = "Wacky Widgets Pty Ltd"
>> person = NaturalPerson.new
>> person.name = "Barney Rubble"
>> org.foo = person
>> org.save
>> puts org.foo.name
Barney Rubble
>> puts org.contact.name
NoMethodError: undefined method `name' for 2:Fixnum
from (irb):14
By George I think I've got it!
"Contact" is just a plain old integer, as I defined it in the ActiveRecord::Migration.
If I used "belongs_to" with the association name "contact" it will override the integer "contact" and add all the funkiness I'm looking for.
Thank you, thank you, thank you!