Forum: RSpec Q: object.id is deprecated. How to mock?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Steve R. (Guest)
on 2008-11-25 21:05
(Received via mailing list)
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
Mark W. (Guest)
on 2008-11-25 22:32
(Received via mailing list)
On Tue, Nov 25, 2008 at 11:04 AM, s.ross <removed_email_address@domain.invalid> 
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
Peter J. (Guest)
on 2008-11-25 22:34
(Received via mailing list)
On Tue, Nov 25, 2008 at 2:04 PM, s.ross <removed_email_address@domain.invalid> 
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.

Peter
Nick H. (Guest)
on 2008-11-25 22:38
(Received via mailing list)
On 2008-11-25, at 14:04, s.ross wrote:
> Steve
Hi 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
Pat M. (Guest)
on 2008-11-26 00:32
(Received via mailing list)
"s.ross" <removed_email_address@domain.invalid> writes:

>
>
>
> Steve
> _______________________________________________
> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users

I 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
Steve R. (Guest)
on 2008-11-26 00:34
(Received via mailing list)
On Nov 25, 2008, at 12:34 PM, Peter J. wrote:

> 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

Thanks 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
This topic is locked and can not be replied to.