Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiparameter error with datetime_select

I have the following code in my form.

<%= f.datetime_select(:date_time, :prompt => {:day => 'Day', :month => 'Month', :year => 'Year'}, :start_year => Date.today.year, :end_year => Date.today.year + 2, :minute_step => 15, :include_blank => false) %> if either one is blank.

When one of the fields is left blank, I get:

1 error(s) on assignment of multiparameter attributes

The params that are being passed are:

{"utf8"=>"✓",
 "authenticity_token"=>"kQpfsj5RxnDtxkvBdwPEFnX1fY6euKnMQeDRAkvJvIE=",
 "event"=>{"description"=>"",
 "venue"=>"",
 "street"=>"",
 "city"=>"",
 "country_id"=>"",
 "date_time(1i)"=>"",
 "date_time(2i)"=>"",
 "date_time(3i)"=>"",
 "date_time(4i)"=>"00",
 "date_time(5i)"=>"00",
 "ticket_url"=>""},
 "x"=>"94",
 "y"=>"12"}

Anyone know why this is occurring?

There seems to be a "dirty" fix for this at this link, but perhaps there is a better solution in Rails 3?

like image 356
Christian Fazzini Avatar asked Jan 17 '11 10:01

Christian Fazzini


2 Answers

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))
like image 118
gabeodess Avatar answered Nov 07 '22 05:11

gabeodess


What Does ActiveRecord::MultiparameterAssignmentErrors Mean?

def initialize(attributes={})
  date_hack(attributes, "deliver_date")
  super(attributes)
end   

def date_hack(attributes, property)
  keys, values = [], []
  attributes.each_key {|k| keys << k if k =~ /#{property}/ }.sort
  keys.each { |k| values << attributes[k]; attributes.delete(k); }
  attributes[property] = values.join("-")
end
like image 37
tiny Avatar answered Nov 07 '22 06:11

tiny