2

次の ActiveRecord::Observer を Service オブジェクト (または複数のオブジェクト) に変換するにはどうすればよいでしょうか?

すべてのPushService変更の WebSocket を介して、接続されているすべてのブラウザーを更新します。これは、外部プロセスへの POST によって行われます。Thread.newからSidekiq に移行してから、オブザーバーが壊れました。:after_create で開始された Sidekiq ジョブは、トランザクションが実際にコミットされる前に実行される可能性があるため、ActiveRecord::NotFound エラーが発生します。

:after_commit フックを使用することをお勧めしますが、そうすると必要な情報PushServicerecord.changes利用できなくなります。

このオブザーバーが実現する興味深い使用例は、別のメッセージへの返信である新しいメッセージが作成されたときです。2 つのコールバックが自動的に実行されます。返信メッセージ用の :after_create と、スレッド メッセージ用の :after_touch 。

明示的なサービス オブジェクトを使用して、この動作を実行する方法に興味があります。

class PushObserver < ActiveRecord::Observer
    observe :message

  def after_create(record)
    Rails.logger.info "[Observe] create #{record.inspect}"
    PushService.new(:create, record).publish
  end

  def after_update(record)
    Rails.logger.info "[Observe] update #{record.changed.inspect}"
    PushService.new(:update, record).publish
  end

  def after_touch(record)
    Rails.logger.info "[Observe] touched #{record.changes.inspect}"
    PushService.new(:touch, record).publish
  end

  def after_destroy(record)
    Rails.logger.info "[Observe] destroy #{record.inspect}"
    PushService.new(:destroy, record).publish
  end
end
4

1 に答える 1

1

wisperという gem を使用して、サブスクライバーとリスナーをセットアップできます。

したがって、PushService クラスには、Wisper::Publisherこれをサービスとして使用するための正確な例が Github ページに含まれています。このようにして、イベントの発火は実際のオブジェクトを処理します。

したがって、PushService が接続されたブラウザの更新を必要とする何かを行うときはいつでも

def some_action
  #some code
  publish(:done_something, self)
end

その後、Service オブジェクトはメソッドを使用してこのイベントをリッスンできますsubscribe

于 2013-08-03T23:18:43.547 に答える