简体   繁体   English

如何使用同一Rails模型中的两个记录作为不同Rails模型中的外键?

[英]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.

相关问题 Rails Join表带有来自同一模型的两个外键 - Rails Join table with two foreign keys from the same model 具有来自同一表的两个外键的Rails模型和DB模式 - Rails Model and DB schema with two foreign keys from the same table Rails - 一个模型上的两个外键都指向相同的模型 - Rails - two foreign keys on one model both refer to same model 如何使用来自同一Rails模型上两个不同宝石的具有相同“名称”的两种不同方法? - How to use two different method with the same “name” from two different gems on the same rails model? 如何在带有单独外键的Rails模型中使用 - how to use through in rails model with separate foreign keys 如何在使用Rails的Ruby中的模型中指定2个外键? - How do I specify 2 foreign keys in a model in ruby on rails? 在Rails中,如何将多个外键添加到同一模型中? 我有等效的Django - In Rails, how do you add multiple foreign keys to the same model? I have the Django equivalent Rails ActiveRecord模型has_one两次使用不同的外键到同一模型 - Rails ActiveRecord model has_one twice to the same model with different foreign keys Rails模型生成中的外键 - Foreign keys in rails model generation Rails 使用来自不同 activerecord 模型的列作为外键 - Rails use column from different activerecord model as foreign key
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM