How to convert this ActiveRecord::Observer to a Service object?

How would one convert the following ActiveRecord::Observer to a Service object (or maybe multiple objects)?

The PushService updates all connected browsers via WebSocket of all changes. It does this by POST-ing to an external process. Since migrating from Thread.new to Sidekiq, the observer broke. A Sidekiq job started in an :after_create can run before the transaction is actually committed, so it will raise an ActiveRecord::NotFound error.

It is recommended to use an :after_commit hook, but then information needed by the PushService such as record.changes will not be available.

The interesting use case that this observer fulfills is that when a new message is created, which is a reply to another message. It will automatically run two callbacks. An :after_create for the reply-message and an :after_touch for the thread-message.

I am interested to see how this behavior can be run by using an explicit service object.

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

You can set up subscribers and listeners using a gem called wisper.

So in your PushService class, you would include Wisper::Publisher There is an exact example on the Github page for using this as a service. This way, the firing off of events will be taken care of the actual objects.

So whenever PushService does something that requires updating connected browsers

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

Then the Service object can be listening for this event with the subscribe method.

链接地址: http://www.djcxy.com/p/66232.html

上一篇: 你可以手动管理事务提交/回滚吗?

下一篇: 如何将此ActiveRecord :: Observer转换为Service对象?