Self referencing has_many :through relationship

Hey,

Trying to set up a self referencing has_many :through relationship but one of my fields in my join table is not getting filled in.

Here’s all the code:

Coaster.rb

has_many :incarnations
has_many :coaster_versions,
through: :incarnations

Incarnation.rb
belongs_to :coaster
belongs_to :coaster_version,
class_name: “Coaster”

When I add a record to Coaster I do it like so:

coaster.incarnations.create!(coaster_version: coaster)

With this, the coaster_id field in the Incarnations table is filled in but not the coaster_versions_id field. Any idea how I can get this field to fill in?

Thanks

Is coaster in the example supposed to be a coaster_version ? So,

coaster.incarnations.create!(coaster_version: coaster_version)

Sorry, My mistake in my post with a typo there.

Basically I run an import from a CSV which creates Coasters. Before creating the new Coaster, it checks if a certain attribute of the one it is to create already exists (it’s an id type attribute but not a unique id, for another purpose). If it already exists then it adds it as normal but should add a record to the Incarnations table.

So if a record does exist I store that as c and the newly created Coaster as coaster so I then run:

coaster.incarnations.create!(coaster_version: c) – See the difference from my OP?

But the problem is that the coaster_version_id does not get filled in. It should be filled in with the id of c.

So, if the coaster_version already exists, can you do something like:

coaster.coaster_versions << c

That should work.

I’ll try this when I get back and post my result. Thanks

Just come back to look at this and can’t see how this would work. Maybe I am going about this the wrong way.

Basically if a record that I am importing has a certain attribute id the same as an already existing record then I want to the new record to relate to the first one via this relationship. How would this be accomplished?

I guess I don’t understand what you’re asking.

if you have a coaster with an id and a coaster_version with an id (meaning, they’ve both been persisted), then coaster.coaster_versions << coaster_version will create the join table entry (incantation) This is how AR Associations work, AFAIK.

Did you try it?

But I don’t have a Coaster Version. I don;t have a model called CoasterVersion.

I don’t believe you can self join with a has_many :through. A self join usually looks like this:

class Employee < ActiveRecord::Base  
  has_many :subordinates, class_name: "Employee",                          
                          foreign_key: "manager_id"   
  belongs_to :manager, class_name: "Employee"
end

Take a look at the Rails guides for self referencing: http://guides.rubyonrails.org/association_basics.html#self-joins

Do you have a join table called CoasterVersion? The code that you posted in your OP you needs 3 tables and models to work. See: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Also, we might be able to help you better if we could see your controller code.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.