【问题标题】:ActiveRecord::StatementInvalid on two namespaced models两个命名空间模型上的 ActiveRecord::StatementInvalid
【发布时间】:2019-02-10 19:52:13
【问题描述】:

我必须在同一个命名空间中拥有两个具有 habtm 关系的模型。

class Resource::Item < ApplicationRecord
    has_and_belongs_to_many :resource_sets, foreign_key: 'resource_item_id', class_name: 'Resource::Set', table_name: 'resource_items_sets'
end

class Resource::Set < ApplicationRecord
    has_and_belongs_to_many :resource_items, foreign_key: 'resource_set_id', class_name: 'Resource::Item', table_name: 'resource_items_sets'
end

已使用rails g migration CreateJoinTableResourceItemsResourceSets resource_item resource_set 生成迁移

class CreateJoinTableResourceItemsResourceSets < ActiveRecord::Migration[5.2]
    def change
        create_join_table :resource_items, :resource_sets do |t|
            # t.index [:resource_item_id, :resource_set_id]
            # t.index [:resource_set_id, :resource_item_id]
        end
    end
end

到目前为止,一切看起来都很棒。正在创建表resource_items_sets,其中包含resource_item_idresource_set_id 两列。

这是架构

create_table "resource_items_sets", id: false, force: :cascade do |t|
    t.bigint "resource_item_id", null: false
    t.bigint "resource_set_id", null: false
end

创建 resource_item 后,我得到以下符合预期的结果。

pry(main)> Resource::Item.first.resource_sets
=> #<Resource::Set::ActiveRecord_Associations_CollectionProxy:0x3fdd08748004>

但执行以下操作会引发错误。我期待0

pry(main)> Resource::Item.first.resource_sets.count
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column resource_items_sets.set_id does not exist
LINE 1: ...N "resource_items_sets" ON "resource_sets"."id" = "resource_...
                                                         ^
: SELECT "resource_sets"."id" FROM "resource_sets" INNER JOIN "resource_items_sets" ON "resource_sets"."id" = "resource_items_sets"."set_id" WHERE "resource_items_sets"."resource_item_id" = $1 ORDER BY "resource_sets"."name" ASC
from /Users/username/.rvm/gems/ruby-2.6.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `async_prepare'
Caused by PG::UndefinedColumn: ERROR:  column resource_items_sets.set_id does not exist
LINE 1: ...N "resource_items_sets" ON "resource_sets"."id" = "resource_...

resource_set_id 到处都被声明了,set_id 又从何而来?我该如何解决这个问题?我想保留两者的命名空间,因为我最终可能会创建项目并设置更多的命名空间。

非常感谢,伙计们!

【问题讨论】:

  • 尝试在迁移中传递表名,因为表名应该是resource_items_resource_sets,Rails 会根据表名猜测关联外键。

标签: ruby-on-rails postgresql rails-activerecord has-and-belongs-to-many


【解决方案1】:

您需要在连接表的两侧设置外键,因为在您的情况下无法推断它们。

在这种情况下,正确的 has_and_belongs_to_many 调用应如下所示:

  has_and_belongs_to_many :resource_items,
                          foreign_key: 'resource_set_id',
                          association_foreign_key: 'resource_item_id',
                          class_name: 'Resource::Item',
                          join_table: 'resource_items_sets'
end

class Resource::Item < ApplicationRecord
  has_and_belongs_to_many :resource_sets,
                          foreign_key: 'resource_item_id',
                          association_foreign_key: 'resource_set_id',
                          class_name: 'Resource::Set',
                          join_table: 'resource_items_sets'
end

注意添加的association_foreign_key 选项指定连接表中的另一个外键。

【讨论】:

  • 成功了!谢谢。我不知道我是怎么错过文档中的association_foreign_key 的。参考链接:guides.rubyonrails.org/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 2020-09-13
  • 2012-11-23
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多