LoginSignup
1
1

[Ruby] ros-apartment と rails 7(と alias の仕様について)

Last updated at Posted at 2023-12-07

はじめに

弊プロダクトではマルチテナントを実現出来る apartment gem を使っています(正確には本家は更新が止まっているので rails-on-services プロジェクトの ros-apartment)。
今回 apartment を 2.11.0、rails を 7.0.8 にアップデートした所遭遇したエラーとその対応について記します。

TL;DR

apartment は master ブランチのリリースが止まっているので development ブランチを使用する(自己責任において)。

Gemfile
gem 'ros-apartment', require: 'apartment', git: 'https://github.com/rails-on-services/apartment.git', branch: 'development'

ros-apartment について

オリジナルの apartment は開発が止まっており、それを受けてフォークして作られたリポジトリです。尚こちらもリリースが滞り気味です。

rails と apartment をバージョンアップしたところ `connected_to': unknown keyword: :database (ArgumentError) エラーに遭遇しました。
調べてみると apartment が rails のメソッドに対して alias でパッチを当てている部分の rails 側の変更によるエラーのようで、すでに PR が出ているのでそれを参考に以下のようにパッチを当てて対処しようとしました。

config/initializes/active_record/connection_handling.rb
module MyApp
  module ActiveRecord
    module ConnectionHandling
      def connected_to_with_tenant(role: nil, prevent_writes: false, &blk)
        current_tenant = Apartment::Tenant.current

        connected_to_without_tenant(role: role, prevent_writes: prevent_writes) do
          Apartment::Tenant.switch!(current_tenant)
          yield(blk)
        end
      end
      
      alias connected_to_without_tenant connected_to
      alias connected_to connected_to_with_tenant
    end
  end
end

しかしどうやっても新しく定義したメソッドが呼ばれず古いメソッドが呼ばれ続けてしまいました。

alias で別名定義されたメソッドは上書きが出来ない

色々調べたところ、どうやら一度 alias によって別名をつけられたメソッドはその後オーバーライドをしても再定義が出来ないという仕様のようで、alias で別名が付けられたメソッドに対しては「別モジュールで同名メソッドを定義して prepend で上書き」という方法は使えないようでした。

参考にさせていただいた記事
https://www.xmisao.com/2014/09/12/ruby-alias-tips.html
https://r7kamura.com/articles/2018-04-02-alias-prepend-f376914c93fb

というわけで ros-apartment の対処については冒頭のとおりですが、それとは別に alias によって別名定義されたメソッドに関してはメソッド名自体を変更したり、呼び出し元をオーバーライドする必要があるという知見でした。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1