タイトルの通りですが、具体的には以下のコマンドでモデルをgenerateしてあげれば、実現できます。
Admin::User
というモデルで admin_users
というテーブルを作りたい場合、以下のコマンドで作成できます。
bundle exec rails g model Admin::User email password flag
invoke active_record
create db/migrate/20160202020202_create_admin_users.rb
create app/models/admin/user.rb
create app/models/admin.rb
invoke rspec
create spec/models/admin/user_spec.rb
module Admin
def self.table_name_prefix
'admin_' #<= DBのtable名にadmin_というプレフィックスがあることが前提
end
end
class Admin::User < ActiveRecord::Base
end
app/models/admin.rb
で table_name_prefix
というクラスメソッドをオーバーライドしています。
Railsではなぜかネームスペースとなる親のModuleに定義してあげると table_name_prefix
が有効な状態となります。
ネームスペースとなっているModuleにメソッドを定義するだけで、そのメソッドが実行できるわけではないので気になって詳しく調べてみました。
通常Rubyだと self.hoge
などで始まる 特異メソッド は extend
しないとダメです。
以下のActiveRecordのソースにコメントで書かれていました。
# If you are organising your models within modules you can add a prefix to the models within
# a namespace by defining a singleton method in the parent module called table_name_prefix which
# returns your chosen prefix.
意訳すると以下の感じでしょうか。
まとめたい(organisingしたい)ときはネームスペース(parent)となっている
Admin
のモジュールに定義することで可能。
実装コードは以下。parents
で親のモジュールに table_name_prefix
の定義があるかを判定しあれば返すという実装になっていました。
def full_table_name_prefix #:nodoc:
(parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
end