app/models/concerns/date_support.rb
module DateSupport
extend ActiveSupport::Concern
included do
after_initialize :init_dates
def init_dates
self.dates ||= []
end
### Calendar::DateValue
# Required by coocon
def build_date_value
Calendar::DateValue.new
end
def date_values
@date_values ||= init_date_values
end
def init_date_values
if dates
dates.each_with_index.map { |d, index| Calendar::DateValue.from_date(index, d) }
else
[]
end
end
private :init_date_values
validate :validate_date_values
def validate_date_values
date_values_are_valid = date_values.all?(&:valid?)
date_values.each do |date_value|
if date_values.count { |d| d.value == date_value.value } > 1
date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_dates'))
date_values_are_valid = false
end
date_ranges.each do |date_range|
if date_range.cover?(date_value.value)
excluded_day = self.respond_to?(:valid_day?) && !self.valid_day?(date_value.value.wday)
unless excluded_day
date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges'))
date_values_are_valid = false
end
end
end
end
unless date_values_are_valid
errors.add(:date_values, :invalid)
end
end
def date_values_attributes=(attributes = {})
@date_values = []
attributes.each do |index, date_value_attribute|
date_value_attribute['value'] = flatten_date_array(date_value_attribute, 'value')
date_value = Calendar::DateValue.new(date_value_attribute.merge(id: index))
@date_values << date_value unless date_value.marked_for_destruction?
end
dates_will_change!
end
before_validation :fill_dates
def fill_dates
if @date_values
self.dates = @date_values.map(&:value).compact.sort
end
end
after_save :clear_date_values
def clear_date_values
@date_values = nil
end
private :clear_date_values
end
end