In Rails, the primary key, by default ''id'', is used all over the place. However, Ruby now deprecates the use of constructs like: @post = Post.find(:first) @post_id = @post.id I buy the rationale, as the Object#id is something of a reserved method. However, changing all references to use [:id], while seemingly the correct approach, also has the unwanted side-effect of breaking every mock created using mock_model that references the id that way. Sure, I can go in and stub [] to return self[:id] for each mock object, but that ActiveRecord objects behave more as a hash than as an object (IMO), so there are things like: @post[:body_text] peppered throughout the codebase, and a big hammer like a stub of the []() method would also break specs. So the conundrum is how to make mock_model respond only to the []() method with an argument of :id to return self[:id]. Questions: 1. Is there something bogus in my assumption that using @post[:id] is preferred to @post.id? 2. Has anyone solved this problem and if so what worked? BTW: I am aware that :to_param returns the id, but it seems counter- intuitive to read code that takes advantage of this quirk. Thanks, Steve
On Tue, Nov 25, 2008 at 11:04 AM, s.ross <cwdinfo at gmail.com> wrote:> In Rails, the primary key, by default ''id'', is used all over the > place. However, Ruby now deprecates the use of constructs like: > > @post = Post.find(:first) > @post_id = @post.id >These are different methods. Object#id is indeed deprecated, but ActiveRecord::Base#id is perfectly fine. ///ark -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081125/b94c45f4/attachment.html>
On Tue, Nov 25, 2008 at 2:04 PM, s.ross <cwdinfo at gmail.com> wrote:> In Rails, the primary key, by default ''id'', is used all over the > place. However, Ruby now deprecates the use of constructs like: > > @post = Post.find(:first) > @post_id = @post.idI think you''ve got the wrong end of the stick there. Object#id (which returns a unique id for the Ruby object) was deprecated in favor of Object#object_id, mostly because ActiveRecord overrides it to return the primary key. #id seemed in retrospect too common to be reserved for an implementation detail. You *should* use model.id to get the primary key. If you''re getting that warning, you''re calling #id on something that doesn''t decend from ActiveRecord::Base. #id is one of the few things that nil responds to (and issues the deprecation warning); maybe there are no Posts in your DB? Try checking the value of @post. Peter
On 2008-11-25, at 14:04, s.ross wrote:> In Rails, the primary key, by default ''id'', is used all over the > place. However, Ruby now deprecates the use of constructs like: > > @post = Post.find(:first) > @post_id = @post.id > > ..snip.. > > Thanks, > > SteveHi Steve. Ruby deprecated Object#id in favour of Object#object_id . Now it''s possible to obtain the ActiveRecord "id" and Object "id" for an ActiveRecord object: @foo = Foo.find :first @foo.id # => 3 @foo.object_id # => 20613620 I hope that clears up your question. Cheers, Nick
"s.ross" <cwdinfo at gmail.com> writes:> In Rails, the primary key, by default ''id'', is used all over the > place. However, Ruby now deprecates the use of constructs like: > > @post = Post.find(:first) > @post_id = @post.id > > I buy the rationale, as the Object#id is something of a reserved > method. However, changing all references to use [:id], while seemingly > the correct approach, also has the unwanted side-effect of breaking > every mock created using mock_model that references the id that way. > > Sure, I can go in and stub [] to return self[:id] for each mock > object, but that ActiveRecord objects behave more as a hash than as an > object (IMO), so there are things like: > > @post[:body_text] > > peppered throughout the codebase, and a big hammer like a stub of the > []() method would also break specs. So the conundrum is how to make > mock_model respond only to the []() method with an argument of :id to > return self[:id]. > > Questions: > > 1. Is there something bogus in my assumption that using @post[:id] is > preferred to @post.id? > 2. Has anyone solved this problem and if so what worked? > > BTW: I am aware that :to_param returns the id, but it seems counter- > intuitive to read code that takes advantage of this quirk. > > Thanks, > > Steve > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersI came across this today when I used stub_model. I hadn''t given it an explicit ID so I got that warning. So if that''s why you''re encountering, just do something like @post = stub_model(:id => 123) As others have said though, only Object#id is deprecated. AR::Base#id is still valid. Pat
On Nov 25, 2008, at 12:34 PM, Peter Jaros wrote:> On Tue, Nov 25, 2008 at 2:04 PM, s.ross <cwdinfo at gmail.com> wrote: >> In Rails, the primary key, by default ''id'', is used all over the >> place. However, Ruby now deprecates the use of constructs like: >> >> @post = Post.find(:first) >> @post_id = @post.id > > I think you''ve got the wrong end of the stick there. Object#id (which > returns a unique id for the Ruby object) was deprecated in favor of > Object#object_id, mostly because ActiveRecord overrides it to return > the primary key. #id seemed in retrospect too common to be reserved > for an implementation detail. You *should* use model.id to get the > primary key. > > If you''re getting that warning, you''re calling #id on something that > doesn''t decend from ActiveRecord::Base. #id is one of the few things > that nil responds to (and issues the deprecation warning); maybe there > are no Posts in your DB? Try checking the value of @post. > > PeterThanks Peter, Nick, Pat and Mark. I think I have a better handle on this now. I''m up-migrating what is appearing to me to be an inconsistent codebase to Rails 2.2 and the issue of indexing versus member access came up. It appears I was incorrect in my assessment that using a hash index would be the safer way to go. Thankfully we have a reasonable number of specs and they will help us find and fix a many of these issues. Steve