Help us understand the problem. What is going on with this article?

Railsでdeviseひとつで複数モデルを管理しよう

More than 5 years have passed since last update.

ウェブサービスなどでよく新規登録画面がhttp://hoge.com/users/sign_up/companies/sign_upなど、ユーザーの属性ごとに管理されているのを目にします。こいつはきっとモデルもきれいに分かれているんだろうなと思いを馳せつつ考えると、例えばセキュリティ的にuserとadminの管理はテーブルごとまるまる別個にしたいという場合だったり、もしコイツができたらいろいろと応用が効きそうなわけです。

すごーく気になったので調べてつくってみました。

導入環境
Ruby:   2.1.3
Rails:  4.2.1
devise: 3.5.1

※deviseの基本的な導入方法などはすっ飛ばします。

1. configに手を加える

$ rails g devise:install

無事deviseがインストールできたらconfig/initializers/配下にdevise.rbが誕生すると思います。その中にこんな記述があるはず。

/config/initializers/devise.rb
# ==> Scopes configuration
# Turn scoped views on. Before rendering "sessions/new", it will first check for
# "users/sessions/new". It's turned off by default because it's slower if you
# are using only default views.
# config.scoped_views = false

この最終行を、こう。

/config/initializers/devise.rb
config.scoped_views = true

コメントアウトはもちろん外します。

2. deviseと関連したmodelを生成する

例えばUserモデルとAdminモデルなど、deviseと関連づけたいモデルを全て生成します。モデル名はまだ存在しないものを選んでください。

$ rails g devise user
$ rails g devise admin

3. 各modelに対応するcontrollerを生成する

先ほど生成した各modelに対して個別のコントローラーを作成してやります。コントローラーなので名前は複数形にしてあげてください。

$ rails g devise:controllers users
$ rails g devise:controllers admins

4. 各modelに対応するviewを生成する

今度はモデル個別のviewを生成してやりましょう。コントローラー名と一致しないとうまく連携が取れないので注意してください。

$ rails g devise:views users
$ rails g devise:views admins

5. routingを設定する

いよいよルーティングをいじります。
今ルーティングはこうなっているはずです。

/config/routes.rb
devise_for :users
devise_for :admins
                   Prefix Verb   URI Pattern                       Controller#Action
                                #[--- 中略 ---]#
cancel_admin_registration GET    /admins/cancel(.:format)          devise/registrations#cancel
       admin_registration POST   /admins(.:format)                 devise/registrations#create
   new_admin_registration GET    /admins/sign_up(.:format)         devise/registrations#new
  edit_admin_registration GET    /admins/edit(.:format)            devise/registrations#edit
                          PATCH  /admins(.:format)                 devise/registrations#update
                          PUT    /admins(.:format)                 devise/registrations#update
                          DELETE /admins(.:format)                 devise/registrations#destroy
                                #[--- 中略 ---]#
 cancel_user_registration GET    /users/cancel(.:format)           devise/registrations#cancel
        user_registration POST   /users(.:format)                  devise/registrations#create
    new_user_registration GET    /users/sign_up(.:format)          devise/registrations#new
   edit_user_registration GET    /users/edit(.:format)             devise/registrations#edit
                          PATCH  /users(.:format)                  devise/registrations#update
                          PUT    /users(.:format)                  devise/registrations#update
                          DELETE /users(.:format)                  devise/registrations#destroy
                                #[--- 中略 ---]#

恐るべき共通具合。これだと宜しくありませんので、ちょいっと変えてやります。

/config/routes.rb
devise_for :admins, controllers: {
  sessions:      'admins/sessions',
  passwords:     'admins/passwords',
  registrations: 'admins/registrations'
}
devise_for :users, controllers: {
  sessions:      'users/sessions',
  passwords:     'users/passwords',
  registrations: 'users/registrations'
}
                   Prefix Verb   URI Pattern                       Controller#Action
                                #[--- 中略 ---]#
cancel_admin_registration GET    /admins/cancel(.:format)          admins/registrations#cancel
       admin_registration POST   /admins(.:format)                 admins/registrations#create
   new_admin_registration GET    /admins/sign_up(.:format)         admins/registrations#new
  edit_admin_registration GET    /admins/edit(.:format)            admins/registrations#edit
                          PATCH  /admins(.:format)                 admins/registrations#update
                          PUT    /admins(.:format)                 admins/registrations#update
                          DELETE /admins(.:format)                 admins/registrations#destroy
                                #[--- 中略 ---]#
 cancel_user_registration GET    /users/cancel(.:format)           users/registrations#cancel
        user_registration POST   /users(.:format)                  users/registrations#create
    new_user_registration GET    /users/sign_up(.:format)          users/registrations#new
   edit_user_registration GET    /users/edit(.:format)             users/registrations#edit
                          PATCH  /users(.:format)                  users/registrations#update
                          PUT    /users(.:format)                  users/registrations#update
                          DELETE /users(.:format)                  users/registrations#destroy
                                #[--- 中略 ---]#

これモデルもコントローラーもビューも別個のユーザー管理ができるようになりました。

6. 後処理をする

もう使わないビューファイルが生成されてしまっているので消します。

$ rails d devise:views

#      invoke  #Devise::Generators::SharedViewsGenerator
#      remove    app/views/devise/shared/_links.html.erb
#      invoke  form_for
#      remove    app/views/devise/confirmations/new.html.erb
#      remove    app/views/devise/passwords/edit.html.erb
#      remove    app/views/devise/passwords/new.html.erb
#      remove    app/views/devise/registrations/edit.html.erb
#      remove    app/views/devise/registrations/new.html.erb
#      remove    app/views/devise/sessions/new.html.erb
#      remove    app/views/devise/unlocks/new.html.erb
#      invoke  erb
#      remove    app/views/devise/mailer/confirmation_instructions.html.erb
#      remove    app/views/devise/mailer/reset_password_instructions.html.erb
#      remove    app/views/devise/mailer/unlock_instructions.html.erb

あとはご自由にモデル・コントローラー・ビューをいじりまくって素敵deviseライフを満喫してください。パス名ももちろん別個のものなので管理もラクラクです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away