2017-08-30 4 views
0

です。これは最善の問題ではないかもしれません。しかし、私は説明しようとします。 モデルを外部サービスと同期させる必要があります。モデルのafter_updateまたはafter_createにHTTPを送信する最も良い方法は、

したがって、モデルを更新または作成できるエントリポイントが多数あります。 したがって、after_updateイベントとafter_createイベントを聞く必要があります。

私はモデル内でHTTPを呼びたくはありません。モデルからHTTPを呼び出す方法を探しています。 (PSはbase.class_evalでモジュールを使用できることを知っていますが、それもまた最終モデルの一部です)

私はhttps://github.com/krisleech/wisper Publisher/Subscriberアプローチを実装したライブラリを見つけました。 それを行うのが最善の方法ですか?

+0

トランザクションアプローチが必要ですか?アップデートが最初のシステムで有効で、2番目のシステムでクラッシュした場合(またはオフラインの場合)、最初のシステムでアップデートを適用する必要がありますか?また、2番目のシステムですぐに更新する必要がありますか?一度に10kモデルを更新し、10kリクエストを考えてみましょう。 –

+0

あなたのモデルのコールバックで 'ActiveJob.perform_later'を押して、そのジョブがHTTPを世話するようにしましょうか? –

答えて

0

ActiveRecordのコールバックを使用することは非常に汚い方法です。

コードの重複を避け、このロジックをカプセル化するために、モデルの作成/更新をサービスにラップする必要があります。

アクティブジョブを使用してHTTP要求を非同期に実行することもお勧めします。

class MyService 
    def create(args) 
    model = Model.create(args) 
    ActiveJob.perform_later(model) if model.persisted? 
    model 
    end 

    def update(model, args) 
    result = model.update_attributes(args) 
    ActiveJob.perform_later(model) if result 
    result 
    end 
end 
+0

ねえ、ありがとう。 あなたと他の人は絶対に正しいです。 作成するエントリポイントが1つしかない場合には、アプローチは機能しています。 問題は、システムにさまざまな方法でモデルを作成または更新できるエントリポイントが多数あり、コードの重複を避けることができることです。 –

+0

@VolodymyrOこの例では、いくつかの更新ロジックが追加されています。更新が非常に異なる場合は、ブロックをメソッドに渡し、 'yield self'を使用して保存結果を取得することもできます。 –

+0

'model = Model.create(args)'は決して偽ではありません。検証が失敗した場合でも、 'create'は無効なモデルを返します。 – Leito

0

あなたの心は、あなたが所属するコードを確実に保持していることを確認してください。カスタムサービスの代わりにコールバックとして保存することをお勧めしますが、ほとんどのコードをActive Job(非同期で実行できるように)に移動します。私が見ているように、モデルは永続性を担当しているので、モデルが変更されたときに「フラグを立てて」誰かに同期化の仕事をさせてもらうのに最適な場所です。

class Foo < ActiveRecord::Base 
    after_commit :create_external, on: :create 

    private 

    def create_external 
    CreateExternalFooJob.perform_later self 
    end 
end 

class CreateExternalFooJob < ApplicationJob 
    queue_as :default 

    def perform(foo) 
    # Create object in external service with HTTP 
    end 
end 

after_commitはまた、あなたが同期して外部サービスを維持すること:update:destroyでトリガすることができます。

Railsはコールバックを独自のクラスに移動する方法を持っていました。Observersと呼ばれ、4.0以降は独自のgemに移動されました。あまりにも多くのコールバックを使用している場合は、@ Fedeによって提案されているように、このサービスまたはサービスを検討してください。

関連する問題