ai.update_attributes!(:id => 99999)
=> true # SEEMS TO INDICATE IT WORKED
AccountItem.find(:all)
=> [#<AccountItem id: 1, account_id: 1, date: “2009-01-11”, amount: #BigDecimal:22f27c0,‘0.1E2’,4(8), balance: #BigDecimal:22f2680,‘0.0’,4(8), description: “test”, notes: nil, created_at: “2009-01-11 09:47:28”, updated_at: “2009-01-11 09:47:28”>] # IT DIDN’T AS THE ID IS STILL 1
?> ai.update_attributes!(:XXXX => 99999)
NoMethodError: undefined method XXXX=' for #<AccountItem:0x22fc6a8> <== THIS IS A BIT MORE LIKE YOU WOULD EXPECT from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/attribute_methods.rb:251:in method_missing’
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:2372:in send' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:2372:in attributes=’
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:2371:in each' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:2371:in attributes=’
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:2278:in `update_attributes!’
from (irb):60
That is because :id is a special case and is protected from mass assignment.
The reason it "works" or says that it does is because when you submit
an update form, you might have a params hash that looks like:
params[:account] #=> {:id => 2, :name => "Bob"}
and you will then do:
a = Account.find(params[:account][:id])
a.update_attributes(params[:account])
Now... in 99% of cases, you want this update_attributes command to
work, but you definately do NOT want some smartarse out there sending
in a carefully crafted web request that changes the ID value of the
account!
So that's why, update_attributes "silently" ignores any attribute that
is protected from mass assignment.
Actually... it doesn't ignore it. Look in your logs and you will see
something along the lines of "Can't mass assign protected attribute
:id" or something.
thanks - given all of this what do you think about the fact Rails doesn’t highlight the issue via exception? It still seems misleading to me the way it works…