見出し画像

【Rails】deviseのController,View,URLのカスタマイズ(ログイン機能を2つ作成)

deviseの仕組み

$ 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. モデルごとに使用するコントローラを変更したい(コントローラーの挙動をカスタマイズしたい、2つのログイン機能を作りたい)

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


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

$ rails g devise:controllers members


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

画像1

しかしまだ、コントローラーを作っただけなのでルーティングは上のものと変化していない。
つまりまだ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内のコントローラが割り当てられる。ここまできてようやくコントローラーがカスタマイズできる。


ビューのカスタマイズ


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

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

$ 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/〇〇のコントローラで呼び出されるビューをカスタマイズできる)

画像2

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

$ rails g devise member
$ rails g devise user


この時ルーティングは次のようになる。

画像3


ここからわかるように、
現状、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


そうするとルーティングは以下のようになる。

画像5


これで、各モデルごとに異なるコントローラーを割り当てることができた。
では、ここで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

https://qiita.com/akasakas/items/https://qiita.com/akasakas/items/138c29fa2cecd271cfe4

https://qiita.com/70yama/items/dbf428a51830e70aa9bd

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




この記事が気に入ったらサポートをしてみませんか?