[英]How can I use two records from the same Rails model as foreign keys in a different Rails model?
我有两个模型:person.rb和Relationship.rb
我需要我的:relationships表来引用:people表中的两行作为外键。
这是两个表的迁移:
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
这个想法是::person_a和:person_b字段都是来自:people表的单独记录(被引用为外键),而:status字段仅是它们之间关系的描述(“已婚”,“朋友”,“分离”等)
我试图找出:
1)为了将:person_a和:person_b设置为来自:people表的外键,我必须在上面的CreateRelationships迁移中编写额外的代码?
2)我需要在下面的两个表的模型文件(person.rb和Relationship.rb)中编写什么代码来定义我正在谈论的关系结构?
class Person < ApplicationRecord
end
class Relationship < ApplicationRecord
end
我在这里发现了另一个问题可以解决这个问题,但是给出的答案是矛盾的,有些不完整,还有其他使用旧版本的Rails的问题。 他们都没有为我工作。
我正在使用Rails 5.1.4
您已经正确定义了迁移,只需在模型中添加以下内容即可定义模型之间的关系。
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
这样,您可以像下面这样访问一个关系所属的人:
@relationship.person_a #user assigned as the first person.
@relationship.person_b #user assigned as the second person.
希望这行得通。
对于聊天模块,我必须执行相同的操作,这是如何执行此操作的示例:
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
更多的解释, 有很多
希望能帮助到你,
编辑:道歉的匆忙和错误的答案。
最初,我认为简单的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
正如@engineersmnky所指出的, has_many
关联在这里不能工作,因为relationships
表中没有person_id
列。 由于我们只能在has_many
关联中声明一个自定义外键,因此无法以这种方式声明它。 belongs_to
可以工作,但我认为这还不够。
一种方法是跳过声明has_many
并坚持使用自定义方法来查询关系:
class Person < ApplicationRecord
def relationships
Relationship.where("person_a_id = ? OR person_b_id = ?", id, id)
end
end
它将为您提供一个ActiveRecord::Relation
来使用,其中包含所需的确切记录。 该解决方案的缺点很多-根据您的需求,您可能需要更多的代码来插入数据,首先需要使用setter方法将关系分配给人们...
真正的解决方案是在Relationship模型中有一个复合主键,该主键由:person_a_id
和:person_b_id
。 ActiveRecord不支持复合主键,但是这个宝珠似乎可以填补空白。 显然,它允许声明这样的密钥并将其用作has_many
关联中的外键。 要注意的是,您的person_a / person_b对在relationships
表中必须是唯一的。
您可以像这样在关系模型中编写
belongs_to : xyz, class_name: "Person", foreign_key: "person_a"
belongs_to : abc, class_name: "Person", foreign_key: "person_b"
亲自模型
has_many :relationships, dependent: :destroy
希望对你有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.