You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rails 7中通过connects_to编程判断当前连接的数据库

Rails 7 读写分离:判断主从库连接及查询打印方案

一、编程判断当前连接的主/从库

Rails 7 的 connects_to 是通过**角色(role)**区分读写库的,主库对应 :writing 角色,从库对应 :reading 角色。不要用 connection.current_database(读写分离场景下无法准确返回当前连接),改用以下方式:

获取当前连接的角色

# 可在模型或 ActiveRecord::Base 中调用
def current_db_role
  connection.pool.db_config.role || :writing
end

# 控制台测试示例
ActiveRecord::Base.current_db_role # 返回 :writing 或 :reading
SecondaryRecord.current_db_role

获取当前连接的数据库名称

直接从连接池的配置中读取,确保准确性:

def current_database_name
  connection.pool.db_config.database
end

二、在 SecondaryRecord 查询时打印当前数据库

提供两种实现方式,按需选择:

方式1:模型回调(拦截查询操作)

利用 around_find 回调拦截类查询方法,每次查询前打印当前数据库:

class SecondaryRecord < ApplicationRecord
  connects_to database: { writing: :primary, reading: :secondary }

  around_find do |block|
    puts "[SecondaryRecord 查询] 当前使用数据库: #{current_database_name}"
    block.call
  end

  private

  def current_database_name
    self.class.connection.pool.db_config.database
  end
end

方式2:订阅 SQL 事件(监控所有查询)

如果需要覆盖关联查询等所有 SQL 操作,订阅 ActiveRecord 的 sql.active_record 事件:

class SecondaryRecord < ApplicationRecord
  connects_to database: { writing: :primary, reading: :secondary }

  class << self
    def inherited(base)
      super
      ActiveSupport::Notifications.subscribe("sql.active_record") do |*args|
        event = ActiveSupport::Notifications::Event.new(*args)
        # 仅过滤当前模型的查询事件
        next unless event.payload[:name]&.start_with?("#{base.name} ")
        puts "[#{base.name} SQL] 当前使用数据库: #{base.connection.pool.db_config.database}"
      end
    end
  end
end

额外测试提示

  • 控制台测试时,需先执行查询(比如 SecondaryRecord.first)触发连接建立,再调用判断方法才会返回有效结果。
  • 可手动切换角色验证逻辑:
    SecondaryRecord.connected_to(role: :reading) do
      puts SecondaryRecord.current_database_name # 输出从库名称
    end
    

内容的提问来源于stack exchange,提问作者Chandan Burman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:00:12