Railsチュートリアル8章まとめ。ログイン画面実装(画面遷移編)

Railsチュートリアル 8章を終えました。
8章ではユーザログイン画面を作成していきます。
今回は画面遷移を実装します
セッション編は次回

railstutorial.jp

ログイン画面について

まずログインとログアウトの要素を、Sessionsコントローラの特定のRESTアクションにそれぞれ対応付けるために Sessionsコントローラとnewアクションを作成します
$ rails generate controller Sessions new

view作成

app/view/session/newにログインして別画面に遷移する、下記のような見た目の画面を作っていきます。

ログイン画面
ログイン画面

この画面のviewを書いていきます。

<div class="row">
    <div class="col-md-6 col-md-offset-3">
        <%= form_for(:session, url: login_path) do |f| %>

        <%= f.label :email %>
        <%= f.email_field :email, class: 'form-control' %>

        <%= f.label :password %>
        <%= f.password_field :password, class: 'form-control' %>

        <%= f.label :remember_me, class: "checkbox inline" do %>
        <%= f.check_box :remember_me %>
        <span>Remember me on this computer</span>
        <% end %>

        <%= f.submit "Log in", class: "btn btn-primary" %>
        <% end %>

        <p>New user?
            <%= link_to "Sign up now!", signup_path %>
        </p>
    </div>
</div>

コントローラでログインに成功したときに別ページにルーティングしておけば、
上記でユーザとパスワードを入力してLog inボタンを押下することでそのページに遷移することができます

セッションの場合のフォームのアクションの指定先

ここでform_for(:session, url: login_path)としているのは、ログインした時にユーザ情報をセッションに格納するためで、 そのためにはリソースの名前とそれに対応するURLを具体的に指定する必要があるためです。

セッション

ログインした際に、ページを離れるたびに毎回毎回ログインせずにすむように、ユーザ情報等、情報を保持したいときに、 ブラウザやRailsサーバにセッションを保持することでユーザ情報を持たすことができます
ブラウザ側に情報を持たせるときにcookie、サーバー側はsessonとなります
cookieはブラウザ側にユーザーのブラウザに保存される小さなテキストデータとなり、
セッションはHTTPプロトコルの上位の階層に保持されているので情報が保持できます

セッション保持

ユーザ情報をsessionに保持するためには

session[:user_id] = user.id

とすることでIDが一時的に保存され、 そして session[:user_id] を使ってユーザーIDを取り出すこともできます。

ログイン失敗と成功

入力したユーザー名やパスワードが不一致の時のログイン失敗する時の処理は、
ログインに失敗した旨のメッセージ(flash)を表示すればいい感じです。

ログイン成功時は別ページに飛べばいい感じです

  def create
    @user = User.find_by(email: params[:session][:email].downcase)
      if @user && @user.authenticate(params[:session][:password])
     ###ログイン成功
        log_in @user
        redirect_to @user
    else
      # エラーメッセージを作成する
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

ここでif @user && @user.authenticate(params[:session][:password])のauthenticateメソッドは認証に失敗したときにfalseを返すので ログインに成功するかどうかを確認できます

また、

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
  end

上記をapp/helper/session_helper.rb内に定義してそのhelperをapplication.rbにincludeすれば
`log_in @userとlog_inメソッドを汎用的に使用することができ、 sessionにユーザ情報を格納できます

flash.now

コントローラ内でフラッシュ表示をflashで指定すると、リクエストのフラッシュメッセージが一度表示されると消えずに残ってしまいます flash.nowを指定することで表示された時だけ表示され別ページに移動したら消えます
(テスト方法として、ログインをわざと失敗→別ページに移動→フラッシュメッセージが表示されてないことを確認できたらokです)

ログイン後

ログインしている、していないによるページの表示切り替えを行うなどをしたいときには、
今ログインしているかどうか判断して分岐が必要です。

@current_user ||= User.find_by(id: session[:user_id])とすると、sessionに格納しているユーザを検索してそのユーザーID を取り出せます。
もしログインしていない時はsessionがnilになりUse.find_byもnilになるので@current_user=@current_userが実行されることになります

要するに@current_user ||= User.find_by(id: session[:user_id])app/helper/session_helper.rb内に定義すればいい感じです

  # 現在ログインしているユーザーを返す (ユーザーがログイン中の場合のみ)
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

セッション実装編へ続きます

参照

記事を作るときに参考にしました。ありがとうございます www.masalog.site