如果模型在本地更改属性,然后将其更改回来,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])
答案 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