ActiveRecord を書いていて、複数の同じ schema を持つが異なるデータを持つ DB の同期(ただコピーというわけではなく、それぞれのデータ内容によって、更新内容をいいかんじに変える)をやりたくなりました。

その中で、複数の module に対して、まったく同じ class を定義したくなりました。具体的には、以下のようなことがやりたいと思っています。

module Database1
  class ApplicationRecord < ActiveRecord::Base
    self.abstract_class = true
    establish_connection :database1
  end

  class User < ApplicationRecord
    include UserConcern
  end

  class Item < ApplicationRecord
    include ItemConcern
  end
end

module Database2
  class ApplicationRecord < ActiveRecord::Base
    self.abstract_class = true
    establish_connection :database2
  end

  class User < ApplicationRecord
    include UserConcern
  end

  class Item < ApplicationRecord
    include ItemConcern
  end
end

この実現のために、module たちを配列につめて、 module_eval の中で class 定義すればいいのではないかと思い、これが実現できないか試すために、以下のテストコードを書きました。

module Database1
  class Class1; end
  puts Class1.name
end

mod = Database1

mod.module_eval do
  class Class2; end
  puts Class2.name
end

実行結果は以下で、 module を開いて class 定義した場合と、 module_eval で定義した場合では、 class の定義が行われる先が異なることに気付きました。

Database1::Class1
Class2

質問

  • 複数のモジュールに対して、まったく同じ class 定義を行いたい場合、どのように記述するのが良いでしょうか? もしくはそもそも、 変数の中の module に対して、 class を定義できますか?