2017-02-28 9 views
0

settings属性のJSONフィールドsearch_termsが更新された後にのみ、メソッドをRailsで実行しようとしています。Rails - 特定の属性の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属性が変更された場合にのみ実行されます。

これは可能ですか?

EDIT:

だから、例えば私が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

これを行うための 'Railsの方法'があるかどうかはわかりません。すばやく簡単な解決策として、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

関連する問題