2017-02-28 2 views
0

settings 속성의 JSON 필드 search_terms이 업데이트 된 후에 만 ​​레일에서 메소드를 실행하려고합니다.레일스 - 특정 속성의 JSON 필드가 업데이트 된 후에 만 ​​메소드가 실행됩니다.

모델의 이름은 Campaign이며,이 인스턴스의 속성의 예는 다음과 같습니다 캠페인 모델 자체에서

Campaign.first.attributes 

=> { 
       "id" => 1, 
      "name" => "example.com", 
      "status" => "on", 
     "languages" => [], 
      "country" => nil, 
     "settings" => { 
        "search_terms" => { 
      "happy" => true, 
      "sad" => true, 
       "excited" => true 
     }, 
     "keyword_refresh_intervals" => { 
      "en-us" => 60, 
      "ru-ru" => "0", 
      "en-gb" => "0" 
     } 
    }, 
    "advertiser_id" => 1, 
     "created_at" => Sun, 25 Dec 2016 10:55:47 UTC +00:00, 
     "updated_at" => Tue, 28 Feb 2017 08:07:05 UTC +00:00 
} 

내가 만든 커밋 후 필요한 작업을 실행 해요 :

class Campaign < ApplicationRecord 
    after_commit -> { PlacementsGeneratorJob.perform_later } 

하지만 settings 속성에서 값이 변경된 후에 만 ​​ 속성을 변경하고 settings 속성을 변경하지 않은 경우에만 실행되기를 원합니다.

그게 가능합니까?

편집 :

그래서 예를 들어 나는 settings 속성 변경 사항을 확인할 수 있습니다

Campaign.first.settings_changed? 
=> true 

그러나 나는 같은 것을 수행 할 수 없습니다

Campaign.first.settings["search_terms"]_changed? 
SyntaxError: unexpected tFID, expecting end-of-input 

답변

0
당신은 만들 수 있습니다

을 작업의 가드 메소드가 속성의 일부가 변경되었는지 확인합니다. 이렇게하려면 활성 레코드를 작업 (현재로서는 GlobalID를 사용하는 활성 작업)과 새 검색 조건으로 보낼 수 있습니다.

작업을 수행하기 전에 수행하거나 필요한 모든 로직을 수행하기 위해 수행 할 수 있습니다. Documentation

예는 물론

class Campaign < ApplicationRecord 
     after_commit -> { PlacementsGeneratorJob.perform_later self, new_search_terms } 
    ..... 


class PlacementsGeneratorJob < ActiveJob::Base 
    around_perform do |job, block| 
    check_changes job.arguments[0], job.arguments[1] 
    block.call 

    end 

    def perform record, new_search_terms=nil 
    return if @no_chnages 
    ..... 
    end 

    private 
    def check_changes record, new_search_terms 
    @no_changes = true unless new_search_terms 
    old_record = record.settings['search_terms'] 
    @no_changes = old_record==new_search_terms 

    end 
.... 
end 

이 원칙의 단지 기본 예입니다. 여기에 자신의 논리를 작성해야합니다. 희망이 도움이됩니다.

+0

나를 위해 작동하지 않습니다. 몇 시간 만에 알아 내려고 노력했습니다. – Tom

0

이 작업을 수행하는 '레일 방식'이 있는지 확실하지 않습니다. 빠르고 간단하게 해결하려면 before_save 콜백을 추가하여 settings['search_terms']의 MD5 값을 계산하는 것이 좋습니다 (Campaign의 속성으로 저장할 수 있음). search_terms_md5. 그런 다음, 마지막 저장 이후에 search_terms이 변경되었는지 확인하려면 현재 MD5 값과 저장된 값을 비교하면됩니다.

require 'digest/md5' 

class Campaign < ActiveRecord::Base 
    before_save :compute_md5_of_search_terms 
    after_commit -> { PlacementsGeneratorJob.perform_later }, if: 'search_terms_changed?' 
    ... 
    def compute_md5_of_search_terms 
    search_terms_md5 = Digest::MD5.hexdigest(settings['search_terms']) 
    end 

    def search_terms_changed? 
    Digest::MD5.hexdigest(settings['search_terms']) != search_terms_md5 
    end 
end 
+0

이것은 과도한 공격입니다. 열을 추가하면 설정에서 search_terms를 자신의 것으로 이동하지만 원하지 않습니다. – Tom