Neil Middleton
Neil Middleton

Reputation: 22238

Rails ActiveRecord::MultiparameterAssignmentErrors

I have the following code in my model:

attr_accessor :expiry_date
validates_presence_of :expiry_date, :on        => :create, :message => "can't be blank"

and the following in my view:

<%= date_select :account, :expiry_date, :discard_day => true, :start_year => Time.now.year, :end_year => Time.now.year + 15, :order => [:month, :year]  %>

However, when I submit my form I get:

ActiveRecord::MultiparameterAssignmentErrors in SignupController#create

/Users/x/.rvm/gems/ruby-1.8.6-p383/gems/activerecord-2.3.5/lib/active_record/base.rb:3073:in `execute_callstack_for_multiparameter_attributes'
/Users/x/.rvm/gems/ruby-1.8.6-p383/gems/activerecord-2.3.5/lib/active_record/base.rb:3028:in `assign_multiparameter_attributes'
/Users/x/.rvm/gems/ruby-1.8.6-p383/gems/activerecord-2.3.5/lib/active_record/base.rb:2750:in `attributes='
/Users/x/.rvm/gems/ruby-1.8.6-p383/gems/activerecord-2.3.5/lib/active_record/base.rb:2438:in `initialize'

Any ideas as to what the problem might be? I've looked at #93277 with no joy, so am kinda stuck.

Adding day to the select does NOT resolve the issue.

Ultimately what I am trying to acheive is a property of the model that is not saved to the database, but is validated. This already appears to work for some other simple string fields in the same model, just not the :expiry_date

Any ideas?

Upvotes: 3

Views: 2042

Answers (2)

pkoch
pkoch

Reputation: 2722

As per https://github.com/rails/rails/blob/v3.0.4/activerecord/lib/active_record/base.rb#L1764, Rails will ask the class what's the type for that column. Since that attribute is not a column, we'll get nil, and nil has no method klass. So, I just patched column_for_attribute. I put this in my class (my attribute was birth_date):

def column_for_attribute_with_birth_date(name)
  if name == 'birth_date'
    return Object.new.tap do |o|
      def o.klass
        Date
      end
    end
  end
  column_for_attribute_without_birth_date(name)
end
alias_method_chain :column_for_attribute, :birth_date

Upvotes: 1

Franck Verrot
Franck Verrot

Reputation: 1041

If you use attr_accessor it means you're not storing that field in the DB.

The issue remains in the fact that you cannot use a non-persistent model attribute (ie: not actually stored into the DB via the model) with helpers.

That's why Rails 3 has got ActiveModel: to use any object, include some ActiveModel behavior (via module inclusion), and use it with ActionPack's helpers (if I understood it all well :)).

Try replacing attr_accessor by attr_accessible or even drop that line if you want to protect that field from mass-assignment.

I hope it helps.

Upvotes: 0

Related Questions