간단한 예제를 사용하여 설정 : 두 번째 테이블 ( ) 에 각 레코드 Totals
의 amount
열 합계를 보유하는 테이블 ( ) 이 1 개 Things
있습니다.
thing.amount
가 업데이트 되면 이전 값과 새 값의 차이를에 추가하고 싶습니다 total.sum
.
지금은 뺀거야 self.amount
동안 before_update
및 추가 self.amount
시 after_update
. 이로 인해 업데이트 성공에 대해 너무 많은 신뢰가 있습니다.
제약 : 모든 거래의 합계를 단순히 재 계산하고 싶지 않습니다.
질문 : 간단히 말해서 after_update
콜백 중에 원래 값에 액세스하고 싶습니다 . 이 작업을 수행하는 방법은 무엇입니까?
업데이트 : 나는 Luke Francl의 아이디어로 갈 것입니다. after_update
콜백 중에 self.attr_was
내가 원하는 값에 여전히 액세스 할 수 있습니다 . 나는 또한 after_update
이런 종류의 논리를 모델에 유지하고 싶기 때문에 구현을하기 로 결정했습니다 . 이렇게하면 나중에 트랜잭션을 어떻게 업데이트할지 결정하더라도 트랜잭션 합계를 올바르게 업데이트하고 있음을 알 수 있습니다. 구현 제안을 해주신 모든 분들께 감사드립니다.
답변
모든 사람들이 거래에 대해 말하는 것과 동일합니다.
그건 …
Rails 2.1부터 ActiveRecord는 객체의 속성 값을 추적합니다. 따라서 속성 total
이 있으면 이전 값을 반환 하는 total_changed?
메서드와 total_was
메서드가 있습니다.
더 이상이를 추적하기 위해 모델에 아무것도 추가 할 필요가 없습니다.
업데이트 : 요청 된 ActiveModel :: Dirty에 대한 문서는 다음과 같습니다 .
답변
다른 사람들은이 모든 것을 트랜잭션으로 감싸는 것에 대해 언급하고 있습니다.하지만 저는 그것이 당신을 위해 끝났다고 생각합니다. after_ * 콜백에서 오류에 대한 예외를 발생시켜 롤백을 트리거하기 만하면됩니다.
참조 http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html를
save, save! 또는 destroy 호출의 전체 콜백 체인은 트랜잭션 내에서 실행됩니다. 여기에는 after_ * 후크가 포함됩니다. 모든 것이 잘되면 체인이 완료되면 COMMIT가 실행됩니다.
before_ * 콜백이 작업을 취소하면 ROLLBACK이 실행됩니다. after_ * 후크를 포함한 모든 콜백에서 예외를 발생시키는 ROLLBACK을 트리거 할 수도 있습니다. 그러나이 경우 클라이언트는 일반 저장이 조용히 거짓을 반환하는 대신 이러한 예외를 발생시키기 때문에이를 인식해야합니다.
답변
답변
이전 값과 새 값을 각각 사용하여 변경된 모든 필드를 가져 오려면 다음을 수행하십시오.
person = Person.create!(:name => 'Bill')
person.name = 'Bob'
person.save
person.changes # => {"name" => ["Bill", "Bob"]}
답변
ActiveRecord :: Dirty 는 속성 변경을 추적하기 위해 ActiveRecord에 내장 된 모듈입니다. 따라서 thing.amount_was
이전 값을 얻는 데 사용할 수 있습니다 .
답변
이것을 모델에 추가하십시오.
def amount=(new_value)
@old_amount = read_attribute(:amount)
write_attribute(:amount,new_value)
end
그런 다음 after_update 코드에서 @old_amount를 사용합니다.
답변
첫째, 데이터가 함께 작성되도록 트랜잭션에서이 작업을 수행해야합니다.
질문에 답하기 위해 before_update의 이전 값으로 멤버 변수를 설정 한 다음 after_update에서 액세스 할 수 있지만 이것은 매우 우아한 솔루션이 아닙니다.