[英]How can I use two records from the same Rails model as foreign keys in a different Rails model?
I have two models: person.rb and relationship.rb 我有两个模型:person.rb和Relationship.rb
I need my :relationships table to reference two rows from the :people table as foreign keys. 我需要我的:relationships表来引用:people表中的两行作为外键。
Here are the migrations for both tables: 这是两个表的迁移:
class CreatePeople < ActiveRecord::Migration[5.1]
def change
create_table :people do |t|
t.string :first_name
t.string :second_name
t.integer :age
t.string :gender
t.timestamps
end
end
end
class CreateRelationships < ActiveRecord::Migration[5.1]
def change
create_table :relationships do |t|
t.references :person_a
t.references :person_b
t.string :status
t.timestamps
end
end
end
The idea is the :person_a and :person_b fields will both be individual records from the :people table referenced as foreign keys, while the :status field will just be a description of their relationship ("Married", "Friends", "Separated", etc.) 这个想法是::person_a和:person_b字段都是来自:people表的单独记录(被引用为外键),而:status字段仅是它们之间关系的描述(“已婚”,“朋友”,“分离”等)
I'm trying to find out: 我试图找出:
1) What is the additional code I have to write in the CreateRelationships migration above in order to set :person_a and :person_b up as foreign keys from the :people table? 1)为了将:person_a和:person_b设置为来自:people表的外键,我必须在上面的CreateRelationships迁移中编写额外的代码?
2) What code do I need to write in the model files (person.rb and relationship.rb) for both tables below to define the relationship structure I'm talking about? 2)我需要在下面的两个表的模型文件(person.rb和Relationship.rb)中编写什么代码来定义我正在谈论的关系结构?
class Person < ApplicationRecord
end
class Relationship < ApplicationRecord
end
I've found one other question on here that deals with this issue, but the answers given were conflicting, some incomplete, and others working with older versions of Rails. 我在这里发现了另一个问题可以解决这个问题,但是给出的答案是矛盾的,有些不完整,还有其他使用旧版本的Rails的问题。 None of them have worked for me. 他们都没有为我工作。
I'm using Rails 5.1.4 我正在使用Rails 5.1.4
You have defined you migration correctly just add the following in your model to define the relationship between the model. 您已经正确定义了迁移,只需在模型中添加以下内容即可定义模型之间的关系。
class Person < ApplicationRecord::Base
has_many :relationships, dependent: :destroy
end
class Relationship < ApplicationRecord::Base
belongs_to :person_a, :class_name => 'Person'
belongs_to :person_b, :class_name => 'Person'
end
This allows you to access the Person that a Relationship belongs to like this: 这样,您可以像下面这样访问一个关系所属的人:
@relationship.person_a #user assigned as the first person.
@relationship.person_b #user assigned as the second person.
Hope this works. 希望这行得通。
I had to do the same for a chat module, this is an example to how you can do it: 对于聊天模块,我必须执行相同的操作,这是如何执行此操作的示例:
class Conversations < ApplicationRecord
belongs_to :sender, foreign_key: :sender_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
end
class User < ApplicationRecord
...
has_many :conversations
has_many :senders, through: :conversations, dependent: :destroy
has_many :recipients, through: :conversations, dependent: :destroy
...
end
More explanations at complex-has-many-through 更多的解释, 有很多
Hope it helps, 希望能帮助到你,
EDIT: Apologies for a rushed and wrong answer. 编辑:道歉的匆忙和错误的答案。
Initially, I thought that simple has_many/belongs_to
association is possible and sufficient. 最初,我认为简单的has_many/belongs_to
关联是可能且足够的。
class Person < ApplicationRecord
has_many :relationships #dependent: :destroy
end
class Relationship < ApplicationRecord
belongs_to :person_a, class_name: "Person"
belongs_to :person_b, class_name: "Person"
enum status: [:married, :friends, :separated]
end
As @engineersmnky pointed out, has_many
association can't work here because there is no person_id
column in relationships
table. 正如@engineersmnky所指出的, has_many
关联在这里不能工作,因为relationships
表中没有person_id
列。 Since we can declare only one custom foreign key in has_many
association, it's not possible to declare it here this way. 由于我们只能在has_many
关联中声明一个自定义外键,因此无法以这种方式声明它。 belongs_to
will work, but I don't think that's enough. belongs_to
可以工作,但我认为这还不够。
One way is to skip declaring has_many
and stick to custom method for querying relationships: 一种方法是跳过声明has_many
并坚持使用自定义方法来查询关系:
class Person < ApplicationRecord
def relationships
Relationship.where("person_a_id = ? OR person_b_id = ?", id, id)
end
end
It will give you an ActiveRecord::Relation
to work with, containing exactly the records you need. 它将为您提供一个ActiveRecord::Relation
来使用,其中包含所需的确切记录。 The drawbacks of this solution are numerous - depending on your needs, you will probably need more code for inserting data, starting with a setter method to assign relationships to people... 该解决方案的缺点很多-根据您的需求,您可能需要更多的代码来插入数据,首先需要使用setter方法将关系分配给人们...
What could be a real solution, is to have a composite primary key in Relationship model - composed of :person_a_id
and :person_b_id
. 真正的解决方案是在Relationship模型中有一个复合主键,该主键由:person_a_id
和:person_b_id
。 ActiveRecord doesn't support composite primary keys, but this gem seems to fill the gap. ActiveRecord不支持复合主键,但是这个宝珠似乎可以填补空白。 Apparently it allows to declare such key and use it as a foreign key in a has_many
association. 显然,它允许声明这样的密钥并将其用作has_many
关联中的外键。 The catch is that your person_a/person_b pairs would have to be unique across relationships
table. 要注意的是,您的person_a / person_b对在relationships
表中必须是唯一的。
You can do like this In relationship model write 您可以像这样在关系模型中编写
belongs_to : xyz, class_name: "Person", foreign_key: "person_a"
belongs_to : abc, class_name: "Person", foreign_key: "person_b"
In Person model write 亲自模型
has_many :relationships, dependent: :destroy
hope it will help 希望对你有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.