2010-03-08 2 views
1

모델이 로컬에서 속성을 변경 한 다음 다시 변경하면 ActiveRecord가 변경 사항을 DB로 보내지 않습니다. 이것은 성능을 위해 매우 중요하지만, 뭔가 다른 데이터베이스를 변경하고, 내가 원래 값으로 되돌리려면, 변화는 고려하지 않습니다 :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은에 생각하기 때문에 마지막 행이 작동하지 않습니다 DB는 여전히 1입니다. 다른 것이 2로 변경 되었더라도 어떻게됩니까? AR 업데이트를 강제로 수행하거나 새 값을 알고 있으면 캐시를 직접 업데이트 할 수 있습니까?

사이드 노트 : 그것을 변경하는 코드는 레코드를 잠그는 update_all 쿼리이지만 캐시를 엉망으로 만드는 부작용이 있습니다. 여러 대의 컴퓨터가이 테이블을 읽습니다. 이 작업을 수행하는 더 좋은 방법이 있다면 알고 싶습니다.

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

답변

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) 
+0

이 데이터베이스 작업을합니까? 값이 무엇인지 알기 때문에 캐시를 직접 설정하는 것이 좋습니다 – phillee

+0

예. 그렇습니다. 그래서 내가 선택한 필드의 수를 줄였습니다. –

+0

대체 방법을 제안하기 위해 답을 업데이트했습니다. –

0

해리 쉬티 (Harish Shetty)의 대답이 정확합니다. 참조에 reload를 호출해야하지만 자동으로 더 나은 방법을 찾았습니다. 당신이 그렇게처럼 after_update 콜백을 만들고 직접이 다시 호출하는 속성을 다시로드하려는 모델에서

는 :

after_update :reload_attr 
def reload_attr 
    reload select: "attr" 
end 
관련 문제