Tuma
Tuma

Reputation: 807

Trying to implement bidirectional self-referential association

(I'm translating the code as I write, so I apologize for any mistakes!)

I'm trying to implement a bidirectional self referential relation involving the Associates table and a join table Property. I tried following this post but something is still wrong.

The way it's supposed to work is, an associate can be the proprietor of zero or more associates, and consequently an associate may have zero or more proprietors (makes more sense in the context of the application).

So I created the Property model:

class CreateProperties < ActiveRecord::Migration
  def change
    create_table :properties do |t|
      t.integer :proprietor_id
      t.integer :property_id

      t.timestamps null: false
    end
  end
end

So the table contains only the ids of one proprietor and one property, both associates, per entry.

Following the tutorial linked above, I came to this configuration:

Associate.rb:

...
has_many :properties 
has_many :related_properties, :through => :properties
has_many :proprietors, :class_name => "Property", :foreign_key => "proprietor_id"
has_many :related_proprietors :through => :proprietors, :source => :associate
...

Property.rb:

belongs_to :associate
belongs_to :related_properties, :class_name => "Associate"

However when I try to use these relations (<% @associate.related_properties.each do |property| %>), I get this error:

PG::UndefinedColumn: ERROR:  column properties.related_properties_id does not exist
LINE 1: ... INNER JOIN "propriedades" ON "associados"."id" = "proprieda...
                                                             ^
: SELECT "associates".* FROM "associates" INNER JOIN "properties" ON "associates"."id" = "properties"."related_properties_id" WHERE "properties"."associate_id" = $1

Basically, the column names are wrong in the generated SQL: properties.related_properties_id should be properties.proprietor_id, and properties.associate_id should be properties.proprietor_id as well.

What have I done wrong, and how can I fix this code to get the correct relations?

Upvotes: 0

Views: 96

Answers (1)

max
max

Reputation: 101831

You need to setup two seperate associations since the foreign key on Property depends on what the Associates role is.

class Associate
  # defines relations where Associate is the "owning" party
  has_many :properties_as_proprietor, 
    class_name: 'Property',
    foreign_key: 'proprietor_id'
  has_many :properties, 
    through: :properties_as_property,
    source: :property # what to select on Property

  # defines relations where Associate is the "owned" party
  has_many :properties_as_property, 
    class_name: 'Property',
    foreign_key: 'property_id'
  has_many :proprietors, 
    through: :properties_as_proprietor,
    source: :proprietor # what to select on Property
end

class Property
  belongs_to :proprietor, class_name: 'Associate'
  belongs_to :property, class_name: 'Associate'
end

Upvotes: 1

Related Questions