PlankTon
PlankTon

Reputation: 12605

Rails ActiveRecord: two has_one relationships between the same models

I have a model, Project, that has 2 associations to the same model:

belongs_to :source_connection, class: Connection
belongs_to :destination_connection, class: Connection

That works fine - I can access connection methods through project without any issues.

I'm a little confused on how to do the inverse, however. I started with a rather optimistic:

has_one :project

on the Connection model, and unsurprisingly, it throws an

ActiveModel::MissingAttributeError: can't write unknown attribute 'connection_id'

error when I try to access the project from the connection itself.

If anyone knows how I can declare the association on the connection side, I'd be appreciative. Cheers.

Upvotes: 1

Views: 1751

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

Associations

You will probably be best looking at the foreign_key arguments for ActiveRecord Associations:

#app/models/project.rb
Class Project < ActiveRecord::Base
   belongs_to :source_connection, class: "Connection", foreign_key: "source_connection_id"
   belongs_to :destination_connection, class: "Connection", foreign_key: "destination_connection_id"
end

#app/models/connection.rb
Class Connection < ActiveRecord::Base
   has_many :projects, foreign_key: "source_connection_id"
end

The issue you have is that since you're not using the foreign_key option in your associations, Rails will be looking for the standard foreign_key associations inside your schema (typically model_name_id).

--

Error

can't write unknown attribute 'connection_id'

I don't know why it's complaining about writing, but the reason is likely that you don't have the correct foreign key set up for your association. Typically, Rails will be looking for the model_name_id - but since you're not, you'll need to set the relative key in your models (as demonstrated)

Upvotes: 5

j-dexx
j-dexx

Reputation: 10406

has_one :project, foreign_key: 'source_connection_id'

Rails is looking for connection_id as the error says, as you've used source_connection and destination_connection you need to tell it to use the correct foreign key to look it up.

You might want to define them as:

has_one :source_project, foreign_key: 'source_connection_id'
has_one :destination_project, foreign_key: 'destination_connection_id'

Because you won't be able to call them both project.

Upvotes: 3

Related Questions