【Rails】deviseについて(ログイン機能の実装)/リダイレクト機能
SNSなどにあるようなログイン機能を実装したいと思います。
この機能を実装することで、
ログインするとログインボタンがユーザー名に切り替わったり、
ログインしたユーザーのみが投稿機能を利用できるように
制限をかけることができます。
このログイン機能を実装するために、
ユーザー管理機能を簡単に実装することができるdeviseというGemを
インストールして使用します。
gemをインストールするところは省きます。
インストールしたら
rails g devise : install というコマンドを実行することで、
設定関連に使用するファイルを自動で生成してくれます。
そこまで完了したら
deviseのUserモデルを作成しましょう。
こちらは通常のモデルの作成方法ではなく、
deviseのモデル作成用コマンドを用います。
rails g devise user
と入力して実行しましょう。
もちろんマイグレーションファイルも合わせて生成してくれます。
また自動的にroutes.rbに devise_for : users が追記されます。
この devise_for はユーザー機能に必要な複数のルーティングを
一度に生成してくれているdeviseのメソッドです。
では自動生成されたマイグレーションファイルを使用して
テーブルを作成していきましょう。
マイグレートを行いusersテーブルが作成されたことを確認してください。
そしてrails sも忘れずに。
ここで一つ問題が。
現状、ログインしているいないに関わらず
新規投稿画面にアクセスすることができます。
そこで未ログインユーザーがアクセスした場合に
ルートパスに遷移するよう設定を行いましょう。
こういった、本来受け取ったパスと別のパスに
転送することをリダイレクトと言います。
ではまずどのようにログインしているか判別するか。
この判別にはuser_signed_in?メソッドとunlessを使用します。
user_signed_in?メソッド
こちらはログインしているか判別するためのメソッドです。
これを合わせてunlessを使用しましょう。
ではコントローラーに定義します。
ここでもまずbefore_actionで処理を実行するメソッドをまとめます。
今回は7つのアクションのうち、
未ログインユーザーが使用できるメソッドが index と show になります。
(ログインしていなくても一覧と詳細は表示できる)
なのでこの2つのアクション以外を実行した場合は
ルートパスへのリダイレクトを適用させましょう。
before_action : move_to_index , expect : [ : index , : show ]
private
def move_to_index
unless user_signed_in?
redirect_to action: : index
end
end
unless user_signed_in?
でログインしるユーザーではない時(返り値がfalseの時)
の処理を指定しています。
redirect_to action: リダイレクト先となるアクション名
でリダイレクト処理を指定できます。
またビューに関してですが、
deviseでログイン機能を実装すると
ログイン/サインアップ画面が自動的に生成されます。
ただこれはGem内に存在するビューファイルを読み込んでいるため
ビューファイルとしては生成されません。
ここに変更を加えたい場合にはdeviseのコマンドを実行して
ビューファイルの生成します。
rails g devise : views
これで、ログイン画面(sessionsディレクトリ)と
サインアップ画面(registrationsディレクトリ)の
ビューファイルが生成されました。
違うディレクトリの同じファイル名なので
編集するときには気をつけましょう。
ではサインアップ画面にて入力できる最大文字数を指定してみましょう。
ニックネームをテーブルのカラムに追加し、
ビューファイルにフォームを追加します。
<div class= "field">
<%= f . label : nickname %> < em >( 6 characters maximum )< /em >< br />
<%= f . text_field : nickname , autofocus : true , maxlength : " 6 " %>
</div>
ここで覚えて欲しいのはmaxlengthメソッドです。
これはtext_fieldに使えるオプションで、入力できる最大文字数を指定できます。
そして最後にもう一つ大事なこと。
deviseに関わるコントローラーはGemに記述されており、
編集ができません。
そこで何が問題になるかというと、
ストロングパラメーターの定義ができないということです。
そのため、deviseにストロングパラメーターを設定するときには
特別な記述が必要となります。
その方法は2つあります。
①devise特有のパラメーターを取得する方法
devise_parameter_sanitizerメソッド
deviseにおけるparamsのようなメソッドです。
「ログイン」「新規登録」などのリクエストからパラメーターを取得できます。
これはもうこういうものなんだという感じで覚えて欲しいのですが、
メソッド名にも慣習的なものがあります。
実際に書くとこうです。
private
def configure_permitted_parameters
devise_parameter_sanitizer.permit ( :deviseの処理名, keys: [ : 許可するキー] )
end
メソッド名は本当はなんでもいいのですが、
慣習的なものでこのように定義することが多いです。
そしてdevise_parameter_sanitizer.permitのpermitメソッドですが、
これはparamsの時とちょっと違います。引数が違うんです。
今までは
params.require( : モデル名). permit( : 許可するキー)
でしたが、今回は
devise_parameter_sanitizer.permit ( : deviseの処理名 , keys : [ : 許可するキー] )
と第一引数にdeviseの処理名、
第二引数にKeysというキーに対し、配列でキーを指定して、
許可するパラメーターを追加します。
ではdeviseの処理名にはどんなものがあるのかみてみましょう。
: sign_in(サインイン(ログイン)の処理を行う時)
: sign_up(サインアップ(新規登録)の処理を行う時)
: account_update(アカウントの情報更新の処理を行う時)
これらを使用することができます。
そして第一引数に該当する処理の時、Keysに指定された名前をもつ
パラメーターの取得を許可します。
ではdeviseのコントローラーは編集できないので、
どこに記述すればいいのでしょうか。
application_controller.rbファイルに記述しましょう。
これは全てのコントローラーが継承しているファイルなので、
ここに記述されたことは全てのコントローラーで共通となる処理になります。
今まで作ってきたコントローラーも、全てこのファイルの処理が読み込まれた上で
作られる仕組みになってます。
ではこのファイルにストロングパラメーターを定義して
処理を読み込ませましょう。
今回もbefore_actionを使用して各アクションの事前処理として設定します。
before_action : configure_permitted_parameters, if : : divise_controller?
private
def configure_permitted_parameters
devise_parmeter_sanitizer. permit ( : sign_up , keys : [ : nickname ] )
end
if : : divise_controller?
ここに注目してみましょう。
これは値にメソッド名を指定することで、
戻り値がtrueの時のみ処理を実行する設定です。
つまり今回はdeviseのヘルパーメソッド名を指定して、
もしdeviseに関する処理であればそのメソッドを実行するよう指示しています。
つまり「この処理の対象はdeviseコントローラーだよ」といってます。
もしこれをbefore_actionとして設定していなければ、
別のコントローラーが実行される時にもこの処理が実行されてしまいます。
applicationコントローラーは全てのコントローラーに継承されてしまうので。
長くなりましたが、
ここまでがdeviseの使い方に関する一連の流れです!
いろいろ特殊ですが便利な機能なのでしっかり覚えましょう。