class Result

Race result

Race is the only required attribute -- even person and place can be blank

Result keeps its own copy of number and team, even though each Person has a team atribute and many RaceNumbers. Result's number is just a String, not a RaceNumber

Attributes

updated_by[RW]

Public Class Methods

find_all_for(person) click to toggle source
# File app/models/result.rb, line 55
def self.find_all_for(person)
  if person.is_a? Person
    person_id = person.id
  else
    person_id = person
  end
  Result.find(
    :all,
    :include => [:team, :person, :scores, :category, {:race => [:event, :category]}],
    :conditions => ['people.id = ?', person_id]
  )
end

Public Instance Methods

cache_attributes!(*args) click to toggle source
# File app/models/result.rb, line 204
def cache_attributes!(*args)
  args = args.extract_options!
  event.disable_notification!
  cache_event_attributes if args.include?(:event)
  cache_non_event_attributes if args.empty? || args.include?(:non_event)
  save!
  event.enable_notification!
end
cache_event_attributes() click to toggle source
# File app/models/result.rb, line 191
def cache_event_attributes
  self[:competition_result]      = competition_result?
  self[:date]                    = event.date
  self[:event_date_range_s]      = event.date_range_s
  self[:event_end_date]          = event.end_date
  self[:event_full_name]         = event.full_name
  self[:event_id]                = event.id
  self[:race_full_name]          = race.try(:full_name)
  self[:race_name]               = race.try(:name)
  self[:team_competition_result] = team_competition_result?
  self.year                      = event.year
end
cache_non_event_attributes() click to toggle source

Cache expensive cross-table lookups

# File app/models/result.rb, line 183
def cache_non_event_attributes
  self[:category_name] = category.try(:name)
  self[:first_name]    = person.try(:first_name, date)
  self[:last_name]     = person.try(:last_name, date)
  self[:name]          = person.try(:name, date)
  self[:team_name]     = team.try(:name, date)
end
calculate_points() click to toggle source

Set points from scores

# File app/models/result.rb, line 252
def calculate_points
  if !scores.empty? and competition_result?
    pts = 0
    scores.each do |score|
      pts = pts + score.points
    end
    self.points = pts
  end
end
category_name=(name) click to toggle source
# File app/models/result.rb, line 262
def category_name=(name)
  if name.blank?
    self.category = nil
  else
    self.category = Category.find_or_create_by_name(name)
  end
  self[:category_name] = name.try(:to_s)
end
competition_result?() click to toggle source
# File app/models/result.rb, line 271
def competition_result?
  if competition_result.nil?
    @competition_result = event.is_a?(Competition)
  else
    competition_result
  end
end
custom_attributes=(hash) click to toggle source
# File app/models/result.rb, line 222
def custom_attributes=(hash)
  if hash
    symbolized_hash = Hash.new
    hash.each { |key, value| symbolized_hash[key.to_s.to_sym] = value}
  end
  self[:custom_attributes] = symbolized_hash
end
date() click to toggle source
# File app/models/result.rb, line 312
def date
  if race || race(true)
    race.date
  end
end
destroy_people() click to toggle source

Destroy People that only exist because they were created by importing results

# File app/models/result.rb, line 231
def destroy_people
  if person && person.results.count == 0 && person.created_from_result? && !person.updated_after_created?
    person.destroy
  end
end
destroy_teams() click to toggle source

Destroy Team that only exist because they were created by importing results

# File app/models/result.rb, line 238
def destroy_teams
  if team && team.results.count == 0 && team.people.count == 0 && team.created_from_result? && !team.updated_after_created?
    team.destroy
  end
end
distance() click to toggle source
# File app/models/result.rb, line 318
def distance
  race && race.distance
end
ensure_custom_attributes() click to toggle source
# File app/models/result.rb, line 213
def ensure_custom_attributes
  if race_id && race.custom_columns && !custom_attributes
    self.custom_attributes = Hash.new
    race.custom_columns.each do |key|
      custom_attributes[key.to_sym] = nil
    end
  end
end
event(reload = false) click to toggle source
# File app/models/result.rb, line 326
def event(reload = false)
  if race(reload)
    race.event(reload)
  end
end
event_id() click to toggle source
# File app/models/result.rb, line 322
def event_id
  self[:event_id] || (race || race(true)).try(:event_id)
end
find_associated_records() click to toggle source

Replace any new person, or team with one that already exists if name matches

# File app/models/result.rb, line 69
def find_associated_records
  _person = person
  if _person && _person.new_record?
    if _person.name.blank?
      self.person = nil
    else
      existing_people = find_people
      if existing_people.size == 1
        self.person = existing_people.to_a.first
      elsif existing_people.size > 1
        self.person = Person.select_by_recent_activity(existing_people)
      end
    end
  end

  # This logic should be in Person
  if person && 
     RacingAssociation.current.add_members_from_results? &&
     person.new_record? &&
     person.first_name.present? &&
     person.last_name.present? &&
     person[:member_from].blank? &&
     event.number_issuer.name == RacingAssociation.current.short_name &&
     !RaceNumber.rental?(number, Discipline[event.discipline])

    person.member_from = race.date
  end

  if team && team.new_record?
    if team.name.blank?
      self.team = nil
    else
      existing_team = Team.find_by_name_or_alias(team.name)
      self.team = existing_team if existing_team
    end
    team.created_by = event if team && team.new_record?
  end
  true
end
find_people(_event = event) click to toggle source

Use first_name, last_name, race_number, team to figure out if person already exists. Returns an Array of People if there is more than one potential match

TODO refactor into methods or split responsibilities with Person? Need Event to match on race number. Event will not be set before result is saved to database

# File app/models/result.rb, line 114
def find_people(_event = event)
  matches = Set.new
  
  #license first if present and source is reliable (USAC)
  if RacingAssociation.current.eager_match_on_license? && license.present?
    matches = matches + Person.find_all_by_license(license)
    return matches if matches.size == 1
  end
  
  # name
  matches = matches + Person.find_all_by_name_or_alias(:first_name => first_name, :last_name => last_name)
  return matches if matches.size == 1

  # number
  if number.present?
    if matches.size > 1
      # use number to choose between same names
      RaceNumber.find_all_by_value_and_event(number, _event).each do |race_number|
        if matches.include?(race_number.person)
          return [ race_number.person ]
        end
      end
    elsif name.blank?
      # no name, so try to match by number
      matches = RaceNumber.find_all_by_value_and_event(number, _event).map(&:person)
    end
  end

  # team
  unless team_name.blank?
    team = Team.find_by_name_or_alias(team_name)
    matches.reject! do |match|
      match.team != team
    end
    return matches if matches.size == 1
  end

  # license
  unless self.license.blank?
    matches.reject! do |match|
      match.license != license
    end
  end

  matches
end
finished?() click to toggle source

Not blank, DNF, DNS, DQ.

# File app/models/result.rb, line 297
def finished?
  return false if place.blank?
  return false if ["DNF", "DNS", "DQ"].include?(place)
  place.to_i > 0
end
first_name=(value) click to toggle source
# File app/models/result.rb, line 364
def first_name=(value)
  if self.person
    self.person.first_name = value
  else
    self.person = Person.new(:first_name => value)
  end
  self[:first_name] = value
  self[:name] = self.person.try(:name, date)
end
laps() click to toggle source
# File app/models/result.rb, line 332
def laps
  self[:laps] || (race && race.laps)
end
last_event?() click to toggle source

Does this result belong to the last event in a MultiDayEvent?

# File app/models/result.rb, line 304
def last_event?
  return false unless self.event && event.parent
  return false unless event.parent.respond_to?(:parent)
  return true unless event.parent

  !(event.parent && (event.parent.end_date != self.date))
end
last_name=(value) click to toggle source
# File app/models/result.rb, line 374
def last_name=(value)
  if self.person
    self.person.last_name = value
  else
    self.person = Person.new(:last_name => value)
  end
  self[:last_name] = value
  self[:name] = self.person.try(:name, date)
end
method_missing(sym, *args, &block) click to toggle source
# File app/models/result.rb, line 428
def method_missing(sym, *args, &block)
  # Performance fix for results page. :to_ary would be called and trigger a load of race to get custom_attributes
  # May want to denormalize custom_attributes in Result.
  if sym == :to_ary
    return super
  end

  if sym != :custom_attributes && custom_attributes && custom_attributes.has_key?(sym)
    custom_attributes[sym]
  elsif race && race.custom_columns && race.custom_columns.include?(sym)
    nil
  else
    super
  end
end
name=(value) click to toggle source

person.name

# File app/models/result.rb, line 389
def name=(value)
  if value.present?
    if person.try(:name) != value
      self.person = Person.new(:name => value)
    end
    self[:first_name] = person.first_name
    self[:last_name] = person.last_name
  else
    self.person = nil
    self[:first_name] = nil
    self[:last_name] = nil
  end
  self[:name] = value
end
person_name() click to toggle source
# File app/models/result.rb, line 384
def person_name
  name
end
person_name=(value) click to toggle source
# File app/models/result.rb, line 404
def person_name=(value)
  self.name = value
end
person_team_name() click to toggle source

Person’s current team name

# File app/models/result.rb, line 409
def person_team_name
  if person
    person.team_name
  else
    ""
  end
end
place() click to toggle source
# File app/models/result.rb, line 336
def place
  self[:place] || ''
end
points() click to toggle source
# File app/models/result.rb, line 340
def points
  if self[:points]
    self[:points].to_f
  else
    0.0
  end
end
points_bonus_penalty=(value) click to toggle source

Hot spots

# File app/models/result.rb, line 349
def points_bonus_penalty=(value)
  if value == nil || value == ""
    value = 0
  end
  write_attribute(:points_bonus_penalty, value)
end
points_from_place=(value) click to toggle source

Points from placing at finish, not from hot spots

# File app/models/result.rb, line 357
def points_from_place=(value)
  if value == nil || value == ""
    value = 0
  end
  write_attribute(:points_from_place, value)
end
save_person() click to toggle source

Save associated Person

# File app/models/result.rb, line 173
def save_person
  if person && (person.new_record? || person.changed?)
    if person.new_record?
      person.created_by = event
    end
    person.save!
  end
end
team_competition_result?() click to toggle source
# File app/models/result.rb, line 279
def team_competition_result?
  if team_competition_result.nil?
    @team_competition_result = event.is_a?(TeamBar) || event.is_a?(CrossCrusadeTeamCompetition) || event.is_a?(MbraTeamBar)
  else
    team_competition_result
  end
end
team_name=(value) click to toggle source
# File app/models/result.rb, line 417
def team_name=(value)
  team_id_will_change!
  if team.nil? || team.name != value
    self.team = Team.new(:name => value)
  end
  if person && person.team_name != value
    person.team = team
  end
  self[:team_name] = value
end
team_size() click to toggle source

TODO Cache this, too

# File app/models/result.rb, line 288
def team_size
  if race_id
    @team_size ||= Result.count(:conditions => ["race_id =? and place = ?", race_id, place])
  else
    @team_size ||= 1
  end
end
to_long_s() click to toggle source

Add race and +raceevent+ name, time and points to default #to_s

# File app/models/result.rb, line 445
def to_long_s
  "#<Result #{id}\t#{place}\t#{race.event.name}\t#{race.name} (#{race.id})\t#{name}\t#{team_name}\t#{self.category_name}\t#{points}\t#{time_s if self[:time]}>"
end
to_s() click to toggle source
# File app/models/result.rb, line 449
def to_s
  "#<Result #{id} place #{place} race #{race_id} person #{person_id} team #{team_id} pts #{points}>"
end
update_person_number() click to toggle source

Set +personnumber+ to number if this isn’t a rental number FIXME optimize default number issuer business

# File app/models/result.rb, line 163
def update_person_number
  discipline = Discipline[event.discipline]
  default_number_issuer = NumberIssuer.find_by_name(RacingAssociation.current.short_name)
  if person && event.number_issuer && event.number_issuer != default_number_issuer && number.present? && !RaceNumber.rental?(number, discipline)
    person.updated_by = self.updated_by
    person.add_number(number, discipline, event.number_issuer, event.date.year)
  end
end
validate_person_name() click to toggle source

Only used for manual entry of Cat 4 Womens Series Results

# File app/models/result.rb, line 245
def validate_person_name
  if first_name.blank? && last_name.blank?
    errors.add(:first_name, "and last name cannot both be blank")
  end
end