如何将以下ActiveRecord :: Observer转换为Service对象(或多个对象)?
PushService
通过WebSocket更新所有连接的浏览器的所有更改。它通过POST到外部进程来完成此操作。自从Thread.new
迁移到Sidekiq后,观察员破了。 Sidekiq作业开始于:after_create可以在事务实际提交之前运行,因此它将引发ActiveRecord :: NotFound错误。
建议使用:after_commit钩子,但PushService
所需的信息(例如record.changes
)将无法使用。
此观察者实现的有趣用例是,当创建新消息时,这是对另一消息的回复。它会自动运行两个回调。答: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
答案 0 :(得分:1)
您可以使用名为wisper的宝石设置订阅者和侦听器。
因此,在您的PushService类中,您将包含Wisper::Publisher
Github页面上有一个确切的示例,可以将其用作服务。这样,事件的发射将被处理实际对象。
因此,每当PushService执行需要更新已连接浏览器的内容时
def some_action
#some code
publish(:done_something, self)
end
然后,Service对象可以使用subscribe
方法监听此事件。