If the value is stored as a date in the database, Rails will coerce the value from a string to a Ruby Date on assignment. I think it probably uses the built-in Date.parse
method (docs):
Date.parse "2012-10-20"
# => #<Date 2012-10-20 ...>
Date.parse "20-10-2012"
# => #<Date 2012-10-20 ...>
Date.parse "10-20-2012"
# => ArgumentError: invalid date
This being the case, you want to avoid the coercion and get your hands on a raw string to parse with Chronic. This is an ideal use-case for virtual attributes. There are a few ways you can do it, something like this should get you started
class User < ActiveRecord::Base
validate :birthday_is_date
# an explicit implementation
def birthday_string
if @birthday_string
@birthday_string
elsif birthday.present?
birthday.strftime("%d-%m-%Y")
else
""
end
end
# a shorter implementation
def birthday_string
@birthday_string || birthday.try(:strftime, "%d-%m-%Y")
end
def birthday_string=(value)
@birthday_string = value
self.birthday = parse_birthday
end
private
def birthday_is_date
errors.add(:birthday_string, "is invalid") unless parse_birthday
end
def parse_birthday
Chronic.parse(birthday_string)
end
end
And then use birthday_string
in your forms, instead of birthday
.