Closed henriquekraemer closed 4 years ago
Hi @HenriqueKraemer! Thanks for reporting this error.
I’m curious if there’s a reason you want to re-instrument the existing sql.active_record
event that Rails already instruments? Do you subscribe to this event somewhere else in your codebase and therefore would like specific event information?
If you’re trying to create your own custom event, you could use a different name (reference here - "11 Creating custom events")
The reason you are seeing this error is because Rails already instruments sql.active_record
and provides a payload object that it expected by our Subscriber. You can see the keys of the payload object here in the Rails codebase (for 4.2.11.1) and we expect that payload to be passed to our Subscriber.
Let us know what exactly you are trying to accomplish so we can help further. Thanks!
@estolfo, sorry for the delay. Here is an example of usage:
class MaintOrder < ActiveRecord::Base
include MaintOrder::CalculationPreloads
...
end
module MaintOrder::CalculationPreloads
extend ActiveSupport::Concern
included do
include CalculationPreload::Base
attr_writer :total_resources_usage
calculation_preload :total_resources_usage do |records|
record_ids = records.collect(&:id)
result = MaintOrderResourcesUsage.where(maint_order_id: record_ids).group(:maint_order_id).sum(:total_cost)
records.each do |record|
record.total_resources_usage = result[record.id].try(:round, 2) || 0.0
end
end
end
module Api
module V1
class MaintOrdersController < ApplicationController
def index
...
render json: do_preloads(apply_pagination(@maint_orders)), meta: meta_hash, root: 'data'
end
def do_preloads query
...
# CalculationPreload
preload_calculations = %i[total_resources_usage]
query = query.calculation_preload(*preload_calculations)
query = query.preload(*preload_associations)
query
end
end
end
end
This is an old module that was created for calculate data once, not after every query execution. Before this module, a lot of calculations were made in the models with attr_accessors.
So, in my front end I can say that I want this data with total_resources_usage
then this data is calculated.
Hi @HenriqueKraemer
Thanks for this extra information. From what I can tell (please correct me if I'm wrong), the actual query that happens within the execute_calculation_preloads!
method is a sql query. That query would be instrumented anyway by the APM agent or any other library subscribed to 'sql.active_record'
. The only reason to use ActiveSupport::Notifications.instrument
would be to create your own custom events that you subscribe to somewhere else in your codebase.
Perhaps I'm missing it, but can you tell me why you're re-instrumenting events with ActiveSupport::Notifications.instrument('sql.active_record'...
?
This will just redefine the API that ActiveRecord uses for that sql event, potentially causing this same error in other libraries that subscribe to 'sql.active_record'
.
Hi, I managed to make it work sending the other payload fields.
Ill talk to the team on how to improve this approach for calculate stuff. This is an old part of the code and its a mess...
Thanks for the support!
Describe the bug
Conflicting with others ActiveSupport::Notifications.instrument.
I have an module called CalculationPreload that I use for caclulate some data from a group of records, instead of doing one by one.
Every time that I call
execute_calculation_preloads
, this error occurs:Exception message: no implicit conversion of nil into String
Error line:
ActiveSupport::Notifications.instrument('sql.active_record', name: "#{self.name} Calculation Preloads") do
Backtrace:
Environment
Additional context
I have tested with older versions of ElasticAPM gem (3.3, 3.4 and 3.5), and the error was different:
Exception message: undefined method `encode' for nil:NilClass
Error line:
ActiveSupport::Notifications.instrument('sql.active_record', name: "#{self.name} Calculation Preloads") do
Backtrace: