@@ -4,7 +4,6 @@ module DateAccessible
44 TAX_YEAR = Date . new ( Rails . configuration . statefile_current_tax_year )
55
66 included do
7- private
87
98 # Calls `date_reader` and `date_writer` on specified date properties to set
109 # getters and setters on the specified date properties. For use with
@@ -28,17 +27,7 @@ def self.date_reader(*properties)
2827 properties = [ properties ] unless properties . is_a? ( Enumerable )
2928
3029 properties . each do |property |
31- self . define_method ( "#{ property } _month" ) do
32- send ( property ) &.month
33- end
34-
35- self . define_method ( "#{ property } _year" ) do
36- send ( property ) &.year
37- end
38-
39- self . define_method ( "#{ property } _day" ) do
40- send ( property ) &.day
41- end
30+ attr_reader :"#{ property } _month" , :"#{ property } _year" , :"#{ property } _day"
4231 end
4332 end
4433
@@ -52,42 +41,32 @@ def self.date_writer(*properties)
5241 properties = [ properties ] unless properties . is_a? ( Enumerable )
5342
5443 properties . each do |property |
55- self . define_method ( "#{ property } _month=" ) do |month |
56- change_date_property ( property , month : month ) unless month . blank?
57- end
44+ attr_writer :"#{ property } _month" , :"#{ property } _year" , :"#{ property } _day"
5845
59- self . define_method ( "#{ property } _year=" ) do |year |
60- change_date_property ( property , year : year ) unless year . blank?
46+ before_validation do
47+ send (
48+ "#{ property } =" ,
49+ Date . new (
50+ send ( "#{ property } _year" ) . to_i ,
51+ send ( "#{ property } _month" ) . to_i ,
52+ send ( "#{ property } _day" ) . to_i ,
53+ )
54+ )
55+ rescue Date ::Error
56+ send ( "#{ property } =" , nil )
6157 end
6258
63- self . define_method ( "#{ property } _day=" ) do |day |
64- change_date_property ( property , day : day ) unless day . blank?
59+ self . class_eval do
60+ validate :"#{ property } _date_valid"
61+
62+ define_method ( "#{ property } _date_valid" ) do
63+ date = send ( property )
64+ if date . present? && !Date . valid_date? ( date . year , date . month , date . day )
65+ errors . add ( property , :invalid_date , message : "is not a valid calendar date" )
66+ end
67+ end
6568 end
6669 end
6770 end
68-
69- # Takes in valid arguments to Date#change. Will create a new date if
70- # `date_of_contribution` is nil, otherwise will merely modify the correct
71- # date part. Values can be strings as long as #to_i renders an appropriate
72- # integer. Note that Date#change only accepts :year, :month, and :day as
73- # keys, all other keys will be treated as nothing was passed at all.
74- #
75- # Note that until all three fragments are passed; month, day, and year
76- # For year, a range must be indicated on the validator on the property itself
77- #
78- # @see Date#change
79- #
80- # @param date_property [Symbol] The property to manipulate
81- # @param args [Hash<Symbol, String | Integer>] Arguments conforming to Date#change
82- def change_date_property ( date_property , args )
83- existing_date = send ( date_property ) || Date . new
84-
85- self . send (
86- "#{ date_property } =" ,
87- existing_date . change ( **args . transform_values ( &:to_i ) )
88- )
89- rescue Date ::Error
90- nil
91- end
9271 end
9372end
0 commit comments