1

在我的Rails应用程序中,我有两个模型: PersonCompany。我需要指定这些对象的任何对之间的多对多关系。所以,我应该可以这样做:双多态协会

@connections = @person.connections 

其中@connectionsPersonCompany对象的数组。

现在我已经创建ConnectionBinding模型,这和它不起作用通缉:

class ConnectionBinding < ActiveRecord::Base 
    belongs_to :connect_from, polymorphic: true 
    belongs_to :connect_to, polymorphic: true 
end 

它thougths ActiveRecord::HasManyThroughAssociationPolymorphicSourceError例外

有谁已经解决这个问题?任何建议感激。

回答

1

Thanx克里斯为显示这个想法。但我需要做一些改变才能完成这项工作。 克里斯例子的问题是,如果我打电话给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增加连接到Person @b?方法连接应显示在两个方向@a.connections@b.connections之间的连接。

现在我想我可以通过添加几个附加的关联和聚合方法来做到这一点。

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作为一个好的框架不会阻止你做任何你真正想做的事情 - 但是为了达到你的目的,需要一些明确性是不常见的。

+0

感谢名单指着我出去。你的回答非常有帮助。我在下一个答案中为我写下了实际的解决方案。 – RunFor 2013-03-13 01:04:57

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