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:3000328.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.