Включите роль запросов активных записей в журналы

#ruby-on-rails #logging #activerecord #multi-database

Вопрос:

Rails теперь включает поддержку нескольких ролей базы данных (по умолчанию writing для основной и reading для реплики).:

 ActiveRecord::Base.connected_to(role: :reading) do
  # all code in this block will be connected to the reading role
end
 

В процессе разработки активные запросы записей регистрируются по умолчанию, например:

 > User.last
  User Load (0.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1]]
 

Как я могу включить роль, используемую для запроса, в ведение журнала? Например:

 > ActiveRecord::Base.connnected_to(role: :reading) { User.last }
  [role: reading] User Load (0.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1]]
 

Ответ №1:

поскольку все запросы будут регистрироваться в журнале методов класса AbstractAdapter на последнем шаге, независимо от того, какой адаптер базы данных вы используете: postgresql, mysql,.. Таким образом, вы могли бы переопределить этот метод и добавить role

 # lib/extent_dblog.rb
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
  alias_method(:origin_log, :log)
  def log(sql, name = 'SQL', binds = [], 
          type_casted_binds = [], statement_name = nil, amp;block)
    # prepend the current role before the log
    name = "[role: #{ActiveRecord::Base.current_role}] #{name}"
    origin_log(sql, name, binds, type_casted_binds, statement_name, amp;block)
  end
end

# config/initializers/ext_log.rb
require File.join(Rails.root, "lib", "extent_dblog.rb")
 

ДЕМОНСТРАЦИЯ

 # config/application.rb
  ...
  config.active_record.reading_role = :dev
  config.active_record.reading_role = :test

# app/models/application_record.rb
 class ApplicationRecord < ActiveRecord::Base
   self.abstract_class = true
   connects_to database: { dev: :development, test: :test }
 end

ActiveRecord::Base.connected_to(role: :dev) do
  Target.all
end
# [role: dev]  (0.6ms)  SELECT "targets".* FROM "targets" 
 

Комментарии:

1. Спасибо за ваше решение. Это уже помогло мне заметить проблему с моим кодом и исправить ее. Однако, к сожалению, это нарушает ведение журнала метода, выполнившего запрос. Это систематическое ведение ↳ config/initializers/extend_dblog.rb:19:in log журнала (вот где я поместил этот код в свой случай). Отлично подходит для отладки, но не для постоянного использования в коде, если только это не поможет.