development

모델에서 속성 변경을 감지하는 방법은 무엇입니까?

big-blog 2020. 9. 23. 07:51
반응형

모델에서 속성 변경을 감지하는 방법은 무엇입니까?


모델이 저장된 후 실행되는 레일에 콜백 함수를 만들고 싶습니다.

이 모델이 있습니다. 클레임 상태에 따라 변경되는 '상태'속성이있는 클레임, 가능한 값은 보류 중, 승인 됨, 승인 됨, 거부 됨

데이터베이스에는 기본값이 '보류 중'인 '상태'가 있습니다.

모델이 처음으로 생성되거나 변경된 상태에 따라 한 상태에서 다른 상태로 업데이트 된 후 특정 작업을 수행하고 싶습니다.

내 생각은 모델에 기능을 갖는 것입니다.

    after_save :check_state

    def check_state
      # if status changed from nil to pending (created)
      do this

      # if status changed from pending to approved
      performthistask
     end

내 질문은 모델 내에서 변경하기 전에 이전 값을 어떻게 확인합니까?


ActiveModel :: Dirty 모듈을 살펴보아야 합니다. 클레임 모델에서 다음 작업을 수행 할 수 있어야합니다.

claim.status_changed?  # returns true if 'status' attribute has changed
claim.status_was       # returns the previous value of 'status' attribute
claim.status_change    # => ['old value', 'new value'] returns the old and 
                       # new value for 'status' attribute

claim.name = 'Bob'
claim.changed # => ["name"]
claim.changes # => {"name" => ["Bill", "Bob"]}

오! Rails의 즐거움!


당신은 이것을 사용할 수 있습니다

self.changed

이 레코드에서 변경된 모든 열의 배열을 반환합니다.

당신은 또한 사용할 수 있습니다

self.changes

변경된 열의 해시와 전후 결과를 배열로 반환합니다.


사용 가능한 상태 머신 플러그인 중 하나를 살펴 보는 것이 좋습니다.

둘 중 하나를 통해 상태 및 상태 간 전환을 설정할 수 있습니다. 요구 사항을 처리하는 매우 유용하고 쉬운 방법입니다.


Rails 5.1+의 경우 활성 레코드 속성 방법을 사용해야합니다.

saved_change_to_attribute? (attr_name, ** 옵션)`

마지막으로 저장했을 때이 속성이 변경 되었습니까? 이 메서드는 saved_change_to_name?대신 으로 호출 할 수 있습니다 saved_change_to_attribute?("name"). 와 유사하게 작동합니다 attribute_changed?. 이 메서드는 저장 호출이 특정 속성을 변경했는지 확인하기 위해 콜백 이후에 유용합니다.

옵션

from 전달되면이 메서드는 원래 값이 주어진 옵션과 같지 않으면 false를 반환합니다.

to 전달되면이 메서드는 값이 주어진 값으로 변경되지 않는 한 false를 반환합니다.

따라서 속성 값의 변경을 기반으로 일부 메소드를 호출하려면 모델이 다음과 같이 보일 것입니다.

class Claim < ApplicationRecord

  after_save: :do_this, if: Proc.new { saved_change_to_status?(from: nil, to: 'pending') }

  after_save: :do_that, if: Proc.new { saved_change_to_status?(from: 'pending', to: 'approved') }


  def do_this
    ..
    ..
  end

  def do_that
    ..
    ..
  end

end

콜백에서 값 변경을 확인하지 않으려면 다음을 수행 할 수 있습니다.

class Claim < ApplicationRecord

  after_save: :do_this, if: saved_change_to_status?


  def do_this
    ..
    ..
  end

end

나는 여러 곳에서 질문이 떠오르는 것을 보았으므로 코드를 조금 더 멋지게 만들기 위해 작은 루비 젬을 작성했습니다 (그리고 모든 곳에서 백만 개의 if / else 문을 피합니다) : https://github.com/ronna-s / on_change . 도움이 되었기를 바랍니다.


state_machine gem 과 같이 잘 테스트 된 솔루션을 사용하는 것이 훨씬 낫습니다 .

참고URL : https://stackoverflow.com/questions/1586536/how-to-detect-attribute-changes-from-model

반응형