Вопрос

I'm looking to set up a self-referencing has_and_belongs_to_many relationship using rails 4, with a postgres db.

Basically I've got a Single Inheritance Table set up called Resource, which holds People, Places, and Things in it. (This works beautifully.)

create_table :resources do |t|
  t.string :name
  t.string :type
  t.text :description
end

I'm trying to create a 'has_and_belongs_to_many' relationship so that each Resource can have a series of 'owners', which will be an Relation of People. Each Person, in turn, will have a series of 'possessions'. Since it's a single table, I'll need to join the Resource table to itself.

My migration for the join table looks like this:

create_table :owners_possessions, id: false do |t|
  t.integer :owner_id        # the id of a person
  t.integer :possession_id   # the id of a place/thing owned by that person
end

Person.rb:

class Person < Resource

  has_and_belongs_to_many :possessions, class_name: :resources,
                                        join_table: :owners_possessions,
                                        foreign_key: :owner_id,
                                        association_foreign_key: :possession_id
end

Resource.rb:

class Resource < ActiveRecord::Base

  has_and_belongs_to_many :owners, class_name: :people,
                                   join_table: :owners_possessions,
                                   association_foreign_key: :possession_id,
                                   foreign_key: :owner_id
end

However, when running Resource.find(x).owners in the console, I get the following error message:

ActiveRecord::StatementInvalid: Could not find table 'resources_resources'

Which is perturbing because everything I've searched so far has pointed toward the join_table option as a way to get it looking at the right table.

Furthermore, running `Person.find(x).possessions' yields

NameError: uninitialized constant Person::Possession

What might I be missing here?

Это было полезно?

Решение

I can't reproduce the errors you posted, I suppose you altered your code somewhat.

Anyway, the class_name option in your associations should be the exact name of the other model. So 'Person' in singular form rather than :people:

class Person < Resource

  has_and_belongs_to_many :possessions, 
    class_name: 'Resource',
    join_table: :owners_possessions,
    foreign_key: :possession_id,
    association_foreign_key: :owner_id
end

class Resource < ActiveRecord::Base

  has_and_belongs_to_many :owners, 
    class_name: 'Person',
    join_table: :owners_possessions,
    association_foreign_key: :possession_id,
    foreign_key: :owner_id
end

Notice I also swapped the :foreign_key and :association_foreign_key values so they return the appropriate records.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top