class MultiDayEvent

Event that spans more than one day: stage races, six days, omniums MultiDayEvents represent events that occur on concurrent days, and Series and WeeklySeries subclasses represent events that do not occur on concurrent days, though this is just a convention.

Calculate start_date, end_date, and date from children. date = start_date

Cannot have a parent event

New child event should populate child event with parent data, but they don’t

Public Class Methods

create_from_children(children) click to toggle source

Create MultiDayEvent from several SingleDayEvents. Use first SingleDayEvent to populate date, name, promoter, etc. Guess subclass (MultiDayEvent, Series, WeeklySeries) from SingleDayEvent dates

# File app/models/multi_day_event.rb, line 85
def MultiDayEvent.create_from_children(children)
  raise ArgumentError.new("children cannot be empty") if children.empty?
  
  first_event = children.first
  new_event_attributes = {
    :city => first_event.city,
    :discipline => first_event.discipline,
    :email => first_event.email,
    :flyer => first_event.flyer,
    :name => first_event.name,
    :phone => first_event.phone,
    :promoter => first_event.promoter,
    :prize_list => first_event.prize_list,
    :sanctioned_by => first_event.sanctioned_by,
    :state => first_event.state,
    :team => first_event.team,
    :velodrome => first_event.velodrome
  }
  
  new_multi_day_event_class = MultiDayEvent.guess_type(children)
  multi_day_event = new_multi_day_event_class.create!(new_event_attributes)
  multi_day_event.disable_notification!

  children.each do |child|
    multi_day_event.children << child
  end

  multi_day_event.enable_notification!
  multi_day_event
end
find_all_by_conditions(conditions, discipline = nil) click to toggle source
# File app/models/multi_day_event.rb, line 68
def MultiDayEvent.find_all_by_conditions(conditions, discipline = nil)
  if RacingAssociation.current.show_only_association_sanctioned_races_on_calendar
    conditions.first << " and sanctioned_by = ?"
    conditions << RacingAssociation.current.default_sanctioned_by
  end

  if discipline
    conditions.first << " and discipline = ?"
    conditions << discipline.name
  end

  MultiDayEvent.all( :conditions => conditions, :order => "date")
end
find_all_by_unix_dates(start_date, end_date, discipline = nil) click to toggle source
# File app/models/multi_day_event.rb, line 63
def MultiDayEvent.find_all_by_unix_dates(start_date, end_date,  discipline = nil)
  conditions = ["date between ? and ?", "#{Time.at(start_date.to_i).strftime('%Y-%m-%d')}", "#{Time.at(end_date.to_i).strftime('%Y-%m-%d')}"]
  MultiDayEvent.find_all_by_conditions(conditions, discipline)
end
find_all_by_year(year, discipline = nil) click to toggle source
# File app/models/multi_day_event.rb, line 58
def MultiDayEvent.find_all_by_year(year, discipline = nil)
  conditions = ["date between ? and ?", "#{year}-01-01", "#{year}-12-31"]
  MultiDayEvent.find_all_by_conditions(conditions, discipline)
end
guess_type(name, date) click to toggle source
# File app/models/multi_day_event.rb, line 116
def MultiDayEvent.guess_type(name, date)
  events = SingleDayEvent.all( :conditions => ['name = ? and extract(year from date) = ?', name, date])
  MultiDayEvent.guess_type(events)
end
same_name_and_year(event) click to toggle source
# File app/models/multi_day_event.rb, line 136
def MultiDayEvent.same_name_and_year(event)
  raise ArgumentError, "'event' cannot be nil" if event.nil?
  MultiDayEvent.first(:conditions => ['name = ? and extract(year from date) = ?', event.name, event.date.year])
end

Public Instance Methods

completed?(reload = false) click to toggle source

All children have results?

# File app/models/multi_day_event.rb, line 234
def completed?(reload = false)
  children.count(reload) > 0 && (children_with_results(reload).size == children.count)
end
create(attributes = {}) click to toggle source
# File app/models/multi_day_event.rb, line 45
def create(attributes = {})
  attributes[:parent_id] = @owner.id
  attributes[:parent] = @owner
  Event::PROPOGATED_ATTRIBUTES.each { |attr| attributes[attr] = @owner[attr] }               
  event = SingleDayEvent.new(attributes)
  (event.date = @owner.date) unless attributes[:date]
  event.parent = @owner
  event.save
  @owner.children << event
  event
end
create!(attributes = {}) click to toggle source
# File app/models/multi_day_event.rb, line 33
def create!(attributes = {})
  attributes[:parent_id] = @owner.id
  attributes[:parent] = @owner
  Event::PROPOGATED_ATTRIBUTES.each { |attr| attributes[attr] = @owner[attr] }               
  event = SingleDayEvent.new(attributes)
  (event.date = @owner.date) unless attributes[:date]
  event.parent = @owner
  event.save!
  @owner.children << event
  event
end
create_children() click to toggle source

Create child events automatically, if we’ve got enough info to do so

# File app/models/multi_day_event.rb, line 142
def create_children
  return unless start_date && @end_date && @every
  
  _start_date = start_date
  until @every.include?(_start_date.wday)
    _start_date = _start_date.next 
  end
  
  _start_date.step(@end_date, 1) do |date|
    children.create!(:date => date) if @every.include?(date.wday)
  end
end
date_range_long_s() click to toggle source
# File app/models/multi_day_event.rb, line 215
def date_range_long_s
  start_date_s = start_date.strftime('%a, %B %d')
  if start_date == end_date
    start_date_s
  else
    "#{start_date_s} to #{end_date.strftime('%a, %B %d, %Y')}"
  end
end
date_range_s(format = :short) click to toggle source

format:

  • :short: 6/7-6/12

  • :long: 6/7/2010-6/12/2010

# File app/models/multi_day_event.rb, line 196
def date_range_s(format = :short)
  if format == :long
    if start_date == end_date
      date.strftime('%m/%d/%Y')
    else
      "#{start_date.strftime('%m/%d/%Y')}-#{end_date.strftime('%m/%d/%Y')}"
    end
  else
    start_date_s = "#{start_date.month}/#{start_date.day}"
    if start_date == end_date
      start_date_s
    elsif start_date.month == end_date.month
        "#{start_date_s}-#{end_date.day}"
    else
      "#{start_date_s}-#{end_date.month}/#{end_date.day}"
    end
  end
end
end_date=(value) click to toggle source

end_date is calculated from child events, and not saved to the DB. If there are no child events, end_date is set to start date. This value is stored in @end_date in memory, and is used to create a new MultiDayEvent with children. Example: #create!(:start_date => Date.new(2009, 4), :end_date => Date.new(2009, 10), :every => “Monday”)

# File app/models/multi_day_event.rb, line 173
def end_date=(value)
  @end_date = value
end
end_date_s() click to toggle source
# File app/models/multi_day_event.rb, line 177
def end_date_s
  "#{end_date.month}/#{end_date.day}"
end
every=(value) click to toggle source

Expects a value from Date::DAYNAMES: Monday, Tuesday, etc., or an array of same. Example: [“Saturday”, “Sunday”]

# File app/models/multi_day_event.rb, line 182
def every=(value)
  _every = value
  _every = [_every] unless value.respond_to?(:each)
  
  _every.each do |day|
    raise "'#{day}' must be in #{Date::DAYNAMES.join(', ')}" unless Date::DAYNAMES.index(day)
  end

  @every = _every.map { |day| Date::DAYNAMES.index(day) }
end
missing_children() click to toggle source

Unassociated events with same name in same year

# File app/models/multi_day_event.rb, line 225
def missing_children
  return [] unless name && date
  
  @missing_children ||= SingleDayEvent.all( 
                        :conditions => ['parent_id is null and name = ? and extract(year from date) = ?', 
                                        name, date.year])
end
propagate_races() click to toggle source

Synch Races with children. More accurately: create a new Race on each child Event for each Race on the parent.

# File app/models/multi_day_event.rb, line 239
def propagate_races
  children.each do |event|
    races.map(&:category).each do |category|
      unless event.races.map(&:category).include?(category)
        event.races.create!(:category => category)
      end
    end
  end
end
to_s() click to toggle source
# File app/models/multi_day_event.rb, line 249
def to_s
  "<#{self.class} #{id} #{discipline} #{name} #{date} #{children.size}>"
end
update_date(child = nil) click to toggle source

Uses SQL query to set date from child events

# File app/models/multi_day_event.rb, line 156
def update_date(child = nil)
  return true if new_record?
  
  minimum_date = Event.minimum(:date, :conditions => { :parent_id => id, :cancelled => false, :postponed => false })
  unless minimum_date.blank?
    self.date = minimum_date
    if date_changed?
      # Don't trigger callbacks
      MultiDayEvent.update_all ["date = ?", date], ["id = ?", id]
    end
  end
  true
end