简体   繁体   English

Rails 5:多个双向Active Record关联

[英]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想要的内容之间的脱节。

Update 更新

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

Answer 回答

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM