在Rails 4中设置自引用HABTM关系

时间:2013-12-19 19:55:17

标签: ruby-on-rails postgresql ruby-on-rails-4 single-table-inheritance has-and-belongs-to-many

我正在寻找使用rails 4和postgres db设置自引用has_and_belongs_to_many关系。

基本上我有一个名为Resource的单一继承表,它包含People,Places和Things。 (这很好用。)

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

我正在尝试创建一个'has_and_belongs_to_many'关系,以便每个资源都可以拥有一系列'所有者',这将是一个人的关系。反过来,每个人都会有一系列“财产”。由于它是一个单独的表,我需要将Resource表连接到自身。

我对联接表的迁移如下所示:

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

但是,在控制台中运行Resource.find(x).owners时,出现以下错误消息:

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

这是令人不安的,因为到目前为止我搜索的所有内容都指向了join_table选项,以此来查看正确的表格。

此外,运行`Person.find(x).possessions'会产生

NameError: uninitialized constant Person::Possession

我在这里可能会缺少什么?

1 个答案:

答案 0 :(得分:1)

我无法重现您发布的错误,我想您在某种程度上更改了代码。

无论如何,关联中的class_name选项应该是其他模型的确切名称。所以'Person'以单数形式而不是: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

注意我还交换了:foreign_key:association_foreign_key值,以便返回相应的记录。