ActiveRecord缓存和update_attributes

时间:2010-03-08 19:45:20

标签: mysql ruby-on-rails activerecord concurrency

如果模型在本地更改属性,然后将其更改回来,ActiveRecord不会将更改发送到数据库。这对性能很有帮助,但是如果其他东西改变了数据库,并且我想将其恢复为原始值,那么更改不会:

model = Model.find(1)
model.update_attribute(:a, 1) # start it off at 1

# some code here that changes model.a to 2
model.a = 2 # I know it changed, reflecting my local model of the change

model.update_attribute(:a, 1) # try change it back, DOESN'T WORK

最后一行不起作用,因为AR在数据库中认为它仍然是1,即使其他东西将其更改为2.如果我知道新值,我如何强制进行AR更新或直接更新缓存? / p>

旁注:更改它的代码是一个update_all查询,用于锁定记录,但它有副作用会弄乱缓存。多台机器读取此表。如果有更好的方法,我很想知道。

Model.update_all(["locked_by = ?", lock_name], ["id = ? AND locked_by IS NULL", id])

2 个答案:

答案 0 :(得分:4)

使用reload方法。

model.reload(:select => "a")

您可以尝试使用will_change!方法(不清楚您的更改是如何发生的。但您可以尝试使用此方法)。

model.update_attribute(:a, 1) # start it off at 1
model.a_will_change! #fore warn the model about the change
model.a = 2  #perform the change
model.update_attribute(:a, 1)

答案 1 :(得分:0)

Harish Shetty的答案是正确的,你需要在引用上调用reload,但是我找到了一种更好的方法来自动完成。

在你的模型中,你想重新加载属性,创建一个after_update回调并直接在那里调用reload,如下所示:

after_update :reload_attr
def reload_attr
    reload select: "attr"
end