【问题标题】:Rails 5: Multiple bidirectional Active Record associationsRails 5:多个双向 Active Record 关联
【发布时间】:2018-01-09 06:41:50
【问题描述】:

我还没有找到一个能准确提出这个问题的问题。我有一个用户表和一个人表。一个用户有一个代表用户个人详细信息的人。但是,一个用户也可能有多个与之关联的人。

想想类似于 macOS 联系人应用程序的东西。 macOS 用户在联系人列表中有一个联系人,其中包含用户的个人详细信息。该用户还有几个代表其他人的联系人。

用户有一个指向用户个人详细信息的外键person_id

Person 有一个外键 owner_id,它指向拥有该占位符 person 的用户。代表用户的人有一个空的owner_id

好的,所以我创建了两个模型:

class User < ApplicationRecord
  belongs_to :person
  has_many :people, foreign_key: :owner_id
end

class Person < ApplicationRecord
  has_one :user
  belongs_to :user, foreign_key: :owner_id
end

我看到了一个我不确定如何解决的问题。当我添加一个将owner_id 设置为用户ID 的人时,Active Record 会更新用户的person_id。我看到执行了以下 SQL 查询:

INSERT INTO "people" (...) VALUES (...) RETURNING "id"
UPDATE "users" SET "person_id" = $1, "updated_at" = $2 WHERE "users"."id" = $3

我尝试在inverse_of 中插入以更明确地定义关联,但这并没有帮助。唯一有效的方法是从 Person 类中删除关联。这很好,但我真的想了解我认为我所说的和 Rails 认为我想要的之间的脱节。

更新

添加迁移:

class CreateUsers < ActiveRecord::Migration[5.0]
 def change
  create_table :users, id: false do |t|
   t.primary_key :id, :uuid
   t.string :username, null: false, unique: true
   t.uuid :person_id, null: false
   ...
   t.timestamps
  end
 end
end

class CreatePeople < ActiveRecord::Migration[5.0]
 def change
  create_table :people, id: false do |t|
   t.primary_key :id, :uuid
   t.uuid :owner_id
   ...
   t.timestamps
  end
  add_foreign_key :people, :users, column: :owner_id, on_delete: :restrict
  add_foreign_key :users, :people, column: :person_id, on_delete: :restrict
 end
end

回答

Jacob Vanus 给出了答案。我需要像这样更改关联的名称:

class User < ApplicationRecord
 belongs_to :person, class_name: 'Person', foreign_key: :person_id
 has_many :contacts, class_name: 'Person', foreign_key: :owner_id
end

class Person < ApplicationRecord
 has_one :user, class_name: 'User', foreign_key: :person_id
 belongs_to :owner, class_name: 'User', foreign_key: :owner_id
end

【问题讨论】:

  • 你能发布你的迁移或 schema.rb 吗?
  • 随迁移而更新。

标签: ruby-on-rails activerecord


【解决方案1】:

我认为问题在于您试图将 2 个关系命名为相同的事物。尝试重命名两个类中的所有权关系。

class User < ApplicationRecord
  belongs_to :person
  has_many :owners, foreign_key: :owner_id, class: "Person"
end

Person 也会遇到类似的问题

class Person < ApplicationRecord
  has_one :user
  belongs_to :owner, foreign_key: :owner_id, class: "Person"
end

我在尝试理解哪种关系时遇到了麻烦,因此您可能需要调整它以适应您的数据模型。

【讨论】:

  • 啊,有趣。我会尝试重构它,看看我是否可以让它工作。我并没有真正考虑协会名称。关联应该像这样工作:用户通过用户中的 person_id 属于一个人,并且用户有很多联系人(与 Person 中的“所有者”相反)。 Person 有一个用户(与 User 中的“person”相反),并且 Person 通过 Person 中的 owner_id 属于所有者。
  • 是的,就是这样。非常感谢!我用有效的代码更新了我原来的问题。
猜你喜欢
  • 2014-12-06
  • 1970-01-01
  • 2017-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2023-03-15
相关资源
最近更新 更多