class Overall

Common superclass for Omniums and Series standings. Easy to miss override: Overall results only include members

Public Class Methods

calculate!(year = Time.zone.today.year) click to toggle source
# File app/models/competitions/overall.rb, line 11
def self.calculate!(year = Time.zone.today.year)
  benchmark("#{name} calculate!", :level => :info) {
    transaction do
      parent = MultiDayEvent.first(
                      :conditions => ["name = ? and date between ? and ?", parent_name, Date.new(year, 1, 1), Date.new(year, 12, 31)])
                      
      if parent && parent.has_results_including_children?(true)
        unless parent.overall
          # parent.create_overall will create an instance of Overall, which is probably not what we want
          parent.overall = self.new(:parent_id => parent.id)
          parent.overall.save!
        end
        parent.overall.destroy_races
        parent.overall.create_races
        parent.overall.calculate!
      end
    end
  }
  true
end
parent_name() click to toggle source
# File app/models/competitions/overall.rb, line 7
def self.parent_name
  self.name
end

Public Instance Methods

add_source_events() click to toggle source
# File app/models/competitions/overall.rb, line 32
def add_source_events
  parent.children.each do |source_event|
    source_events << source_event
  end
end
all_year?() click to toggle source
# File app/models/competitions/overall.rb, line 155
def all_year?
  false
end
create_competition_results_for(results, race) click to toggle source

If same rider places twice in same race, only highest result counts

# File app/models/competitions/overall.rb, line 71
def create_competition_results_for(results, race)
  competition_result = nil
  results.each_with_index do |source_result, index|
    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?

    person = source_result.person
    points = points_for(source_result)
    
    # We repeat some calculations here if a person is disallowed
    if points > 0.0 && 
       (!parent.completed? || (parent.completed? && raced_minimum_events?(person, race))) && 
         (!members_only? || member?(person, source_result.date))

      if first_result_for_person?(source_result, competition_result)
        # Intentionally not using results association create method. No need to hang on to all competition results.
        # In fact, this could cause serious memory issues with the Ironman
        competition_result = Result.create!(
           :person => person, 
           :team => (person ? person.team : nil),
           :race => race)
      end

      competition_result.scores.create_if_best_result_for_race(
        :source_result => source_result, 
        :competition_result => competition_result, 
        :points => points
      )
    end

    # Aggressive memory management. If competition has a race with many results, 
    # the results array can become a large, uneeded, structure
    results[index] = nil
    if index > 0 && index % 1000 == 0
      logger.debug("GC start after record #{index}")
      GC.start
    end

  end
end
default_bar_points() click to toggle source
# File app/models/competitions/overall.rb, line 116
def default_bar_points
  0
end
maximum_events() click to toggle source
# File app/models/competitions/overall.rb, line 124
def maximum_events
  6
end
members_only?() click to toggle source

Only members can score points?

# File app/models/competitions/overall.rb, line 112
def members_only?
  false 
end
minimum_events() click to toggle source
# File app/models/competitions/overall.rb, line 120
def minimum_events
  nil
end
preliminary?(result) click to toggle source
# File app/models/competitions/overall.rb, line 148
def preliminary?(result)
  minimum_events && 
  parent.children_with_results.size > minimum_events && 
  !parent.completed? && 
  !raced_minimum_events?(result.person, result.race)
end
raced_minimum_events?(person, race) click to toggle source
# File app/models/competitions/overall.rb, line 128
def raced_minimum_events?(person, race)
  return true if minimum_events.nil?
  return false if parent.children.empty? || person.nil?

  event_ids = parent.children.collect(&:id).join(", ")
  category_ids = category_ids_for(race).join(", ")

  count = Result.count_by_sql(
    %Q{ SELECT count(*) FROM results  
        JOIN races ON races.id = results.race_id 
        JOIN categories ON categories.id = races.category_id 
        JOIN events ON races.event_id = events.id 
        WHERE categories.id in (#{category_ids})
            and events.id in (#{event_ids})
            and results.person_id = #{person.id}
     }
  )
  count >= minimum_events
end
source_results(race) click to toggle source

#source_results must be in person-order

# File app/models/competitions/overall.rb, line 48
def source_results(race)
  return [] if parent.children.empty?
  
  event_ids = parent.children.collect do |event|
    event.id
  end
  event_ids = event_ids.join(', ')
  category_ids = category_ids_for(race).join(', ')
  
  Result.find_by_sql(
    %Q{ SELECT results.* FROM results  
        JOIN races ON races.id = results.race_id 
        JOIN categories ON categories.id = races.category_id 
        JOIN events ON races.event_id = events.id 
        WHERE place between 1 and #{point_schedule.size - 1}
            and categories.id in (#{category_ids})
            and events.id in (#{event_ids})
        order by person_id
     }
  )
end
source_results_with_benchmark(race) click to toggle source
# File app/models/competitions/overall.rb, line 38
def source_results_with_benchmark(race)
  results = []
  Overall.benchmark("#{self.class.name} source_results", :level => :debug) {
    results = source_results(race)
  }
  logger.debug("#{self.class.name} Found #{results.size} source results for '#{race.name}'") if logger.debug?
  results
end