【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の中にコントローラが作られる
しかしまだ、コントローラーを作っただけなのでルーティングは上のものと変化していない。
つまりまだ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/〇〇のコントローラで呼び出されるビューをカスタマイズできる)
ここの話は、deviseで作られたモデルが複数ある時のがわかりやすいので、memberモデルとuserモデルを作ったとして改めて説明する。
(一から作ってビューやコントローラーは何もカスタマイズしていないものを考える。)
$ rails g devise member
$ rails g devise user
この時ルーティングは次のようになる。
ここからわかるように、
現状、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
そうするとルーティングは以下のようになる。
これで、各モデルごとに異なるコントローラーを割り当てることができた。
では、ここで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を見てください。
この記事が気に入ったらサポートをしてみませんか?