views:

2237

answers:

8

I have a rails form with a datetime_select field. When I try to submit the form, I get the following exception:

ActiveRecord::MultiparameterAssignmentErrors in WidgetsController#update 
1 error(s) on assignment of multiparameter attributes

If it's a validation error, why don't I see an error on the page?

This is in Rails 2.0.2

+4  A: 

It turns out that rails uses something called Multi-parameter assignment to transmit dates and times in small parts that are reassembled when you assign params to the model instance.

My problem was that I was using a datetime_select form field for a date model field. It apparently chokes when the multi-parameter magic tries to set the time on a Date object.

The solution was to use a date_select form field rather than a datetime_select.
Jason Wadsworth
+1  A: 

ActiveRecord throws the MultiparameterAssignmentErrors exception when you try to set an invalid date to a models attribute.

Try to pick a Nov 31 date from the date_select or datetime_select dropdown and you will get this error.

franee
A: 

What if we want to use datetime_select? Is it now broken?

elliott
this is not an answer!
Labuschin
A: 

This error can also occur with webrat/cucumber when filling in form data using a table.

eg this doesn't work:

When I fill in the following:
  | report_from_1i | 2010     |
  | report_from_2i | January  |
  | report_from_3i | 1        |
  | report_to_1i   | 2010     |
  | report_to_2i   | February |
  | report_to_3i   | 1        |

but this does:

When I fill in the following:
  | report_from_1i | 2010 |
  | report_from_2i | 1    |
  | report_from_3i | 1    |
  | report_to_1i   | 2010 |
  | report_to_2i   | 2    |
  | report_to_3i   | 1    |
Zubin
+1  A: 

Super hack, but I needed to solve this problem right away for a client project. It's still a bug with Rails 2.3.5.

Using either date_select or datetime_select, if you add this to your model in the initialize method, you can pre-parse the passed form-serialized attributes to make it work:

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

I am using this with a nested, polymorphic, model. Here's a question I had showing the models I'm using. So I needed accepts_nested_attributes_for with a datetime.

Here's the input and output using the console:

e = Event.last
=> #<Event id: 1052158304 ...>
e.model_surveys
=> []
e.model_surveys_attributes = [{"survey_id"=>"864743981", "deliver_date(1i)"=>"2010", "deliver_date(2i)"=>"2", "deliver_date(3i)"=>"11"}]
PRE ATTRIBUTES: {"survey_id"=>"864743981", "deliver_date(1i)"=>"2010", "deliver_date(2i)"=>"2", "deliver_date(3i)"=>"11"}
# run date_hack
POST ATTRIBUTES: {"survey_id"=>"864743981", "deliver_date"=>"2010-2-11"}
e.model_surveys
=> [#<ModelSurvey id: 121, ..., deliver_date: "2010-02-11 05:00:00">]
>> e.model_surveys.last.deliver_date.class
=> ActiveSupport::TimeWithZone

Otherwise it was either null, or it would throw the error:

1 error(s) on assignment of multiparameter attributes

Hope that helps, Lance

viatropos
A: 

In my case the ActiveRecord am/pm plugin caused the error through an incorrect alias_method_chain resulting in an StackLevelTooDeep exception.

The plugin was included by the unobtrusive_date_picker plugin.

The look into this before hacking away.

mikezter
A: 

simple: the model attribute is missing in the backing database table

don
A: 

Like Zubin I've seen this exception when the form submits a month as a month name rather than a numerical month string (eg. October rather than 10).

One user agent I've encountered seems to submit the contents of the option tag rather than the value attribute:

Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE66-1/300.21.012; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413

So in the case of submitting a multi-parameter date from a helper generated select (from date_select helper) your params will have:

"event"=> {
    "start_on(2i)"=>"October",
    "start_on(3i)"=>"19",
    "start_on(1i)"=>"2010"
}

This creates an exception: ActiveRecord::MultiparameterAssignmentErrors: 1 error(s) on assignment of multiparameter attributes

Most user agents will correctly submit:

"event"=> {
    "start_on(2i)"=>"10",
    "start_on(3i)"=>"19",
    "start_on(1i)"=>"2010"
}
nutcracker