在我的rails应用程序中,我有两个型号:
Person
和Company
。我需要在这些对象的任何对之间指定多对多关系。所以我应该这样做:
@connections = @person.connections
其中@connections
是Person
和Company
个对象的数组。
现在我已为此创建了ConnectionBinding
模型,但它无法正常工作:
class ConnectionBinding < ActiveRecord::Base
belongs_to :connect_from, polymorphic: true
belongs_to :connect_to, polymorphic: true
end
它会发生ActiveRecord::HasManyThroughAssociationPolymorphicSourceError
例外
有人已经解决了这个问题吗?任何建议表示赞赏。
答案 0 :(得分:5)
您需要告诉ActiveRecord它正在寻找的关联列。我猜你想拥有以下内容:
class Person < ActiveRecord::Base
has_many :connection_bindings
has_many :companies, :through => :connection_bindings
has_many :people, :through => :connection_bindings
end
class company < ActiveRecord::Base
has_many :connection_bindings
has_many :companies, :through => :connection_bindings
has_many :people, :through => :connection_bindings
end
问题在于你有两个表将id放在一列中,而Rails不知道要查找哪个表。
例如,在数据库中任何给定的connection_binding行上,connect_from可以是company_id或person_id,connect_to也是如此。所以你说:'嘿Rails,加载我关联的ConnectionBindings',它得到一行,其中connect_from是11,connect_to是12.但是它是Person.find(12)还是Company.find(12)?没有办法说出来!
相反,您必须向Rails提供更多信息:
class Person < ActiveRecord::Base
has_many :connection_bindings
has_many :person_connections, :through => :connection_bindings, :source => :to_connect, :source_type => 'Person'
has_many :company_connections, :through => :connection_bindings, :source => :to_connect, :source_type => 'Company
def connections
person_connections + company_connections
end
end
你需要在另一端构建它(以及相关的:from_connect),但这取决于你如何使用这些连接。应该足以让你入门。
它比你在Ruby和Rails的神奇世界中习惯的打字要多得多,但它是一个非常复杂的数据模式,你正在尝试构建。这并不意味着它是不可能的 - 作为一个好的框架,Rails不会阻止你做任何你真正想做的事情 - 但是在你的目的上需要一些明确性是不常见的。
答案 1 :(得分:1)
Thanx Chris表达了这个想法。但我需要做一些改变才能使这项工作成功。
Chris示例的问题是,如果我调用person_connections
方法,它将生成错误的查询。
Person.find(720).person_connections
生成此SQL
SELECT "people".* FROM "people"
INNER JOIN "connection_bindings"
ON "people"."id" = "connection_bindings"."connect_to_id"
WHERE "connection_bindings"."person_id" = 720
AND "connection_bindings"."connect_to_type" = 'Person'
person_id
列应为connect_from_id
。因此,我需要向:as => :connect_from
添加has_many :connection_bindings
选项,以向ActiveRecord显示其多态关联。
has_many :connection_bindings, :as => :connect_from
has_many :person_connections, :through => :connection_bindings,
:source => :connect_to, source_type: 'Person'
has_many :company_connections, :through => :connection_bindings,
:source => :connect_to, source_type: 'Company'
但仍然不够。我需要能够获得反向连接。那么,如果Person @a
添加了与人@b
的连接?方法连接应在@a.connections
和@b.connections
两个方向上显示该连接。
现在我想我可以通过添加几个额外的关联和聚合方法来实现这一点。
答案 2 :(得分:0)
关注:
module Linkable
extend ActiveSupport::Concern
included do
has_many :links_to, as: :linkable_to, class_name: 'Link' # [this]->[other object]
has_many :links_from, as: :linkable_from, class_name: 'Link' # [other object]->[this]
end
end
链接表:
class Link < ActiveRecord::Base
#The idea for this class is to by a double polymorphic table, linking an object to another object
belongs_to :linkable_from, :polymorphic => true
belongs_to :linkable_to, :polymorphic => true
end