has_and_belongs_to_many作为"通过"

时间:2016-05-25 01:53:05

标签: ruby-on-rails ruby-on-rails-4 nested-attributes has-and-belongs-to-many polymorphic-associations

模型

患者:

说明:
应该只有1 推荐人

协会:

has_and_belongs_to_many :referrer


推荐人:

说明:
包含所有类型的引荐来源,例如但不限于:

  • 合作伙伴

协会:

has_and_belongs_to_many :referrer


推荐人类型(我认为我应该添加的新模型):

引荐人的详细信息在这里,例如网站的名称引导患者去该医院,或合作伙伴的名称建议医院到患者




工作流程&解释

在表格中,医院员工会记录患者的详细信息。其中一个细节是 推荐人 - 将患者转介到该医院的实体。引荐来源呈现为下拉列表框

由于以下原因,我将Patient-Referrer与HABTM联系起来:

  1. 除了Patient之外,其他型号也将使用Referrer模型。
  2. Referrer模型有自己的脚手架,管理员可以添加/删除引荐来源。



  3. 要求(问题)

    每次下拉框的值为"合作伙伴"时,都应该有一个字段来输入该实体的名称。这就是第三个模型的用武之地。第三个模型将包含:

    1. 合作伙伴的姓名
    2. 对推荐人模型的记录的引用,名为"合作伙伴"
    3. 对患者记录的引用。
    4. 现在正在使用第三个模型,我将如何 为每个推荐人插入每个患者的新推荐人详细信息,并使其可级联,从某种意义上说,当我删除患者时,推荐者详细信息将被删除,但推荐人将仍然保持不变,轨道方式。

1 个答案:

答案 0 :(得分:0)

has_and_belongs_to_many不太好

has_and_belongs_to_many (HABTM)是ActiveRecord中最有限的关系之一,实际上只适用于需要非常简单的多对多关系的地方:

  • 您永远不需要连接模型或将逻辑附加到连接表
  • 您永远不需要将任何额外数据附加到联接表
  • 您永远不需要单独查询联接表

没有HABTM"通过"因为HABTM没有连接模型。那就是重点。您不能在HABTM关系中使用多态 - 因为这需要连接模型。

使用HABTM不是正确的选择。

In most cases you should be using has_many :though instead.

这里你想要的是与连接模型的一对多关系:

class Patient < ActiveRecord::Base
  has_one :referral, dependent: :destroy
  has_one :referrer, through: :referral
end

class Referral < ActiveRecord::Base
  belongs_to :patient
  belongs_to :partner
  validates_uniqueness_of :patient_id
end

class Partner < ActiveRecord::Base
  has_many :referrals
  has_many :referred_patients, through: :referrals
end

Polymorpism

可以使用多态来让相同的关联指向不同的表:

class Referral < ActiveRecord::Base
  belongs_to :referred, polymorphic: :true
  belongs_to :referrer, polymorphic: :true
  validates_uniqueness_of :referred_id, scope: :referred_type
end

您需要将referred_type:stringreferrer_type:string列添加到referrals

# app/models/concerns/referable.rb
module Referable
  extend ActiveSupport::Concern
  included do
    has_one :referral, as: :referred, dependent: :destroy
    has_one :referrer, through: :referral
    has_many :referrals, as: :referrer
    has_many :referred_entities, through: :referrals
                        source: :referred
  end
end

class Patient < ActiveRecord::Base
  include Referable
end

class Doctor < ActiveRecord::Base
  include Referable
end

class Partner < ActiveRecord::Base
  include Referable
end

此示例可让患者,医生和合作伙伴成为推荐方或推荐人。然而,一个很大的缺点是缺少连接和多态关联的急切加载,因为事先无法知道连接表。