I’m using Rails 4.2.3 I have a model with two relations to the same type of object,
class MyObject < ActiveRecord::Base
belongs_to :user
has_many :my_object_times
…
has_one :my_object_time, foreign_key: :linked_my_object_time_id
The column name in my database for the "has_one" is "linked_my_object_time_id." What I can’t figure out is how to write the model for the linked object. I know I need to put two “belongs_to” clauses, but I can’t figure out how to write the second one. So far I have
class MyObjectTime < ActiveRecord::Base
belongs_to :my_object
When I go to save my object …
my_object.linked_my_object_time = my_object_time
my_object.save
I get the error “NoMethodError (undefined method `linked_my_object_time=' for #”
Rails magically infers the foreign key of an association and its model name based on the association name. If the foreign key or model name differs from the association name, you must explicitly tell rails which class name and foreign key to use. Doing this will allow you to write your model with two relations.
It should look something like this:
class MyObject < ActiveRecord::Base
belongs_to :user
has_many :my_object_times
has_one :linked_my_object_time, class_name: 'MyObjectTime'
What happened here? I changed the name of the has_one association because it needs to be differentiated in name from the has_many relationship that rails will infer. There is no name clash in this file, but if you used has_many :my_object_times and has_one :my_object_time, you wouldn't be able to differentiate between the associations (ie. belongs_to :my_object) in the MyObjectTime model. Because I changed the association name, rails cannot infer the model name anymore so I specify it. But because rails generally adds _id to the association name, it should be able to infer the foreign key column of linked_my_object_time_id from the association name.
What about the MyObjectTime model?
class MyObjectTime < ActiveRecord::Base
belongs_to :my_object
belongs_to :whatever_you_want_to_call_it, class_name: 'MyObject', foreign_key: 'linked_my_object_time_id'
The first belongs_to is the reverse association for has_many: my_object_times and rails will look for the my_object_id column in the MyObjectTime table as expected. The second belongs_to has to have a different association name to be able to differentiate between the associations, and since the association name changed, I have to include the class name and the foreign_key since it cannot be inferred from the association name.
I got all of my information from here.
(EDIT: Fixed syntax in association)