Search code examples
ruby-on-railshas-many-throughpolymorphic-associations

Double polymorphic association


In my rails app I have two models: Person and Company. I need to specify many-to-many relationship between any pairs of this objects. So I should be able do like this:

@connections = @person.connections

where @connections is an array of Person and Company objects.

Right now I've created ConnectionBinding model for this and it does not work as wanted:

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

It thougths ActiveRecord::HasManyThroughAssociationPolymorphicSourceError exception

Does anybody already solve this problem? Any suggestions appreciated.


Solution

  • Thanx Chris for showing the idea. But I need to do some changes to make this work. The problem of Chris example is that if I call person_connections method it will generate wrong query.

    Person.find(720).person_connections
    

    generates this 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'
    

    That person_id column should be connect_from_id. So I need to add :as => :connect_from option to has_many :connection_bindings to show ActiveRecord that its a polymorphic association.

    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'
    

    But it is still not enough. I need to be able to get reverse connections. So if Person @a adds connection to Person @b? method connections should show that connection in both directions @a.connections and @b.connections.

    And now I think I can do this by adding couple of additional associations and aggregation methods.