LoginSignup
3
10

More than 3 years have passed since last update.

RailsのdeviseのController,View,URLのカスタマイズ(初心者向け)

Last updated at Posted at 2020-06-15

どんな記事?

ここではrailsでアプリを作る際に認証機能を簡単に作成するgemである'devise'を使う時の、コントローラーとビュー、URLをカスタマイズする方法とその考え方を解説する。

deviseとは

$ rails g devise モデル名

とするだけでモデルを作成してくれて、内部的にビューやコントローラーも作成される。
そのためこのコマンドをうつだけで、モデル、ビュー、コントローラーの三つを作成することができる。
非常に簡単にログイン認証の仕組みを作ることができる。

逆に言うと
デフォルトで設定される URL
デフォルトで使用されるコントローラー
デフォルト使用されるビュー
が存在するため、 細かい設定をするためには色々と変更しなければならない。 今回はその設定方法と考え方について解説する。

デフォルトではどうなっているか

まず、

$ rails g devise member

とするとmemberモデルが作成され ルーティングは以下のようになる(必要部分だけ)。

                    Prefix Verb   URI Pattern                                                       Controller#Action
        new_member_session GET    /members/sign_in(.:format)                             devise/sessions#new
            member_session POST   /members/sign_in(.:format)                             devise/sessions#create
    destroy_member_session DELETE /members/sign_out(.:format)                            devise/sessions#destroy
       new_member_password GET    /members/password/new(.:format)                        devise/passwords#new
      edit_member_password GET    /members/password/edit(.:format)                       devise/passwords#edit
           member_password PATCH  /members/password(.:format)                            devise/passwords#update
                           PUT    /members/password(.:format)                            devise/passwords#update
                           POST   /members/password(.:format)                            devise/passwords#create
cancel_member_registration GET    /members/cancel(.:format)                              devise/registrations#cancel
   new_member_registration GET    /members/sign_up(.:format)                             devise/registrations#new
  edit_member_registration GET    /members/edit(.:format)                                devise/registrations#edit
       member_registration PATCH  /members(.:format)                                     devise/registrations#update
                           PUT    /members(.:format)                                     devise/registrations#update
                           DELETE /members(.:format)                                     devise/registrations#destroy
                           POST   /members(.:format)                                     devise/registrations#create

ここで抑えて欲しいのは
・URL(の先頭)には members(モデル名+s)がつく
・コントローラーは devise/〇〇 が使われるということ。(railsアプリのディレクトリ内にあるわけではない)

では、デフォルトの状態からどんなカスタマイズをしたくなるか、以下のようなパターンがある。
1. ビューをカスタマイズしたい(デフォルトはダサいので誰もがしたくなるはず)
2. URLをカスタマイズしたい(ユーザーから見える部分だから綺麗にしたくなったりする)
3. モデルごとに使用するコントローラを変更したい(コントローラーの挙動をカスタマイズしたい)

コントローラーのカスタマイズ

デフォルトではdevise/〇〇が使われていたがこれを直接編集することはできない。
なので、コマンドでコントローラーを作成し、そのコントローラーを操作したいモデルに割り当て、それを編集する。
挙動のカスタマイズは人ぞれぞれなので、割り当てについて説明する。

$ rails g devise:controllers members

とするとapp/controllers/membersの中にコントローラが作られる

image.png

しかしまだ、コントローラーを作っただけなのでルーティングは上のものと変化していない。
つまりまだmemberモデルはdevise/〇〇のコントローラ を使ってしまう。なので、memberモデルに今作ったcontrollers/members内のコントローラを割り当てる作業をする。

routes.rb
Rails.application.routes.draw do
devise_for :members
end

を次のように変更する

routes.rb
Rails.application.routes.draw do
#devise_for :members
#使用するコントローラをapp/contorolers/members内のものにできる
devise_for :members, module: "members"
end

もしくは次のようにしても良い

routes.rb
Rails.application.routes.draw do
#devise_for :members
#以下ようにしても同様に、使用するコントローラをapp/contorolers/members以下にできる
#コントローラーの指定をより細かくできるという違いがある
devise_for :members, :controllers => {
 :sessions => 'members/sessions',
 :passwords => 'members/passwords',
 :registrations => 'members/registrations'
}
end

こうするとルーティングは次のようになり、memberモデルに今作ったcontrollers/members内のコントローラが割り当てられる。ここまできてようやくコントローラーがカスタマイズできる。
image.png

ちなみに

今回はmemberモデルに対応するコントローラ ということでrails g devise:controllers maembersとしたがrails g devise:controllers aaaでも大丈夫だ。(単数形でも大丈夫、モデル名と一致させなくてもroutes.rbで割り当てをするので大丈夫)
その場合以下のようにする

routes.rb
#これか
devise_for :members, module: "aaa"
#もしくはこれ
devise_for :members, :controllers => {
 :sessions => 'aaa/sessions',
 :passwords => 'aaa/passwords',
 :registrations => 'aaa/registrations'
}

ビューのカスタマイズ

まず、前提として、基本的にビューはコントローラのアクションが実行されてから呼び出される。つまり、ビューはコントローラーと連携してる必要がある
これをしっかり覚えておいてください。

では、ビューをカスタマイズ
以下のコマンドでビューファイルを作成

$ rails g devise:views XXXs

app/views/XXXsディレクトリが作成され、その中にビューファイルが作られる。
XXXsはディレクトリ名になるわけだが、このディレクトリ名が重要。
rails g devise:controllers maembersで作った、controllers/members内のコントローラで呼び出されるビューをカスタマイズするのであれば$ rails g devise:views membersとする。
つまり、コントローラーのディレクトリ名とビューのディレクトリ名は一致していないといけない。
また、XXXを省略して$ rails g devise:views とするとディレクトリ名はdeviseになる(デフォルトのdevise/〇〇のコントローラで呼び出されるビューをカスタマイズできる)
image.png

ここの話は、deviseで作られたモデルが複数ある時のがわかりやすいので、memberモデルとuserモデルを作ったとして改めて説明する。
(一から作ってビューやコントローラーは何もカスタマイズしていないものを考える。)

$ rails g devise member
$ rails g devise user

この時ルーティングは次のようになる。
image.png
ここからわかるように、
現状、userモデルもmemberモデルも devise/〇〇のコントローラーを使ってしまうので、memberモデルには新たに、members内にコントローラを作ってそれを割り当てる作業をする。(先ほど説明した通り)

rails g devise:controllers maembers

してからroutes.rbを編集(上で説明した通り)

routes.rb
Rails.application.routes.draw do
#devise_for :members
devise_for :members, module: "members"
devise_for :users
end

そうするとルーティングは以下のようになる。
image.png
これで、各モデルごとに異なるコントローラーを割り当てることができた。
では、ここでuserモデルを操作するためのビューをカスタマイズするにはどうするのか
そう、$ rails g devise:viewsとすればよかった。なぜなら、「userモデルの操作を担当するコントローラーはdevise/〇〇だから、viewフォルダ内ではdeviseディレクトリ内にビューファイルを作ればいい」からだ。

では、membersモデルを操作するためのビューをカスタマイズするにはどうするのか
そう、$ rails g devise:views membersとすればよかった。なぜなら、「memberモデルの操作を担当するコントローラーはmembers/〇〇だから、viewフォルダ内ではmembersディレクトリ内にビューファイルを作ればいい」からだ。

もちろん

rails g devise:controllers maembers
rails g devise:controllers users

としてから

routes.rb
Rails.application.routes.draw do
#devise_for :members
#devise_for :users
devise_for :members, module: "members"
devise_for :users, module: "users"
end

としても良い
(というかするのが一般的ではある...気がする... どっちか一方のコントローラーだけdeviseのままなのは変な感じがする)

くどくなってきたが、大事なのは
コントローラーのディレクトリ名に合わせてビューを作ろう
ということだ。

注意

deviseでコントローラーをカスタマイズするときも、基本的にコントローラー名は複数形にすべきだが、単数でも大丈夫と説明した。
rails g devise:controllers member
でもちゃんとディレクトリは作られる。
この時ビューをカスタマイズするのであれば、ビューファイルは app/views/member内にないといけない。
ならば
rails g devise:views member
とするべきだろう。
しかし、このビューを作るコマンドでは、作られるディレクトリは必ず複数形になって作られてしまう。
つまり、
rails g devise:views member
としてもapp/views/member内にビューファイルはできずにapp/views/members内にできる。
なので、コントローラ 名を単数形にしたい時、かつ、ビューファイルをカスタマイズしたいときは、一旦ディレクトリ名を複数形でビューファイルを作成してから、手動でディレクトリ名を変更する必要がある。

URLのカスタマイズ

一番最初に、URL(の先頭)には members(モデル名+s)がつくと説明した。こういうのを変えたかったり、sign_inをloginに変えたかったりすることがある。

デフォルトのURLの先頭を変える方法

memberモデルがあるときデフォルトは /members/sign_inとか /members/sign_upとかになっている。
これを/aaaa/sign_inとか /aaaa/sign_upにするなら以下。

routes.rb
Rails.application.routes.draw do
#devise_for :members
devise_for :members, path: 'aaaa'
end

先頭の/membersを無くして/sign_inとか /sign_upにするなら以下。

routes.rb
Rails.application.routes.draw do
#devise_for :members
devise_for :members, path: ''
end

/sign_inをloginにしたりする方法

routes.rb
Rails.application.routes.draw do
#devise_for :members
devise_for :members, path_names: {
      sign_in: 'login', sign_out: 'logout',
      password: 'secret', confirmation: 'verification',
      registration: 'register', edit: 'edit/profile'
    }
end

まとめ

これまでの説明を踏まえると、例えば以下のようになる

$ rails g devise member
$ rails g devise user
$ rails g devise:controllers members
$ rails g devise:views members
$ rails g devise:controllers admins
$ rails g devise:views admins
roures.rb
Rails.application.routes.draw do
devise_for :members,
    module: "members",
    path: '',
    path_names: {
      sign_in: 'login', sign_out: 'logout',
      password: 'secret', confirmation: 'verification',
      registration: 'register', edit: 'edit/profile'
    }

devise_for :users,
    module: "admins",
    path: "admin"
end
[vagrant@localhost devise-app]$ rails routes
                    Prefix Verb   URI Pattern                                  Controller#Action
        new_member_session GET    /login(.:format)                             members/sessions#new
            member_session POST   /login(.:format)                             members/sessions#create
    destroy_member_session DELETE /logout(.:format)                            members/sessions#destroy
       new_member_password GET    /secret/new(.:format)                        members/passwords#new
      edit_member_password GET    /secret/edit(.:format)                       members/passwords#edit
           member_password PATCH  /secret(.:format)                            members/passwords#update
                           PUT    /secret(.:format)                            members/passwords#update
                           POST   /secret(.:format)                            members/passwords#create
cancel_member_registration GET    /register/cancel(.:format)                   members/registrations#cancel
   new_member_registration GET    /register/sign_up(.:format)                  members/registrations#new
  edit_member_registration GET    /register/edit/profile(.:format)             members/registrations#edit
       member_registration PATCH  /register(.:format)                          members/registrations#update
                           PUT    /register(.:format)                          members/registrations#update
                           DELETE /register(.:format)                          members/registrations#destroy
                           POST   /register(.:format)                          members/registrations#create
          new_user_session GET    /admin/sign_in(.:format)                     admins/sessions#new
              user_session POST   /admin/sign_in(.:format)                     admins/sessions#create
      destroy_user_session DELETE /admin/sign_out(.:format)                    admins/sessions#destroy
         new_user_password GET    /admin/password/new(.:format)                admins/passwords#new
        edit_user_password GET    /admin/password/edit(.:format)               admins/passwords#edit
             user_password PATCH  /admin/password(.:format)                    admins/passwords#update
                           PUT    /admin/password(.:format)                    admins/passwords#update
                           POST   /admin/password(.:format)                    admins/passwords#create
  cancel_user_registration GET    /admin/cancel(.:format)                      admins/registrations#cancel
     new_user_registration GET    /admin/sign_up(.:format)                     admins/registrations#new
    edit_user_registration GET    /admin/edit(.:format)                        admins/registrations#edit
         user_registration PATCH  /admin(.:format)                             admins/registrations#update
                           PUT    /admin(.:format)                             admins/registrations#update
                           DELETE /admin(.:format)                             admins/registrations#destroy
                           POST   /admin(.:format)                             admins/registrations#create

image.png

参考

https://qiita.com/akasakas/items/138c29fa2cecd271cfe4
https://qiita.com/ryosuketter/items/9240d8c2561b5989f049
https://www.rubydoc.info/github/heartcombo/devise/master/ActionDispatch/Routing/Mapper
特に3つ目のやつ見てください。

3
10
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
3
10