ActiveRecord allows un-synced aliases?


#1

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?


#2

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


#3

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.


#4

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.