首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展ActiveSupport::Notifications.subscribe、instantiation.active_record挂钩

扩展ActiveSupport::Notifications.subscribe、instantiation.active_record挂钩
EN

Stack Overflow用户
提问于 2018-12-04 06:30:55
回答 2查看 464关注 0票数 6

我正在探索ActiveSupport::Notifications,我想了解更多关于'instantiation.active_record'的信息,而不仅仅是:record_count:class_name [1]。例如,

代码语言:javascript
复制
ActiveSupport::Notifications.subscribe /instantiation.active_record/ do |*args|

  args.status #Database or ActiveRecord return status
  args.result #The actual result set returned
  args.etc .. #Any other info I can collect on the event

  # Additional code ...
end

这可以做到吗?如果可以,如何做到?

更新:感谢下面的Tom和Pavel。挑战的一部分,是我正在构建一个第三方gem,它将分析主机应用程序的所有SQL返回,而不需要修改他们的代码。基本上,将它插入到Gemfile中,进行捆绑,然后就可以了。

我正在考虑extending ActiveRecord::Baseusing the method append_info_to_payload,但到目前为止还没有在gem中工作过。

例如,我想重写ActiveRecord::Querying find_by_sql()方法的有效负载,如下所示:

代码语言:javascript
复制
payload = {
  record_count: result_set.length,
  class_name: name,
  result_set: result_set
}

在测试和手动编辑我本地的ActiveRecord gem时,这将通过ActiveSupport::Notifications发布/订阅提供完整的result_set。

答:所以,答案是使用class_eval方法,并覆盖ActiveRecord::Querying中的find_by_sql方法:

代码语言:javascript
复制
ActiveRecord::Querying.class_eval do
  def find_by_sql(sql, binds = [], preparable: nil, &block)
    result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
    column_types = result_set.column_types.dup
    columns_hash.each_key { |k| column_types.delete k }
    message_bus = ActiveSupport::Notifications.instrumenter

    payload = {
        record_count: result_set.length,
        class_name: name,
        result_set: result_set
    }

    message_bus.instrument("instantiation.active_record", payload) do
      result_set.map { |record| instantiate(record, column_types, &block) }
    end
  end
end

我将其添加到我的gem的initializer.rb文件中。

最后:我在ActiveRecord上创建了两个拉请求,让result_set在有效负载中向前传递,以便在ActiveSupport::Notifications:querying.rbjoin_dependency.rb中使用。

EN

回答 2

Stack Overflow用户

发布于 2018-12-12 17:31:35

可以做到这一点吗?如果可以,如何做到?

我不这样认为。

看看thisthis -在这两种情况下,payload都是一个只有record_countclass_name选项的哈希表。除了指南中描述的以外,没有额外的选项。

票数 1
EN

Stack Overflow用户

发布于 2018-12-13 06:01:49

您可以使用::instrument创建custom hook。然后,您可以定义具有statusresult_set等的有效负载,并在块中定义它们的行为。

您可以在::instrument::subscribe here上找到更多可靠的文档。

编辑:我更深入地了解了这一点,偶然发现了this stack overflow question。看起来append_info_to_payload方法就是您要找的。它已经被移到了private method is Rails 5。

最后一次编辑:如果你觉得勇敢,那么如果你想直接插入额外的有效载荷,那么可以使用herehere来通知。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53602951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档