Ruby Forum Ruby on Rails > MultiparameterAssignmentErrors when feeding a bogus day/month combination into a date_select--how be

Posted by Roy Pardee (rpardee)
on 19.08.2008 21:13
(Received via mailing list)
Hey All,

My user just got bit by this problem (in my rails version 2.0.2 app):

http://railsmanual.com/class/ActiveRecord::MultiparameterAssignmentErrors

That is, if you use the date_select generated list boxes to select a 
nonexistant date like say, April 31st, you get a stack trace like this 
here:

  c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2397:in 
`execute_callstack_for_multiparameter_attributes'
  c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2377:in 
`assign_multiparameter_attributes'
  c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2120:in 
`attributes='
  c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2033:in 
`update_attributes'
  app/controllers/projects_controller.rb:76:in `update'
  app/controllers/projects_controller.rb:75:in `update'

You get the same exception if you

So... is there some particularly good place to fix this?  I can 
certainly pull the date components out of params[] in my controller, try 
a Date.parse() on them & give the user a better error message.  But I've 
got date_select's in lots of different places in my app & would love it 
if I could just fix it in one spot...

I've looked in the attributes=() method in ar:base, but am a bit daunted 
by it--have a hard time imagining I'm going to do more good than harm in 
there... :(

Anybody got ideas for me?

Thanks!

-Roy

Roy Pardee
Research Analyst/Programmer
Group Health Center For Health Studies (Cancer Research Network)
(206) 287-2078
Google Talk: rpardee
Posted by Roy Pardee (rpardee)
on 19.08.2008 23:06
(Received via mailing list)
This seems to work, but it's hardly DRY:

  def update
    @project = Project.find(params[:id])
    respond_to do |format|
      begin
        if @project.update_attributes(params[:project])
          flash[:notice] = 'Project was successfully updated.'
          format.html { redirect_to(@project) }
          format.xml  { head :ok }
        else
          format.html { render :action => "edit" }
          format.xml  { render :xml => @project.errors, :status => 
:unprocessable_entity }
        end
      rescue ActiveRecord::MultiparameterAssignmentErrors
        @project.errors.add("end_date"  , "May be bogus")
        @project.errors.add("start_date", "May be bogus")
        format.html { render :action => "edit" }
        format.xml  { render :xml => @project.errors, :status => 
:unprocessable_entity }
      end
    end
  end

I'd have to repeat that for every update and create action :P

It looks like the root cause is that Date.new(), unlike other 
constructors in ruby (I think?), throws an ArgumentError exception if 
you give it something it doesn't understand.  The others seem to give a 
default value (e.g., 0 for integers, false for booleans).

I dug a little deeper in ar:base.rb--still don't see a good place to 
muck around in there. :(