Class Bar
In: app/models/competitions/bar.rb
Parent: Competition

Best All-around Rider Competition. Assigns points for each top-15 placing in major Disciplines: road, track, etc. Calculates a BAR for each Discipline, and an Overall BAR that combines all the discipline BARs. Also calculates a team BAR. Recalculating the BAR at years-end can take nearly 30 minutes even on a fast server. Recalculation must be manually triggered. This class implements a number of OBRA-specific rules and should be generalized and simplified. The BAR categories and disciplines are all configured in the database. Race categories need to have a bar_category_id to show up in the BAR; disciplines must exist in the disciplines table and discipline_bar_categories.

Methods

Public Class methods

[Source]

    # File app/models/competitions/bar.rb, line 11
11:   def Bar.calculate!(year = Date.today.year)
12:     benchmark(name, Logger::INFO, false) {
13:       transaction do
14:         year = year.to_i if year.is_a?(String)
15:         date = Date.new(year, 1, 1)
16:         
17:         overall_bar = OverallBar.find_or_create_for_year(year)
18: 
19:         # Age Graded BAR, Team BAR and Overall BAR do their own calculations
20:         Discipline.find_all_bar.reject { |discipline|
21:           [ Discipline[:age_graded], Discipline[:overall], Discipline[:team] ].include?(discipline)
22:         }.each do |discipline|
23:           bar = Bar.find(:first, :conditions => { :date => date, :discipline => discipline.name })
24:           unless bar
25:             bar = Bar.create!(
26:               :parent => overall_bar,
27:               :name => "#{year} #{discipline.name} BAR",
28:               :date => date,
29:               :discipline => discipline.name
30:             )
31:           end
32:         end
33: 
34:         Bar.find(:all, :conditions => { :date => date }).each do |bar|
35:           bar.destroy_races
36:           bar.create_races
37:           # Could bulk load all Event and Races at this point, but hardly seems to matter
38:           bar.calculate!
39:         end
40:       end
41:     }
42:     # Don't return the entire populated instance!
43:     true
44:   end

[Source]

    # File app/models/competitions/bar.rb, line 46
46:   def Bar.find_by_year_and_discipline(year, discipline_name)
47:     Bar.find(:first, :conditions => { :date => Date.new(year), :discipline => discipline_name })
48:   end

Public Instance methods

[Source]

     # File app/models/competitions/bar.rb, line 119
119:   def create_races
120:     Discipline[discipline].bar_categories.each do |category|
121:       races.create!(:category => category)
122:     end
123:   end

[Source]

     # File app/models/competitions/bar.rb, line 125
125:   def friendly_name
126:     'BAR'
127:   end

[Source]

    # File app/models/competitions/bar.rb, line 50
50:   def point_schedule
51:     [ 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
52:   end

Apply points from point_schedule, and adjust for field size

[Source]

     # File app/models/competitions/bar.rb, line 105
105:   def points_for(source_result, team_size = nil)
106:     points = 0
107:     Bar.benchmark('points_for') {
108:       field_size = source_result.race.field_size
109: 
110:       team_size = team_size || Result.count(:conditions => ["race_id =? and place = ?", source_result.race.id, source_result.place])
111:       points = point_schedule[source_result.place.to_i] * source_result.race.bar_points / team_size.to_f
112:       if source_result.race.bar_points == 1 and field_size >= 75
113:         points = points * 1.5
114:       end
115:     }
116:     points
117:   end

Source result = counts towards the BAR "race" and BAR results Example: Piece of Cake RR, 6th, Jon Knowlson

bar_result, bar_race = BAR itself and placing in the BAR Example: Senior Men BAR, 130th, Jon Knowlson, 45 points

BAR results add scoring results as scores Example: Senior Men BAR, 130th, Jon Knowlson, 18 points

 - Piece of Cake RR, 6th, Jon Knowlson 10 points
 - Silverton RR, 8th, Jon Knowlson 8 points

[Source]

     # File app/models/competitions/bar.rb, line 65
 65:   def source_results(race)
 66:     race_disciplines = case race.discipline
 67:     when "Road"
 68:       "'Road', 'Circuit'"
 69:     when "Mountain Bike"
 70:       "'Mountain Bike', 'Downhill', 'Super D'"
 71:     else
 72:       "'#{race.discipline}'"
 73:     end
 74:     
 75:     # Cat 4/5 is a special case. Can't config in database because it's a circular relationship.
 76:     category_ids = category_ids_for(race)
 77:     category_4_5_men = Category.find_by_name("Category 4/5 Men")
 78:     category_4_men = Category.find_by_name("Category 4 Men")
 79:     if category_4_5_men && category_4_men && race.category == category_4_men
 80:       category_ids << ", #{category_4_5_men.id}"
 81:     end
 82: 
 83:     Result.find(:all,
 84:                 :include => [:race, {:person => :team}, :team, {:race => [{:event => { :parent => :parent }}, :category]}],
 85:                 :conditions => [%Q{
 86:                   place between 1 AND #{point_schedule.size - 1}
 87:                     and (events.type in ('Event', 'SingleDayEvent', 'MultiDayEvent', 'Series', 'WeeklySeries', 'TaborOverall') or events.type is NULL)
 88:                     and bar = true
 89:                     and events.sanctioned_by = "#{RacingAssociation.current.default_sanctioned_by}"
 90:                     and categories.id in (#{category_ids})
 91:                     and (events.discipline in (#{race_disciplines})
 92:                       or (events.discipline is null and parents_events.discipline in (#{race_disciplines}))
 93:                       or (events.discipline is null and parents_events.discipline is null and parents_events_2.discipline in (#{race_disciplines})))
 94:                     and (races.bar_points > 0
 95:                       or (races.bar_points is null and events.bar_points > 0)
 96:                       or (races.bar_points is null and events.bar_points is null and parents_events.bar_points > 0)
 97:                       or (races.bar_points is null and events.bar_points is null and parents_events.bar_points is null and parents_events_2.bar_points > 0))
 98:                     and events.date between '#{date.year}-01-01' and '#{date.year}-12-31'
 99:                 }],
100:                 :order => 'person_id'
101:       )
102:   end

[Source]

     # File app/models/competitions/bar.rb, line 129
129:   def to_s
130:     "#<#{self.class.name} #{id} #{discipline} #{name} #{date}>"
131:   end

[Validate]