| Class | Overall |
| In: |
app/models/competitions/overall.rb
|
| Parent: | Competition |
# File app/models/competitions/overall.rb, line 7
7: def Overall.calculate!(year = Date.today.year)
8: benchmark("#{name} calculate!", Logger::INFO, false) {
9: transaction do
10: parent = MultiDayEvent.find(
11: :first,
12: :conditions => ["name = ? and date between ? and ?", parent_name, Date.new(year, 1, 1), Date.new(year, 12, 31)])
13:
14: if parent && parent.has_results_including_children?(true)
15: unless parent.overall
16: # parent.create_overall will create an instance of Overall, which is probably not what we want
17: parent.overall = self.new(:parent_id => parent.id)
18: parent.overall.save!
19: end
20: parent.overall.destroy_races
21: parent.overall.create_races
22: parent.overall.calculate!
23: end
24: end
25: }
26: true
27: end
# File app/models/competitions/overall.rb, line 29
29: def add_source_events
30: parent.children.each do |source_event|
31: source_events << source_event
32: end
33: end
By default, does nothing. Useful to apply rule like:
# File app/models/competitions/overall.rb, line 111
111: def after_create_competition_results_for(race)
112: race.results.each do |result|
113: # Don't bother sorting scores unless we need to drop some
114: if result.scores.size > 6
115: result.scores.sort! { |x, y| y.points <=> x.points }
116: lowest_scores = result.scores[6, 2]
117: lowest_scores.each do |lowest_score|
118: result.scores.destroy(lowest_score)
119: end
120: # Rails destroys Score in database, but doesn't update the current association
121: result.scores(true)
122: end
123:
124: if preliminary?(result)
125: result.preliminary = true
126: end
127: end
128: end
If same rider places twice in same race, only highest result counts
# File app/models/competitions/overall.rb, line 68
68: def create_competition_results_for(results, race)
69: competition_result = nil
70: results.each_with_index do |source_result, index|
71: logger.debug("#{self.class.name} scoring result: #{source_result.date} race: #{source_result.race.name} pl: #{source_result.place} mem pl: #{source_result.members_only_place if place_members_only?} #{source_result.last_name} #{source_result.team_name}") if logger.debug?
72:
73: person = source_result.person
74: points = points_for(source_result)
75:
76: # We repeat some calculations here if a person is disallowed
77: if points > 0.0 &&
78: (!parent.completed? || (parent.completed? && raced_minimum_events?(person, race))) &&
79: (!members_only? || member?(person, source_result.date))
80:
81: if first_result_for_person(source_result, competition_result)
82: # Intentionally not using results association create method. No need to hang on to all competition results.
83: # In fact, this could cause serious memory issues with the Ironman
84: competition_result = Result.create!(
85: :person => person,
86: :team => (person ? person.team : nil),
87: :race => race)
88: end
89:
90: competition_result.scores.create_if_best_result_for_race(
91: :source_result => source_result,
92: :competition_result => competition_result,
93: :points => points
94: )
95: end
96:
97: # Aggressive memory management. If competition has a race with many results,
98: # the results array can become a large, uneeded, structure
99: results[index] = nil
100: if index > 0 && index % 1000 == 0
101: logger.debug("GC start after record #{index}")
102: GC.start
103: end
104:
105: end
106: end
# File app/models/competitions/overall.rb, line 166
166: def date
167: if source_events.any?
168: source_events.sort.first.date
169: else
170: parent.start_date
171: end
172: end
Only members can score points?
# File app/models/competitions/overall.rb, line 131
131: def members_only?
132: false
133: end
# File app/models/competitions/overall.rb, line 159
159: def preliminary?(result)
160: minimum_events &&
161: parent.children_with_results.size > minimum_events &&
162: !parent.completed? &&
163: !raced_minimum_events?(result.person, result.race)
164: end
# File app/models/competitions/overall.rb, line 139
139: def raced_minimum_events?(person, race)
140: return true if minimum_events.nil?
141: return false if parent.children.empty? || person.nil?
142:
143: event_ids = parent.children.collect(&:id).join(", ")
144: category_ids = category_ids_for(race)
145:
146: count = Result.count_by_sql(
147: %Q{ SELECT count(*) FROM results
148: JOIN races ON races.id = results.race_id
149: JOIN categories ON categories.id = races.category_id
150: JOIN events ON races.event_id = events.id
151: WHERE categories.id in (#{category_ids})
152: and events.id in (#{event_ids})
153: and results.person_id = #{person.id}
154: }
155: )
156: count >= minimum_events
157: end
source_results must be in person-order
# File app/models/competitions/overall.rb, line 45
45: def source_results(race)
46: return [] if parent.children.empty?
47:
48: event_ids = parent.children.collect do |event|
49: event.id
50: end
51: event_ids = event_ids.join(', ')
52: category_ids = category_ids_for(race)
53:
54: Result.find_by_sql(
55: %Q{ SELECT results.* FROM results
56: JOIN races ON races.id = results.race_id
57: JOIN categories ON categories.id = races.category_id
58: JOIN events ON races.event_id = events.id
59: WHERE place between 1 and #{point_schedule.size - 1}
60: and categories.id in (#{category_ids})
61: and events.id in (#{event_ids})
62: order by person_id
63: }
64: )
65: end
# File app/models/competitions/overall.rb, line 35
35: def source_results_with_benchmark(race)
36: results = []
37: Overall.benchmark("#{self.class.name} source_results", Logger::DEBUG, false) {
38: results = source_results(race)
39: }
40: logger.debug("#{self.class.name} Found #{results.size} source results for '#{race.name}'") if logger.debug?
41: results
42: end