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.