diff --git a/lib/validates_timeliness/extensions/date_time_select.rb b/lib/validates_timeliness/extensions/date_time_select.rb index 03ca7fd..5906593 100644 --- a/lib/validates_timeliness/extensions/date_time_select.rb +++ b/lib/validates_timeliness/extensions/date_time_select.rb @@ -14,8 +14,32 @@ module ValidatesTimeliness module InstanceMethods - TimelinessDateTime = Struct.new(:year, :month, :day, :hour, :min, :sec) - + class TimelinessDateTime + + attr_accessor :year, :month, :day, :hour, :min, :sec + + def initialize(year, month, day, hour, min, sec) + @year = year + @month = month + @day = day + @hour = hour + @min = min + @sec = sec + end + + # adapted from activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 36 (3.0.7) + def change(options) + TimelinessDateTime.new( + options[:year] || year, + options[:month] || month, + options[:day] || day, + options[:hour] || hour, + options[:min] || (options[:hour] ? 0 : min), + options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec) + ) + end + end + def datetime_selector_with_timeliness(*args) @timeliness_date_or_time_tag = true datetime_selector_without_timeliness(*args) @@ -32,7 +56,7 @@ module ValidatesTimeliness values = [nil] * 6 pairs.map do |(param, value)| position = param.scan(/\(([0-9]*).*\)/).first.first - values[position.to_i-1] = value + values[position.to_i-1] = value.to_i end TimelinessDateTime.new(*values) diff --git a/spec/validates_timeliness/extensions/date_time_select_spec.rb b/spec/validates_timeliness/extensions/date_time_select_spec.rb index 2ac9796..298e156 100644 --- a/spec/validates_timeliness/extensions/date_time_select_spec.rb +++ b/spec/validates_timeliness/extensions/date_time_select_spec.rb @@ -101,6 +101,20 @@ describe ValidatesTimeliness::Extensions::DateTimeSelect do @output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true) should_not_have_datetime_selected(:birth_time, :year, :month, :day) end + + it "should support discarding of the day part" do + # this doesn't make sense for birthdays, but it does for credit card expirations, for example + @params["person"] = { + "birth_date(1i)" => 2009, + "birth_date(2i)" => 2, + } + person.birth_date = nil + @output = date_select(:person, :birth_date, :discard_day => true) + should_have_datetime_selected(:birth_date, :year => 2009, :month => 'February') + should_not_have_datetime_selected(:birth_date, :day) + @output.should have_tag("input[id=person_birth_date_3i][type=hidden][value='1']") + end + end describe "time_select" do