How to or Should I Find an Object by the Object_Id Attribute in Ruby

Can I or SHOULD I find an object by the object_id attribute in ruby?

Yes, you can:

irb(main):002:0> s1 = "foo"
#=> "foo"
irb(main):003:0> s2 = ObjectSpace._id2ref(s1.object_id)
#=> "foo"
irb(main):004:0> s2.object_id == s1.object_id
#=> true
irb(main):005:0> s2[0] = "z"
#=> "z"
irb(main):006:0> s1
#=> "zoo"

Should you do this? I'll leave that up to you. There are less geeky ways to store an object with a serializable id (e.g. in an Array and returning the index). One problem you may run into is that if the only 'reference' you keep to an object is the object_id, the object can be collected by GC when you're not looking.

Can we access the objects we created in ruby using their object _ids in ruby?

How an object ID is “assigned” depends on the Ruby implementation and other factors like the OS bitness. For example, in CRuby nil.object_id returns 4 on 32-bit and 8 on 64-bit.

Additionally nil is a so called immediate value. true, false, fixnums (small integers) and sometimes even floats are other immediate values. They have fixed IDs for the following reasons:

  • they're passed by value and not by reference like the other (dynamically allocated) objects
  • there's only one nil, one true, one 19, etc. however there can be two different arrays

See the documentation of BasicObject#object_id. You can also click to toggle the source to get a look at the CRuby implementation.

Call ObjectSpace._id2ref to retrieve an object by ID:

id = nil.object_id
ObjectSpace._id2ref(id) # => nil

In some implementations that method may not be implemented or really slow. According to matz it was originally a hack needed to implement weakref but current versions don't call it anymore.

Ruby Object#id warnings and Active Record

I'm assuming you're doing mocking / stubbing (because you mentioned specs).

In my case, I run into these warnings when I stub an ActiveRecord object and access its ID attribute.

In cases where you expect to access the ID of your ActiveRecord object, I'd recommend you do the following:

 mock("MyActiveRecordObject", :id => 1001)

Ruby object to_s what is the encoding of the object id?

Think of the object_id, or __id__ as the "pointer" for the object. It is not technically a pointer, but does contain a unique value that can be used to retrieve the internal C VALUE.

There are patterns to the value it has for some data types, as you can see with its hexadecimal representation with to_s. I am will not go into all the details, as there are already numerous answers on SO explaining, and already linked from comments, but integers (up to a FIXNUM_MAX, have predictable values, and special constants like true, false, and nil will always have the same object_id in every run.

To put simply, it is nothing more than a number, and shown as a hexadecimal (base 16) value, not any actual "encoding" or cypher.

Going to expand upon this a bit more in light of your latest edits to the question. As you posted, the hexadecimal number you see in to_s is the value of the internal C VALUE of the object. VALUE is a C data type (unsigned, pointer size number) that every Ruby object is represented as in C code. As @Stefan pointed out in a comment, for non-integer types (I speak only for MRI version), it is twice the value of the object_id. Not that you probably care, but you can shift the bits of an integer to predict the value for those.

Therefore, using you example.

A value of 0x00007fac5eb6afc8 is simple hexadecimal notation for a number. It uses a base 16 counting system as opposed to the base 10 decimal system we are more used to in everyday life. It is simply a different way of looking at the same number.

So, using that logic.

a = 0x00007fac5eb6afc8
#=> 140378300133320 # Decimal representation

a /= 2 # Remember, non-integers are half of this value
#=> 70189150066660 # Your object_id

Rails - include? with object or object id

There's really no difference between the two. Both are very inefficient and won't work if your Company table is large. They load all the Company records into memory, and furthermore call c.owners which fires an additional query on each of the records. This is called an N+1 query. You can address the N+1 part by using Company.all.includes(:owners), but you'd still have the issue of loading everything into memory.

It's hard to give you exact code since you haven't shared your model definition (specifically, how the Company#owners association is defined). But I'll assume you have a CompanysOwners join table. In which case I would recommend the following code:

companies = CompanysOwners.where(owner: current_user).includes(:company).map(&:company)

This only fires off a single query, and doesn't load more records into memory than are needed. You could get rid of the includes(:company) part and it would still work, but be slower.

If your Company#owners association is defined differently than this, feel free to leave a comment and I can show you how to modify this for your needs.

By the way, to address your original question more directly ... under the hood, c.owners.include?(current_user) uses == to compare the records. And ActiveRecord::Core#== is comparing the IDs under the hood. You can see the source code here for proof of that: https://api.rubyonrails.org/v6.1.3.1/classes/ActiveRecord/Core.html#method-i-3D-3D. So they really are doing the same thing.

Rails primary key and object id

It sounds like the object you've called .id on is not actually an ActiveRecord model. You should only see that warning for Ruby objects where .id is the soon-to-be deprecated version of Object#object_id.

However, another way to access the primary key for the field with an ActiveRecord model is model.attributes['id'] so you could try that.

Mongodb change ObjectID or _id attribute for a document?

MongoDB won't let you update the _id field of a document, but you can delete the document and reinsert it with a new _id value.

How can I get the parent object id inside the child model? Nested form

Solved it using a before_save callback and self.campaign.id to get the parent id inside a method to manipulate the info my user typed.



Related Topics



Leave a reply



Submit