[英]Rails 5: Multiple bidirectional Active Record associations
I haven't quite found a question that asks precisely this question. 我还没有找到一个确切地问这个问题的问题。 I have a User table and a Person table. 我有一个用户表和一个人表。 A user has one person that represents the user's personal details. 用户拥有一个代表用户个人详细信息的人。 However, a user may also have several people associated with it. 但是,用户也可能有几个与之关联的人。
Think something similar to the macOS Contacts app. 认为与macOS Contacts应用类似。 A macOS user has one contact in the contact list with the user's personal details. macOS用户在联系人列表中有一个联系人,其中包含该用户的个人详细信息。 The user also has several contacts that represent other people. 用户还具有代表其他人的几个联系人。
User has a foreign key person_id
that points to the user's personal details. 用户具有指向用户的个人详细信息的外键person_id
。
Person has a foreign key owner_id
that points to the user that owns that placeholder person. 人员具有外键owner_id
,该所有者指向拥有该占位符人员的用户。 A person that represents a user has a null owner_id
. 代表用户的人的null owner_id
为空。
OK, so I created two models: 好的,所以我创建了两个模型:
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
I'm seeing a problem that I'm not exactly sure how to address. 我看到一个我不确定如何解决的问题。 When I add a Person with owner_id
set to a user's ID, Active Record updates the user's person_id
. 当我添加一个owner_id
设置为用户ID的Person时,Active Record会更新该用户的person_id
。 I see the following SQL queries executed: 我看到执行以下SQL查询:
INSERT INTO "people" (...) VALUES (...) RETURNING "id"
UPDATE "users" SET "person_id" = $1, "updated_at" = $2 WHERE "users"."id" = $3
I tried peppering in inverse_of
to more explicitly define the associations, but that did not help. 我尝试在inverse_of
加入胡椒粉,以更明确地定义关联,但这无济于事。 The only thing that works is just removing the associations from the Person class. 唯一有效的方法就是从Person类中删除关联。 Which is fine, but I'm really trying to understand the disconnect between what I think I am saying and what Rails thinks I want. 很好,但我实际上是想了解我在说的内容与Rails想要的内容之间的脱节。
Adding migrations: 添加迁移:
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 had the answer. 雅各布·范纳斯(Jacob Vanus)有了答案。 I need to change the names of the associations like so: 我需要像这样更改关联的名称:
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
I think the problem is you're trying to have 2 relations named the same thing. 我认为问题在于您正试图将2个关系命名为同一事物。 Try renaming the ownership relation in both classes. 尝试在两个类中重命名所有权关系。
class User < ApplicationRecord
belongs_to :person
has_many :owners, foreign_key: :owner_id, class: "Person"
end
You'll have a similar problem with Person
你将有一个类似的问题Person
class Person < ApplicationRecord
has_one :user
belongs_to :owner, foreign_key: :owner_id, class: "Person"
end
I'm having trouble trying to grok which relationship is which, so you may need to adjust this to fit your data model. 我在尝试弄清哪种关系时遇到麻烦,因此您可能需要调整此关系以适合您的数据模型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.