Rails date format in a text_field

后端 未结 14 2166
傲寒
傲寒 2020-12-13 06:05

I have a rails form that displays a date in a text_field:

<%= form.text_field :check_in_date  %>

The date is rendered as yyyy-m

相关标签:
14条回答
  • 2020-12-13 06:52

    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?

    0 讨论(0)
  • 2020-12-13 06:54

    I had similar problems with time attributes/fields. So one can follow this:

    http://railscasts.com/episodes/32-time-in-text-field

    And it works pretty well.

    But I dug into and found another interesting solution. Kind of a ugly monkeypatch, but in some cases it could be more useful that the one from railscasts.

    So I have a model with a column named time (ofc it has a time type). Here is my solution:

      after_initialize :init
    
      private
      def init
        unless time.nil?
          @attributes['time'] = I18n.l(time, format: :short)
        end
      end
    

    As you can see I format the variable which going to be returned by time_before_type_cast method. So I have properly formatted time in my text input (rendered by FormBuilder), but if user puts something wrong like 10;23 I still have this and in next request it will be rendered by FormBuilder::text_field. So user has an opportunity to fix his miserable mistake.

    0 讨论(0)
提交回复
热议问题