Topic: Sport Competition Design


I'm building a webapplication to manage competitions.
Some background info: A competition is divided into poules and teams are assigned to a poule.
During the competition those teams play matches agains each-other.
A match can only be played between 2 different teams from the same poule.
A team is only bound to the poule in a competition.
A year has 2 competitions (indoor and outdoor).
So over the years a team plays many matches in many poules.
When a team scores more goals than the opponent they receive 2 points for that,
a tie results in 1 point and when you loose, well you loose.. (no points smile ).

The current models:

    has_many     :poules

    belongs_to     :competition
    has_many     :matches
    has_and_belongs_to_many    :teams

    belongs_to     :hometeam,
                :class_name => "Team",
                :foreign_key => "hometeam_id"
    belongs_to     :awayteam,
                :class_name => "Team",
                :foreign_key => "awayteam_id"

    belongs_to     :poule
    has_many    :matches
    belongs_to    :club   
    has_and_belongs_to_many    :poules
    has_many    :teams

Some high level features:
    show all the teams in a poule
    show all the matches in a poule
    show the ranking in a poule       
    And more, but that's for version 2 smile

The ranking is the most tricky part, I really have no clue how I should implement this.
Should it be a seperate model?
Or should I implement this from the poule model?

I'm fairly new to all of this, so I hope that some of you can provide me with some insight to solve this.

Re: Sport Competition Design

How are the points/goals stored in the database?

Railscasts - Free Ruby on Rails Screencasts

Re: Sport Competition Design

Hi Ryan,

a match has 2 fields for the goals: home_goals and away_goals

Re: Sport Competition Design

The logic is a little too complicated to do all in one MySQL query, so you need to calculate it in Ruby. Let's start at the interface and work down to the logic. You want to display a list of teams in a given poule ordered by the points?

# in controller
@teams = @poule.teams.sort_by(&:points).reverse

Now you need to create a points method in Team:

# in team.rb
def points
  matches.inject(0) { |total, match| total + match.points_for_team(self) }

inject is just a fancy iterator for keeping track of another variable (such as the sum). IIRC, in edge rails there is a sum method built right into the Array class so you could use that.

Now you need to make the points_for_team method in Match:

# in match.rb
def points_for_team(team)
  if winner_team_id ==
  elsif tie?

def winner_team_id
  if home_goals > away_goals
  elsif away_goals > home_goals

def tie?
  home_goals == away_goals

This entire thing isn't very well optimized. If you want to improve performance I recommend caching the points for each team.

Railscasts - Free Ruby on Rails Screencasts

Re: Sport Competition Design

Thanks... that a very extensive anwser. very helpfull.

I will make it work first, than make it faster smile

Last edited by NeXoPheuS (2006-11-11 07:50:01)