Question

I have two Models Team and Match and a TeamMatch association.

class Match < ActiveRecord::Base
    has_many :teams, :through => :team_matches, :source => :team
    has_many :team_matches

    def attend(team)
        self.team_matches.create!(:team => team)
        rescue ActiveRecord::RecordInvalid
        nil
    end
end

class Team < ActiveRecord::Base
    has_many :matches, :through => :team_matches, :source => :match
    has_many :team_matches
end

class TeamMatch < ActiveRecord::Base
    belongs_to :match
    belongs_to :team
end

How do I restrict how many Teams can be assigned to a Match?

EDIT: Update according to suggestions. m = FactoryGirl.create(:team), t..2 = FactoryGirl.create(:team)

1.9.3p194 :005 > m.attend(t)
   (0.1ms)  BEGIN
  TeamMatch Exists (0.3ms)  SELECT 1 AS one FROM `team_matches` WHERE (`team_matches`.`team_id` = BINARY 1 AND `team_matches`.`match_id` = 1) LIMIT 1
  SQL (0.2ms)  INSERT INTO `team_matches` (`match_id`, `team_id`) VALUES (1, 1)
   (0.4ms)  COMMIT
 => #<TeamMatch id: 1, match_id: 1, team_id: 1> 
1.9.3p194 :006 > m.attend(t1)
   (0.1ms)  BEGIN
  TeamMatch Exists (0.3ms)  SELECT 1 AS one FROM `team_matches` WHERE (`team_matches`.`team_id` = BINARY 2 AND `team_matches`.`match_id` = 1) LIMIT 1
  SQL (0.1ms)  INSERT INTO `team_matches` (`match_id`, `team_id`) VALUES (1, 2)
   (0.4ms)  COMMIT
 => #<TeamMatch id: 2, match_id: 1, team_id: 2> 
1.9.3p194 :007 > m.attend(t2)
   (0.1ms)  BEGIN
  TeamMatch Exists (0.3ms)  SELECT 1 AS one FROM `team_matches` WHERE (`team_matches`.`team_id` = BINARY 3 AND `team_matches`.`match_id` = 1) LIMIT 1
  SQL (0.2ms)  INSERT INTO `team_matches` (`match_id`, `team_id`) VALUES (1, 3)
   (0.4ms)  COMMIT
Was it helpful?

Solution 2

You can use association callback.

has_many :teams, :through => :team_matches, :source => :team, :before_add => :limit_number_of_teams

def limit_number_of_teams(added_team)
  raise Exception.new('Team limit for the match reached') if teams.size >= 2
end

OTHER TIPS

I just realize there is much neater solution to that, which is possible as it is has_many through association:

class TeamMatch < ActiveRecord::Base
  belongs_to :match
  belongs_to :team

  validate :teams_per_match_limit

  def teams_per_match_limit
    errors.add(:base, 'blah') if par.children.size > 1
  end

end

You should add some kind of custom validation like this:

class Match < ActiveRecord::Base
    has_many :teams, :through => :team_matches, :source => :team
    has_many :team_matches

  validate :max_associate

  def max_associate
    errors.add(:teams, "can not be added more than 5") if teams.length > 5
  end

end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top