ActiveRecord allows un-synced aliases?

q1 = Question.find(1)
q2 = Question.find(1)

Now, we find q1.id != q2.id.

It appears the two aliases are not kept in sync:

q1.name => ‘old name’
q2.name = ‘new name’
q2.save!
q1.name => ‘old name’
q2.name => ‘new name’
q1.reload
q1.name => ‘new name’

Even worse, is this fun:

q1.destroy
q2.name = ‘third name’
q2.save!

That actually runs; ActiveRecord happily updates all 0 rows that match
(let’s hope IDs can never be re-used, or that could have just updated
the wrong row)

Finally,

q2.reload
ActiveRecord::RecordNotFound: Couldn’t find Question with ID=1

Why does ActiveRecord return two objects both representing a single row
in the database?

This is correct. Rails doesn’t use IdentityMap pattern (in terms of
PoEAA). You should be aware of that when you develop with Rails.

Kent

Kent S. wrote:

This is correct. Rails doesn’t use IdentityMap pattern (in terms of
PoEAA). You should be aware of that when you develop with Rails.

Is .save! working on a record that (no longer) exists at least a bug?
Especially on databases that return the number of effected rows (at
least Pg and MySQL), this should be really easy to detect.

That particular case I’d recommend to handle with database
transactions and an appropriate isolation level set. Also you should
look at the AR::Locking facility at

http://api.rubyonrails.org/classes/ActiveRecord/Locking.html

Kent.