我有两个模型:person.rb和relationship.rb
我需要my: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)我必须在上面的CreateRelationships迁移中编写的附加代码是什么,以便将:person_a和:person_b up设置为:people表中的外键?
2)我需要在下面的两个表的模型文件(person.rb和relationship.rb)中编写什么代码来定义我正在谈论的关系结构?
class Person < ApplicationRecord
end
class Relationship < ApplicationRecord
end
我在这里发现另外一个问题来解决这个问题,但是给出的答案是冲突的,有些是不完整的,而其他人则使用旧版本的Rails。他们都没有为我工作。
我正在使用Rails 5.1.4
答案 0 :(得分:3)
您已正确定义了迁移,只需在模型中添加以下内容即可定义模型之间的关系。
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
这允许您访问关系所属的Person,如下所示:
@relationship.person_a #user assigned as the first person.
@relationship.person_b #user assigned as the second person.
希望这有效。
答案 1 :(得分:1)
我必须为聊天模块做同样的事情,这是一个如何做到的例子:
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
的更多解释
希望它有所帮助,
答案 2 :(得分:1)
编辑:为匆忙和错误的答案道歉。
最初,我认为简单的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
关联无法在此处工作,因为person_id
表中没有relationships
列。由于我们只能在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方法开始为人们分配关系......
什么是真正的解决方案,是在关系模型中使用复合主键 - 由:person_a_id
和:person_b_id
组成。 ActiveRecord不支持复合主键,但this gem似乎填补了空白。显然它允许声明这样的密钥并将其用作has_many
关联中的外键。问题是你的person_a / person_b对在relationships
表中必须是唯一的。
答案 3 :(得分:0)
你可以这样做 在关系模型中写
belongs_to : xyz, class_name: "Person", foreign_key: "person_a"
belongs_to : abc, class_name: "Person", foreign_key: "person_b"
In Person模型写
has_many :relationships, dependent: :destroy
希望它会有所帮助