Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes

If I try to execute the following code:

hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms")

I obain the following error:

Failure/Error: hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms")
 ActiveModel::MassAssignmentSecurity::Error:
   Can't mass-assign protected attributes: type

I am not sure what this means. I have made the :type to be compulsory, so if I do remove it, I get an sql error.

like image 462
Karan Avatar asked May 13 '12 20:05

Karan


2 Answers

A couple things:

Mass Assignment usually means passing attributes into the call that creates an object as part of an attributes hash. That is, you pass a bunch of attributes in a hash into the call that creates the new object. For example:

@user = User.create({:name => "My name", :user_type => "nice_user"})

However, Rails includes some basic security rules that mean not all attributes can be assigned that way by default. You have to specify which ones can beforehand. You do so like this:

class User < ActiveRecord::Base
  attr_accessible :name, :user_type
end

If you don't specify an attribute is attr_accessible, and you pass it in to create the object, you get the error you posted.

Here are more details:

http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

The alternative is to set some of the attributes when you first create the record, and set others after -- like so:

# In this example `user_type` is not attr_accessible so it needs to be set specifically
@user = User.create({:name => "My name"})
@user.user_type = "nice_user"
@user.save

In addition, if you're having issues with using the column name type because rails is getting confused and thinks you want to use Single Table Inheritance (STI), check the answer to this question to see how to get around it: http://guides.rubyonrails.org/

like image 76
Kevin Bedell Avatar answered Sep 29 '22 03:09

Kevin Bedell


Are you working with Rails 3.2 while following a 3.1 tutorial such as the Pragmatic Programmer's "Agile Web Development with Rails" 4th edition? Then check http://guides.rubyonrails.org/3_2_release_notes.html.

Your problem is that from Rails 3.1 to 3.2 checking of mass assignment protection for Active Record models is set to 'strict' by default. Comment out the appropriate lines in these files:

config/environments/development.rb
config/environments/test.rb

... and you're good to go on learning. Remember to leave this in effect when coding your first production application :)

like image 21
LANerd Avatar answered Sep 29 '22 04:09

LANerd