初めに
この記事では、deviseでadminとuserの二画面を構成し、二つのアカウントで同時にログインをした際に、どのようにヘッダーの切り替えをすることができるのかについて書いていきたいと思います。
先に解決方法を知りたい方はこちらから
前提
ruby 2.6.9
rails 5.2.5(多分ここは6系でも大丈夫です)
devise(userとadminの二画面構成 & namespaceでadminのviewは全て/adminがついている)
解決したい問題
現在の状態は、application.html.erbでheaderを記述しておりheaderが呼び出される状態になっている。admin側とuser側でheaderのメニューを条件分岐を使用して切り替えている。
userでログインを行い、adminでもログインを行なっている際に、admin側の管理者画面ではない画面を開いた時にもheaderのメニューがuserのheaderに切り替わらない。
もう少し簡単に説明すると、adminの画面、つまり/adminから始める画面では正常にadminのheaderのメニューが表示されるが、userの画面、/から始まる画面ではuser側のheaderのメニューが表示されずadmin側のheaderのメニューが表示されている状態になってしまっている。
## application.html.erb
if admin_signed_in?
// adminログイン状態の際に、表示したいheaderのメニューを記載
elsif user_signed_in?
// userログイン状態の際に、表示したいheaderのメニューを記載
else
// adminでもuserでもログインしていない時に表示するheaderのメニューを記載
end
原因
原因としては簡単で、if分は上から順番に条件を実行し、trueが返されたものを実行するため今回adminとuserの二つでログインをしていても、初めにadmin_signed_in?でtrueが返されてしまい、user_signed_in?は実行すらされないことが原因となっている。
解決方法
解決方法としては、全部で三つが挙げられるかなと思います。今回この記事では2つのアカウントでのログインを許容する一番楽な解決方法にフォーカスして紹介していきたいと考えております。
2つのアカウントでのログインを許容する解決方法
- 全てのadmin側とuser側のviewに部分テンプレートでheaderを呼び出す(めっちゃめんどくさい)
- urlのpathを取得し、pathごとにurlを判別する方法
ログインしているアカウントは常に一つ
- userかadminにログインがかかる際に、deviseのreset_sessionを使用してログインしているデータを強制的にログアウトさせる方法(多分reset_sessionを使わずにもっと賢い方法があるはず)
具体的な解決方法
urlのpathを取得し、pathごとにurlを判別する方法
今回この記事ではpathからadminの画面なのかuserの画面なのかを判断して画面ごとに適切なheaderを返すような仕様に変更してきたいと思います。
まず、現在のURLのpathを取得するためにrequestというものを使用します。
requestについてはこちらを参照してください。
今回は、URLの中に/adminが含まれていればadminのheaderを返して含まれていなければuserのheaderのメニューを返す仕様にしていきます。今回はrequestの中のrequest.fullpathを使用して現在いる画面のpathを取得していきます。そして、その受け取ったpathの中に/adminが含まれているか文字列の検索をかけるのでinclude?というメソッドを使用し、/adminが含まれていればtrueを返し、含まれていなければfalseを返すように設定をします。
## 実装例
if request.fullpath.include? "/admin"
//admin側のheaderを返す
else
// user側のheaderを返す
end
上記で/adminが含まれているか、条件分岐をかけることができたのであとはこの内容をapplication.htmlに記述してあげれば一件落着になります。
if admin_signed_in?
if request.fullpath.include? "/admin"
//admin側のheaderを返す
else
// user側のheaderを返す
end
elsif user_signed_in?
// userログイン状態の際に、表示したいheaderのメニューを記載
else
// adminでもuserでもログインしていない時に表示するheaderのメニューを記載
end
最後に
これで、adminとuserの両方のアカウントでログインをしていても適切なheaderが返される仕様にすることができました。解決方法のところで紹介した一つのアカウントのログインのみを許容するという仕様も良いのですが、私はいちいちログインし直すのがめんどくさいので、私のようなめんどくさがり屋におすすめな実装方法になるかなと思います。devise最高〜〜〜