Can't mass-assign protected attributes

Hi there. I started using rails (after reading docs on guides.rubyonrails.org/*) but I have a problem with "Can't mass-assign protected attributes" with the controllers (but not from the console). I will give an idea by commenting the code (I made it simple: just 2 entities).

First of all: % rails - v Rails 3.2.3

The models (generated using 'rails g scaffold'): % cat app/models/ project.rb class Project < ActiveRecord::Base   attr_accessible :file, :name   has_one :auction end

% cat app/models/ auction.rb class Auction < ActiveRecord::Base   belongs_to :projects   has_many :offers   attr_accessible :date_begin, :name end

And the schema with the migrations (already migrated):

% cat db/ schema.rb ActiveRecord::Schema.define(:version => 20120503182925) do

  create_table "auctions", :force => true do |t|     t.string "name"     t.datetime "date_begin"     t.integer "projects_id"     t.datetime "created_at", :null => false     t.datetime "updated_at", :null => false   end

  add_index "auctions", ["projects_id"], :name => "index_auctions_on_projects_id"

  create_table "projects", :force => true do |t|     t.string "name"     t.binary "file"     t.datetime "created_at", :null => false     t.datetime "updated_at", :null => false   end

end

I launch the console and create some projects, but then see what happens: % rails c irb(main):001:0> Project => Project(id: integer, name: string, file: binary, created_at: datetime, updated_at: datetime) irb(main):002:0> p = Project.new(name: 'foo', file: 'yaw') => #<Project id: nil, name: "foo", file: "yaw", created_at: nil, updated_at: nil> irb(main):003:0> p.save() => true irb(main):004:0> Project.all => [#<Project id: 6, name: "foo", file: "yaw", created_at: "2012-05-03 19:52:43", updated_at: "2012-05-03 19:52:43">]

irb(main):007:0> Auction => Auction(id: integer, name: string, date_begin: datetime, projects_id: integer, created_at: datetime, updated_at: datetime) irb(main):008:0> a = Auction.new(name: 'baz', date_begin: "2012-05-03 19:52:43", projects_id: 6) ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: projects_id   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ activemodel-3.2.3/lib/active_model/mass_assignment_security/ sanitizer.rb:48:in `process_removed_attributes'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ activemodel-3.2.3/lib/active_model/mass_assignment_security/ sanitizer.rb:20:in `debug_protected_attribute_removal'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ activemodel-3.2.3/lib/active_model/mass_assignment_security/ sanitizer.rb:12:in `sanitize'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ activemodel-3.2.3/lib/active_model/mass_assignment_security.rb:230:in `sanitize_for_mass_assignment'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ activerecord-3.2.3/lib/active_record/attribute_assignment.rb:75:in `assign_attributes'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ activerecord-3.2.3/lib/active_record/base.rb:498:in `initialize'   from (irb):8:in `new'   from (irb):8   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ railties-3.2.3/lib/rails/commands/console.rb:47:in `start'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ railties-3.2.3/lib/rails/commands/console.rb:8:in `start'   from /usr/local/Cellar/ruby/1.9.3-p194/lib/ruby/gems/1.9.1/gems/ railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'   from script/rails:6:in `require'   from script/rails:6:in `<main>'

To solve this problem, I modify the model in this way: class Auction < ActiveRecord::Base   belongs_to :projects   has_many :offers   attr_accessible :date_begin, :name, :projects_id                                                        ^^^^^^^^^^^^ end

And, relaunching the console, I can now instantiate an Auction object: irb(main):002:0> a = Auction.new(name: 'baz', date_begin: "2012-05-03 19:52:43", projects_id: 6) => #<Auction id: nil, name: "baz", date_begin: "2012-05-03 19:52:43", projects_id: 6, created_at: nil, updated_at: nil> irb(main):003:0> a.save() => true

I have generated the controllers using the scaffold method, and I haven't touched anything on them. The projects controller works perfectly: http://dl.dropbox.com/u/8724298/projects.png The auctions controller does not work at all with the error: "uninitialized constant Auction::Projects": http://dl.dropbox.com/u/8724298/auctions_1.png

To resolve the problem, I delete the element from the table: => [#<Auction id: 5, name: "baz", date_begin: "2012-05-03 19:52:43", projects_id: 6, created_at: "2012-05-03 19:56:35", updated_at: "2012-05-03 19:56:35">] irb(main):009:0> Auction.delete(5)   SQL (1.6ms) DELETE FROM "auctions" WHERE "auctions"."id" = 5 => 1 irb(main):010:0> Auction.all   Auction Load (0.2ms) SELECT "auctions".* FROM "auctions" =>

Now, if I want to add an auction object irb(main):011:0> Project.all   Project Load (0.1ms) SELECT "projects".* FROM "projects" => [#<Project id: 6, name: "foo", file: "yaw", created_at: "2012-05-03 19:52:43", updated_at: "2012-05-03 19:52:43">] Fill out the form: http://dl.dropbox.com/u/8724298/auctions_2.png And got the ActiveModel::MassAssignmentSecurity::Error in AuctionsController#create: http://dl.dropbox.com/u/8724298/auctions_3.png

The question is: where am I wrong? How do I have to customize the generated controller in order to work properly? Thank you very much!

The belongs_to in the Auction class looks incorrect.

class Auction belongs_to :project # and not :projects

end

And what do you have in config/routes.rb ? You shouldn’t be inputting project_id in a form, that should be part of the URL that creates the auction. Like this: http://localhost:3000/projects/6/auctions/new.

Regards

Vijay

I have a question

we don’t have acces to your link because it’s your local address ’ http://localhost:3000 '328.png

Rubyment Oliver Morel

Hi! Most probably I have chose the wrong mailing-list, but since you are helping, I am answering your questions and asking new questions! I modified the auction model like you said:

% cat app/models/auction.rb

          class Auction < ActiveRecord::Base   belongs_to :project   has_many :offers   attr_accessible :date_begin, :name, :projects_id, :project end

and also the _form: % cat app/views/auctions/_form.html.erb

         <%= form_for(@auction) do |f| %> ...   <div class="field">     <%= f.label :project %><br />     <%= f.text_field :project %>   </div> ... <% end %>

Now when I try to fill out the project_id (I know that the user should not inputs the project_id and I should get it from the url using routes, but I am trying this as a simple solution in order to learn rails): http://dl.dropbox.com/u/8724298/auction_4.png

And I get this error: http://dl.dropbox.com/u/8724298/auction_5.png

Perhaps in the controller I should extract the Project with the id passed in the form and retrieve the instance to use it when saving the Auction object? Thanks!

  1. Auction class should have attr_accessible :project_id (not :project, not :projects_id).

  2. The field in the form should also be project_id and not project.

Yes, you might have got more responses on the Rails Talk mailing list, the target list for such questions, which you can use in future.

Regards Vijay

I changed the code as you mentioned: % cat app/models/auction.rb

         class Auction < ActiveRecord::Base   belongs_to :project   has_many :offers   attr_accessible :date_begin, :name, :project_id end

% cat app/views/auctions/_form.html.erb

         <%= form_for(@auction) do |f| %> ...   <div class="field">     <%= f.label :project_id %><br />     <%= f.text_field :project_id %>   </div> ... <% end %>

When I open http://127.0.0.1:3000/auctions/new (so, before filling out the form), I receive this error: http://dl.dropbox.com/u/8724298/auction_6.png

I will keep in mind to write to the Talk mailing list in the future, I am finishing this thread here so I can at least insert an auction. Thanks again!

Sorry, I missed replying earlier.

Do you have a project_id column in the auctions table at all? If you can, please create a repo on github for your project so that we can help by pointing out specifics. I find this back and forth too time-consuming.