Кэширование ActiveRecord и update_attributes - PullRequest
1 голос
/ 08 марта 2010

Если модель изменяет атрибут локально, а затем изменяет его обратно, 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 или обновить кэш напрямую, если я знаю новое значение? 1004 *

Примечание: код, который изменяет это запрос update_all, блокирует запись, но имеет побочные эффекты, которые портят кэш. Несколько машин читают эту таблицу. Если есть лучший способ сделать это, я хотел бы знать.

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

Ответы [ 2 ]

4 голосов
/ 08 марта 2010

Для этого используйте метод reload.

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

OR

Вы можете попробовать метод 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)
0 голосов
/ 16 мая 2013

Ответ Хариша Шетти правильный, вам нужно вызвать reload для ссылки, однако я нашел лучший способ сделать это автоматически.

В вашей модели, к которой вы хотите перезагрузить атрибут, создайте обратный вызов after_update и вызовите перезагрузку прямо там, например так:

after_update :reload_attr
def reload_attr
    reload select: "attr"
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...