【Rails】テーブル名にプレフィックスを付与・ネームスペース付きのモデルを作成

はじめに

ある2つのプロジェクトを1つのプロジェクトとして統合して管理したいため、Railsアプリの各ディレクトリ内を以下のようにプロジェクト毎に取り扱いということがありました。

models
  └ProjectA
    └User.rb
    └Admin.rb
    └...
  └ProjectB
    └User.rb
    └Admin.rb
    └...

そのためテーブル名にプレフィックスをつけて管理、モデルもそれに対応する必要があり、この記事を書いています。

ネームスペース付きのモデルを新規で作成してみる

新規でテーブル名にプレフィックスを付与・ネームスペース付きのモデルを作成する場合は以下のようにネームスペース名::をつけてモデルを作成します。

rails g model Project::User email:string

ネームスペース付きでrails g modeをすると以下のファイルが作成されます。

①マイグレートファイル

class CreateProjectUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :project_users do |t|
      t.string :email

      t.timestamps
    end
  end
end

self.table_name_prefixをオーバーライドしてくれるmodule

module Project
  def self.table_name_prefix
    "project_"
  end
end

③Projectのネームスペース付きUserモデル

class Project::User < ApplicationRecord
end

通常rails g modelする時との違いとして以下があります。

  • ① table名にプレフィックスが付与される(project_users)
  • ② self.table_name_prefixをオーバーライドするmoduleが作成される
    • Project::Userからfindやwhereをした際に、project_xxxxのテーブルを参照するようになる
  • ③ モデル名にProject::のようなネームスペースが付与される

既存のプロジェクトをネームスペースに分けたい時

既存のプロジェクトをネームスペースで分けたいけど、テーブル名は変えたくありませんでした。

その際は前述のapp/models/project.rbにあたるself.table_name_prefixをオーバーライドするファイルを作成せず、③のようにネームスペース(Project::)をつけてあげるだけで問題ありませんでした。

Project::User.findすると発行されるSQLで参照されるテーブル名はusersのままです。

また、controller等でUser.findみたいに呼び出している箇所はProject::User.findのように呼び出すよう修正してみてください。