multiparameter error with datetime_select

后端 未结 6 747
傲寒
傲寒 2021-01-02 09:13

I have the following code in my form.

<%= f.datetime_select(:date_time, :prompt => {:day => \'Day\', :month => \'Month\', :year => \'Year\'},          


        
6条回答
  •  太阳男子
    2021-01-02 09:39

    Christian. This is a bug in Rails that checks the database to infer the type needed for the multiparameter attributes. My guess is that your "date_time" attribute is not associated with a time column in your database.

    I recently tackled this problem where I wanted a non-database attribute to accepted multiparameter attributes, this was the best solution I could come up with:

    I found myself wanting to set an attr_accessor to handle passing a date to my model in a form_for tag with the f.datetime_select helper. So this is what I had:

    Model:

    attr_accessor :my_time
    

    View:

    <%= f.datetime_select :my_time %>
    

    Unfortunately when I submit my form I get this:

    1 error(s) on assignment of multiparameter attributes
    

    Well it turns out that this is actually a Rails bug a ticket for which has been submitted. In the meantime how do we make this work? The only solution I could find that was remotely attractive was to make use of composed_of as a replacement for attr_accessor. so...

    Model:

      composed_of :my_time,
                  :class_name => 'Time',
                  :mapping => %w(Time to_s),
                  :constructor => Proc.new{ |item| item },
                  :converter => Proc.new{ |item| item }
    

    I know almost nothing about the composed_of method so you should probably do your own reading on it, but what I do know is that it creates both a reader and writer for the given instance variable, and more importantly, the setter accepts multiparameter attributes. How I chose the options:

    class_name: the name of our expected class. In this case, Time
    mapping: the first argument is the class and the second argument seems to work with any method that an instance of the class responds to. I chose to_s constructor: Not really sure how this is supposed to work. Seems to be called when @my_time is nil.
    converter: Not really sure how this is supposed to work. Seems to be called when from my_time=, but doesn't seem to be applied with mass assignment. One problem I ran into with this solution was that times were getting set in UTC instead of the environment's time zone. So unfortunately we cannot use my_time directly, but instead need to convert it to the proper time zone:

    Time.zone.parse(my_time.to_s(:number))
    

提交回复
热议问题