【发布时间】:2018-02-20 15:09:01
【问题描述】:
在 Rails 5.1 中,我有以下关系:
class RootArea < ApplicationRecord
has_many :common_areas
end
class CommonArea < ApplicationRecord
belongs_to :root_area, foreign_key: 'area_id', optional: true
end
以下是他们的迁移:
create_table "root_areas", force: :cascade do |t|
t.integer "area_id"
t.string "localname"
t.string "globalname"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "common_areas", force: :cascade do |t|
t.integer "area_id"
t.string "localname"
t.string "globalname"
t.integer :root_area_id
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
我的目标是“连接”common_areas 到 root_areas -在 area_id 而不仅仅是 id- 这样单个根区域条目可能“具有”多个公共领域。
例如美国(RootArea)有加利福尼亚(CommonArea),德克萨斯(CommonArea)等。
我尝试使用迁移和外键来执行此操作,如下所示:
add_foreign_key :common_areas, :root_areas, primary_key: :area_id
虽然起初这似乎运作良好,但最终失败了:
>>> RootArea.create!(area_id: 1111,
localname: ’test',
globalname: ’test') # OK
>>> CommonArea.create!(area_id: 9999,
localname: ’test',
globalname: ’test') # OK
>>> RootArea.first.common_areas << CommonArea.first # Error
=> # SQL (44.3ms) UPDATE "common_areas" SET "root_area_id" = $1, "updated_at" = $2 WHERE "common_areas"."id" = $3 [["root_area_id", 19], ["updated_at", "2018-02-20 14:45:52.545450"], ["id", 1]]
输出表明 Rails 尝试将CommonArea 的属性root_area_id 设置为RootArea 的主键(id 而不是area_id)。
例如在上面的示例中,生成的 sql 语句应该将 root_area_id 设置为 1111 而不是 19。
【问题讨论】:
-
您能分享一下您的班级和关系吗?
-
已更新。世界
-
谢谢。所以你没有名为'area'的类?使用
has_many ... through似乎更容易实现您想要的目标 -
我不太明白为什么会有
root_areas和common_areas表。或者为什么这不是 HMT 等。 -
所以,我正在尝试执行以下操作:即加利福尼亚
belongs_to美国,德克萨斯belongs_to美国等。但我还需要能够执行 USA.common_areas 并吐出加利福尼亚,德克萨斯州等。最好的方法是什么?
标签: ruby-on-rails activerecord activemodel