Rails date format in a text_field
Solution 1:
Simple one time solution is to use :value
option within text_field
call instead of adding something to ActiveRecord::Base
or CoreExtensions
.
For example:
<%= f.text_field :some_date, value: @model_instance.some_date.strftime("%d-%m-%Y") %>
Solution 2:
I added these to my initializers/time_formats.rb
and it works great:
# Default format for displaying dates and times
Date::DATE_FORMATS[:default] = "%m/%d/%Y"
Time::DATE_FORMATS[:default] = "%m/%d/%Y"
Using Ruby 1.9.3 and Rails 3.2.x
Solution 3:
I spent some time looking in the code, and changing the DATE_FORMAT won't work because Rails never asks for the date format. Felix's solution of setting :value does work, but feels cumbersome: why should I have to set the value of date-specific textfields by hand? So this is a codesmell, and I wanted something better.
Here's my short solution, but then I'll explain it a bit because I'm hoping somebody else will write something better:
MyModel < ActiveRecord::Base
# ...
self.columns.each do |column|
if column.type == :date
define_method "#{column.name}_before_type_cast" do
self.send(column.name).to_s
end
end
end
end
Somewhat longer explanation:
When a textfield is setting the value attribute, it'll first look in the options hash (which is why Felix's solution works), but if it's not there, it'll call form.object.check_in_date_before_type_cast
, which (after some method_missing magic) will call form.object.attributes_before_type_cast['check_in_date']
, which will look up 'check_in_date' in the @attributes hash inside form.object. My guess is that the @attributes hash is getting the direct MySQL string representation (which follows the 'yyyy-mm-dd' format) before it gets wrapped in a Ruby object, which is why simply setting the DATE_FORMAT doesn't work by itself. So the dynamic method creation above creates methods for all date objects that actually perform the typecast, allowing you to format the date using ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default]
.
This feels a little dirty because the whole purpose of '_before_type_cast' is to avoid a typecast, and this is one of those "thar be dragons" monkeypatches. But still, from what I can tell, it feels like the best of what's around. Maybe somebody else can do a little more digging and find a better solution?
Solution 4:
Expanding Kamil's answer a bit: add the following method to application_helper.rb:
def date_mdY(date)
if date.nil?
""
else
date.strftime("%m-%d-%Y")
end
end
Then you can modify Kamil's answer slightly:
<%= f.text_field :some_date, :value => date_mdY(@model_instance.some_date) %>
Then you can use this helper method in any other view.
I'm using the jQuery datepicker and the date needed to be in a particular format in order for the default date to be set correctly. Thanks for the answer Kamil!