概要
サインアップしたユーザーが、メールアドレスとパスワードでサインインし、サインアウトする機能を実装する。
セッションによるアクセス制限などの管理は後に実装し、ここではユーザー認証とページ遷移だけにとどめる。
サインイン機能
サインイン処理アクション
サインインが要求されたとき、sign_inアクションからサインインのビューがレンダリングされる。ビューのフォームとの間でUserモデルを介してデータをやりとりするので、アクションでUserモデルのインスタンスを生成しておく。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
class UsersController < ApplicationController ..... def sign_in @user = User.new render layout: 'application_signed_out' end ..... end |
フォームでのモデルの設定
サインインのビュー、sign_in.html.erbのform_withヘルパーで、コントローラーで生成されたUserモデルのインスタンスを指定する。
app/views/users/sign_in.html.erb
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="sign_in_page"> <h1>EX-BBS</h1> <div class="sign_in_form"> <h2>サインインページ</h2> <%= form_with model: @user, url: sign_in_path, local: true do |f| %> <%= f.email_field :email, placeholder: "メールアドレスを入力" %> <%= f.password_field :password, placeholder: "パスワードを入力" %> <button>サインイン</button> <p>ユーザー登録したい方は<%= link_to "サインアップへ", sign_up_path %></p> <% end %> </div> </div> |
サインイン処理
サインインフォームの入力情報は、users_controllerのsign_in_processアクションにPOSTされる(ルーティングは「フォームの入力を確認する」で設定した)。
users_controllerに、以下のsign_in_processメソッドを追加する。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class UsersController < ApplicationController def sign_up ..... def sign_in ..... def sign_in_process @user = User.new(user_params) encrypted_password = User.generate_digest(user_params[:password]) user = User.find_by(email: user_params[:email], password: encrypted_password) if user redirect_to top_path and return else flash.now[:danger] = "サインインできません" render :sign_in, layout: 'application_signed_out' and return end end private def user_params ..... end |
処理の流れは以下のとおり。
- POSTされたデータを
user_paramsメソッドにより受け取る(user_paramsについてはform_withとモデルの使い方を参照) user_paramsを使って入力データがセットされたUserインスタンスを生成- ユーザー登録時と同じ方法で暗号化されたパスワード(ダイジェスト)を生成
- メールアドレスとパスワードダイジェストで、データベースからユーザーを検索
- ユーザーが存在する場合、サインインとして
topページにリダイレクト - ユーザーが存在しない場合、エラーメッセージをセットして再度サインイン画面をレンダリング(
@userに入力データがセットされているので、サインイン画面にメールアドレスが残る)
サインアウト機能
サインインに成功すると、トップ画面に遷移する。
トップ画面を始めサインイン後にアクセス可能な画面は全てヘッダーメニューを持つ。そのメニュー中、サインアウトの項目をサインイン画面へのリンクとする。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html> ..... <body> <header> <div class="header_logo"></div> <h1>EX-BBS</h1> <ul class="header_menu"> <li><%= link_to("投稿する", "#") %></li> <li><%= link_to("プロフィール", "#") %></li> <li><%= link_to("サインアウト", sign_in_path) %></li> </ul> </header> <%= yield %> </body> </html> |