如何在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
相关产品推荐
相关产品推荐

