3

I was trying to figure out if ActiveRecord caches model instances within a transaction (or even within a request) so I ran the following code and was surprised what I saw:

User.transaction do
    u1 = User.find(1)
    u2 = User.find(1)
    puts u1.eql?(u2) # outputs true, this means they are the same instance
    puts u1.email # outputs 'user@gmail.com'

    u1.email = 'foo' # change the email, should change on u1 and u2

    puts u1.email # outputs 'foo'
    puts u2.email # outputs 'user@gmail.com' # how can the values be different if u1 and u2 are the same instance?
end

Isn't .eql? in Ruby supposed to evaluate instance equality? What gives? Does ActiveRecord override this method? How can my two references point to the same instance and have different values?

mockaroodev
  • 2,031
  • 1
  • 20
  • 24

1 Answers1

3

It sounds like you're thinking of .equal? From http://ruby-doc.org/core-2.0.0/Object.html:

Unlike ==, the equal? method should never be overridden by subclasses as it is used to determine object identity (that is, a.equal?(b) if and only if a is the same object as b):

and

The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==.

robyoder
  • 2,366
  • 1
  • 12
  • 13
  • Here's another SO article that answers the question: http://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and – robyoder Nov 16 '13 at 05:03
  • You're totally right. Thanks! I shouldn't be programming this late... So basically it looks like activerecord doesn't cache model instances at all? That's an interesting difference from Hibernate in the java world, which maintains a session cache, and will only read one instance of a given record per session. – mockaroodev Nov 16 '13 at 05:03