Query では読み込み専用 、Mutation では読み書きを使うようにしたかった。
上記のコメントで動くのだが、テストでトランザクションを使ったロールバック戦略を採用していると、レプリカに変更が伝搬されずに失敗する点に注意。(関連:Rails 6.0の複数DBでリードレプリカのテストするのたぶん大変)
module Tracers class DatabaseRoleTracer EVENT_NAME = 'execute_multiplex'.freeze def trace(event, data) # テストではテストケースごとにトランザクションをロールバックするためコミットされずレプリカに伝搬しない # ので、やむなくテストモードでは無効=プライマリに繋ぐ if event == EVENT_NAME && !Rails.env.test? multiplex = data[:multiplex] role = multiplex.queries.all?(&:query?) ? ActiveRecord::Base.reading_role : ActiveRecord::Base.writing_role Rails.logger.debug("[#{self.class.name}] ActiveRecord::Base.connected_to(role: #{role.inspect})") ActiveRecord::Base.connected_to(role: role) do yield end else yield end end end end class MyAppSchema < GraphQL::Schema mutation(Types::MutationType) query(Types::QueryType) # 省略 # Query か Mutation かで接続先データベースを変更する tracer Tracers::DatabaseRoleTracer.new end