2017-01-04 1 views
2

나는 a common race condition을 피하기 위해 커밋 후에 실행해야하는 sidekiq 작업이 있습니다.인라인`after_commit` 레일에서 콜백

class User < ActiveRecord::Base 
    ... 
    after_commit do |user| 
    if @enqueue_some_job 
     SomeJob.new(user).enqueue 
     @enqueue_some_job = nil 
    end 
    end 

    def verify 
    @enqueue_some_job = ... 
    ... 
    save! 
    end 
end 

코드가 약간 엉망입니다.

class User < ActiveRecord::Base 
    def verify 
    if ... 
     run_after_commit do |user| 
     SomeJob.new(user).enqueue 
     end 
    end 
    ... 
    save! 
    end 
end 

은 아무것도 이런 구문 (즉 임시 인스턴스 변수를 설정하는 방법에 의존하지 않는)을 지원하기 위해 레일에 존재하는 내장합니까 : 나는 차라리 어떻게 든이 같은 콜백 인라인을 포장 할 수있을 것? 또는 Rails를 확장하여 이와 같은 구문을 추가하는 라이브러리가 있습니까? 콜백을 선언 할 때

답변

0

:

당신은 방법 이름 또는 람다를 사용할 수 있습니다. 스 니펫이 충분히 재사용되어 인스턴스 변수를 추상화하고 재사용 가능한 패턴을 형성하는 것이 더 좋은 옵션 일 수 있습니다. 그것은 반환 (어떤 트랜잭션이 롤백 존재하지 않기 때문에 after_commit를 통해 지원되는 확실하지를 처리하지 않습니다.

응용 프로그램/모델/문제/callbackable.rb

module Callbackable 
    extend ActiveSupport::Concern 

    included do 

    after_commit do |resource| 
     if @_execute_after_commit 
     @_execute_after_commit.each do |callback| 
      callback.call(resource) 
     end 
     @_execute_after_commit = nil 
     end 
    end 
    end 

    def execute_after_commit(&callback) 
    if callback 
     @_execute_after_commit ||= [] 
     @_execute_after_commit << callback 
    end 
    end 

end 

응용 프로그램/모델/

class User < ActiveRecord::Base 
    include Callbackable 

    def verify 
    if ... 
     execute_after_commit do |user| 
     SomeJob.new(user).enqueue 
     end 
    end 
    ... 
    save! 
    end 
end 
0

당신은 블록 대신 메소드 이름을 사용할 수 있습니다

class User < ActiveRecord::Base 
    after_commit :do_something! 

    def do_something! 
    end 
end 

당신이 ifunless 옵션을 사용할 수 있습니다 콜백에 조건을 설정합니다. 이것들은 해시 옵션 일 뿐이며 키워드가 아닙니다. 우려 통해를 사용하여 솔루션을 찾을 수

class User < ActiveRecord::Base 
    after_commit :do_something!, if: -> { self.some_value > 2 } 
    after_commit :do_something!, unless: :something? 

    def do_something! 
    end 

    def something? 
    true || false 
    end 
end 
+0

덕분에 최대 - 그래서 다음에 대한 인스턴스 변수를 설정해야 할 것 - (verify' 같은 경우'에서) 함수 내에서 라이브 검사에 대한 유감스럽게도 조건 그것들 각각. –

+0

나는 당신이 무엇을 얻으려고하는지 정말로 이해하지 못하거나 당신이 정말로 그것을 overthinking 중입니다. if 절 또는'if' 옵션에서'verify' 메서드를 직접 사용할 수 있습니다 - 부울 조건으로 평가되는 메서드뿐만 아니라 인스턴스 변수/상태가 필요한 이유를 실제로 볼 수 없습니다. – max

+0

또한 코드가 실행될 때 다소 혼란스러워 보입니다. 클래스가 평가 될 때 콜백이 선언됩니다. 두 번째 예제의 verify 메소드는 인스턴스 메소드입니다. 인스턴스로부터 싱글 톤 클래스를 변경하기 위해 메타 프로그래밍을 사용할 수 있지만, 이것은 당신이 원하는 것이 아닌 것 같습니다. – max

-1

하면 사용자가 이후에 생성 확인해야한다고 가정 user.rb.

after_commit :run_sidekiq_job, on: :create 
after_commit :run_sidekiq_job, on: [:create, :update] // if you want on update as well. 

이렇게하면 db 커밋 이후에만 작업이 실행됩니다.

그런 다음 수행해야 할 작업을 정의하십시오.

def run_sidekiq_job 
    --------------- 
    --------------- 
end 

는 희망이 도움이 당신 :

관련 문제