Greg Hauptmann
2009-Jan-11 10:08 UTC
Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
Hi, Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)? Here''s an example. The update of "id" versus update of a non-existent attribute. ?> ai = AccountItem.find(:first) => #<AccountItem id: 1, account_id: 1, date: "2009-01-11", amount: #<BigDecimal:22fb334,''0.1E2'',4(8)>, balance: #<BigDecimal:22fb1f4,''0.0'',4(8)>, description: "test", notes: nil, created_at: "2009-01-11 09:47:28", updated_at: "2009-01-11 09:47:28"> >> 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 >> thanks --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mikel Lindsaar
2009-Jan-11 11:38 UTC
Re: Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
On Sun, Jan 11, 2009 at 9:08 PM, Greg Hauptmann <greg.hauptmann.ruby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Why does ActiveRecord allow perception of success when updating an ID, > however it doesn''t really work(i.e. no change in database)?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. For what it''s worth, doing: account.update_attribute(:id, 1) or account.id = 1 account.save Both work. Hope that helps Mikel -- http://lindsaar.net/ Rails, RSpec and Life blog.... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Greg Hauptmann
2009-Jan-11 11:46 UTC
Re: Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
thanks Mike - I was trying to setup a spec that tests that my foreign key constraints would hold - I''ll try the method you suggest On Sun, Jan 11, 2009 at 9:38 PM, Mikel Lindsaar <raasdnil-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > On Sun, Jan 11, 2009 at 9:08 PM, Greg Hauptmann > <greg.hauptmann.ruby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Why does ActiveRecord allow perception of success when updating an ID, > > however it doesn''t really work(i.e. no change in database)? > > 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. > > For what it''s worth, doing: > > account.update_attribute(:id, 1) > > or > > account.id = 1 > account.save > > > Both work. > > Hope that helps > > Mikel > > -- > http://lindsaar.net/ > Rails, RSpec and Life blog.... > > > >-- Greg http://blog.gregnet.org/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Greg Hauptmann
2009-Jan-11 11:48 UTC
Re: Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
PS. Just noted the other methods also don''t work fyi - see below. That is it doesn''t seem to be mass assignment related. ?> ai = AccountItem.find(:first) => #<AccountItem id: 1, account_id: 1, date: "2009-01-11", amount: #<BigDecimal:22e80b8,''0.1E2'',4(8)>, balance: #<BigDecimal:22e7f78,''0.0'',4(8)>, description: "test", notes: nil, created_at: "2009-01-11 09:47:28", updated_at: "2009-01-11 09:47:28">>> ai.id = 100000=> 100000>> ai=> #<AccountItem id: 100000, account_id: 1, date: "2009-01-11", amount: #<BigDecimal:22e34b4,''0.1E2'',4(8)>, balance: #<BigDecimal:22e3374,''0.0'',4(8)>, description: "test", notes: nil, created_at: "2009-01-11 09:47:28", updated_at: "2009-01-11 09:47:28">>> ai.save=> true>>?> AccountItem.find(:all) => [#<AccountItem id: 1, account_id: 1, date: "2009-01-11", amount: #<BigDecimal:22db098,''0.1E2'',4(8)>, balance: #<BigDecimal:22daf58,''0.0'',4(8)>, description: "test", notes: nil, created_at: "2009-01-11 09:47:28", updated_at: "2009-01-11 09:47:28">]>>On Sun, Jan 11, 2009 at 9:38 PM, Mikel Lindsaar <raasdnil-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > On Sun, Jan 11, 2009 at 9:08 PM, Greg Hauptmann > <greg.hauptmann.ruby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Why does ActiveRecord allow perception of success when updating an ID, > > however it doesn''t really work(i.e. no change in database)? > > 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. > > For what it''s worth, doing: > > account.update_attribute(:id, 1) > > or > > account.id = 1 > account.save > > > Both work. > > Hope that helps > > Mikel > > -- > http://lindsaar.net/ > Rails, RSpec and Life blog.... > > > >-- Greg http://blog.gregnet.org/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mikel Lindsaar
2009-Jan-11 12:31 UTC
Re: Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
Now.. that is interesting To be honest, I''ve only ever used setting the id to a specific value on a new record... not on an existing one. The problem is that the following code in rails/activerecord/lib/base.rb is what does the update: def update(attribute_names = @attributes.keys) quoted_attributes = attributes_with_quotes(false, false, attribute_names) return 0 if quoted_attributes.empty? connection.update( "UPDATE #{self.class.quoted_table_name} " + "SET #{quoted_comma_pair_list(connection, quoted_attributes)} " + "WHERE #{connection.quote_column_name(self.class.primary_key)} #{quote_value(id)}", "#{self.class.name} Update" ) end As you can see, the WHERE clause is going to use id to find the record we are after, as you set id to a different value... that won''t work.... This code would have to be updated to allow id to be set using a "new_id" and "old_id" value pair... I think this is enough of an edge case though that you would be better served by making a new record and deleting the old one... like so: a = Account.find(1) new_account = Account.new(a.params) new_account.id = new_id new_account.save *should* work :) Mikel -- http://lindsaar.net/ Rails, RSpec and Life blog.... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mikel Lindsaar
2009-Jan-11 12:32 UTC
Re: Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
> a = Account.find(1) > new_account = Account.new(a.params) > new_account.id = new_id > new_account.save > > *should* work :)Well.. it most definitely won''t... You need: new_account = Account.new(a.attributes) and you might get further -- http://lindsaar.net/ Rails, RSpec and Life blog.... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Greg Hauptmann
2009-Jan-11 20:36 UTC
Re: Why does ActiveRecord allow perception of success when updating an ID, however it doesn''t really work(i.e. no change in database)?
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... On Sun, Jan 11, 2009 at 10:32 PM, Mikel Lindsaar <raasdnil-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > a = Account.find(1) > > new_account = Account.new(a.params) > > new_account.id = new_id > > new_account.save > > > > *should* work :) > > Well.. it most definitely won''t... > > You need: > > new_account = Account.new(a.attributes) > > and you might get further > > > -- > http://lindsaar.net/ > Rails, RSpec and Life blog.... > > > >-- Greg http://blog.gregnet.org/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Possibly Parallel Threads
- any tricks re using " eql(5.5)", but where 5.5 is a decimal not float?
- Cheapest Rails Hosting where they give you full access to Apache (to load modules etc)???
- Mail now in ActionMailer
- Mail now in ActionMailer
- How do I change MYSQL startup options on Mac??? (can't work it out)