Manager
有多个contacts
通过多态关联
class Manager
has_many :contacts, as: :contactable
end
class Contact
belongs_to :contactable, polymorphic: true
end
关系正常,但现在联系人可以与许多managers
相关联。
因此,添加了一个新模型Contactable
,一个联接表'contactables',并将contactable_id
和contactable_type
字段从contacts
表移至contactables
表。
class Contactable
belongs_to :contact
belongs_to :contactable, polymorphic: true
end
现在对Manager
和Contact
关系感到困惑,因为它会如何在模型中正确定义以使其正常工作。试过以下但不起作用:
class Manager
has_many :contacts, through: :contactables, source: :contactable, source_type: "Contact"
end
答案 0 :(得分:1)
所以我检查了这个有趣的话题,并告诉我所知道的。
在has_many :through
中照常创建对象时:
class Contact
has_many :contactables
has_many :managers, :through => :contactables
end
class Manager
has_many :contactables
has_many :contacts, :through => :contactables
end
class Client
has_many :contactables
has_many :contacts, :through => :contactables
end
class Contactable
belongs_to :contact
belongs_to :manager
belongs_to :client
end
您可以使用每个引用对象的外键。多态似乎是一个很好的解决方案。所以:
class Contactable
belongs_to :contact
belongs_to :polymorphic_model, polymorphic: true
end
class Contact
has_many :contactables
has_many :managers, :through => :contactables, :source => :polymorphic_model, :source_type => 'Manager'
end
class Manager
has_many :contactables, :as => :polymorphic_model
has_many :contacts, :through => :contactables
end
设置:as选项表示这是一个多态 协会
:source => :polymorphic_model
用于告诉Rails从子类中获取相关对象。 :source
表示与:class_name
相同。如果没有此选项,Rails将尝试从Contactables表中获取关联的Manager,同时应通过虚拟Polymorphic_model访问它。
通过将belongs_to :polymorphic_model
添加到Contactable,您可以启用联系人(因为belongs_to :contact
已经坐在那里,因为have_many
)与管理员或客户关联,因为那是多态关联所做的 - 引用两个或更多父母表。因为联系Manager.create!(name: "Bravo")
=> #<Manager id: 1, created_at: "2017-04-12 12:17:41", updated_at: "2017-04-12 12:17:41", name: "Bravo">
Manager.create!(name: "Johnny")
=> #<Manager id: 2, created_at: "2017-04-12 12:18:24", updated_at: "2017-04-12 12:18:24", name: "Johnny">
Contact.create!(number:"123")
=> #<Contact id: 1, created_at: "2017-04-12 12:18:59", updated_at: "2017-04-12 12:18:59", number: 123>
c = Contactable.new
c.contact = Contact.first
c.unit = Manager.first
c
=> #<Contactable id: nil, unit_type: "Manager", created_at: nil, updated_at: nil, unit_id: 1, contact_id: 1>
可联系人,同一个联系人对象可以与许多经理或客户关联。因此,在您了解它之后,它看起来非常简单 - 连接模型属于Contact,Joined模型也通过Polymorphic关联保存对Manager和Client的引用。因此,为了使Contact拥有许多管理器,您可以创建另一个属于同一个Contact但位于不同Manager的Contactable对象。看起来效率不高,但我个人而言,不知道更好的方式..
以下是经过测试的证明:
cc = Contactable.new
cc.contact = Contact.first
cc.unit = Manager.last
cc
=> #<Contactable id: nil, unit_type: "Manager", created_at: nil, updated_at: nil, unit_id: 4, contact_id: 1>
现在将另一个Manager设置为同一个联系人,我们创建一个新的Contactable:
Contact.first.managers
并获得所有关联:
contact_id
unit_id
unit_type
可联系人的数据库:
Whileprintingrecords;
stringvar array sMessage := split({Inventory.MessageText},",");
If UBound(sMessage ) > 0 then
(
Trim(sMessage [1]) & Chr(13) & Trim(sMessage [2]);
)
@Bill Karwin的一句有趣的话:
多态关联设计打破了关系规则 数据库设计。我不建议使用它。
但他很久以前写过这篇文章。现在可能无关紧要。
Why can you not have a foreign key in a polymorphic association?