Search code examples
ruby-on-railsactiverecordmany-to-manyassociationshas-many-through

Two similar Many-to-Many Relationships


I have two similar M:M relationships that I work with individually however I don't know how to them working without conflicting.

Relationships are Players & Teams

1) Many players "play for" many teams

2) Many players "are members of" many teams

class Player < ActiveRecord::Base
  has_many :plays
  has_many :members
  has_many :teams, through: :plays
  has_many :teams, through: :members
end

class Teams < ActiveRecord::Base
  has_many :plays
  has_many :members
  has_many :players, through: :plays
  has_many :players, through: :members
end

class Play < ActiveRecord::Base
  belongs_to :players
  belongs_to :teams
end

class Member < ActiveRecord::Base
  belongs_to :players
  belongs_to :teams
end

I need to be able to find:

Player.find(21).teams #who he plays for
Player.find(21).teams #who he is a member of

Solution

  • You have to give a different name to each has_many association, and use the source parameter to specify the actual association name.

    Like this:

    class Player < ActiveRecord::Base
      has_many :plays
      has_many :memberships
      has_many :played_with_teams, through: :plays, source: :team
      has_many :member_of_teams, through: :memberships, source: :team
    end
    
    class Team < ActiveRecord::Base
      has_many :plays
      has_many :memberships
      has_many :played_players, through: :plays, source: :player
      has_many :member_players, through: :members, source: :player
    end
    
    class Play < ActiveRecord::Base
      belongs_to :player
      belongs_to :team
    end
    
    class Membership < ActiveRecord::Base
      belongs_to :player
      belongs_to :team
    end
    

    That can be used like this:

    Player.find(21).played_with_teams #who he plays for
    Player.find(21).member_of_teams #who he is a member of
    

    Hint: I updated the answer.