コミュ障だから明日が僕らをよんだって返事もろくにしなかった

何かを創る人に憧れたからブログをはじめたんだと思うよ

社会のボトムズがRailsに手を出す #8

これまでのあらすじ

最近SNSを見ていて思うのですが、Railsチュートリアルって何週もするものなのでしょうか?あれって『ゲームとかで言う「強くてニューゲーム」みたいなことをやっているだけなのでは?』って思うのですよ。みなさんは一度クリアしたゲームを「強くてニューゲーム」で何週もするんですか?僕は……。


めっちゃそういう周回プレイ大好き。圧倒的なパワーで蹂躙するのたまらねぇぜ!!


はい、もはやあらすじの体をなしてないRailsチュートリアル第八章はーじめるよー!!前回は登録の方の制御を作りました。今回はログインの方の制御をつくっていきます。あ、こんなこと書いてますけどRailsチュートリアル2週目記事とか書く気はないです。第一章の段階からおふざけプレイで色々やってるからね。二週目の追加要素は書ける気がしないのです。

前回記事
inujini.hatenablog.com



ログインフォームをつくるよ

今回はセッションの扱いとかの話なんですかね?まあ、何はともあれまずはログイン用のガワを作ります。

# $ rails generate controller Sessions new
$ rails generate controller [コントローラ名] [アクション]

そんでこんなの作りました。ログイン時はアカウント情報を表示するようになりました。
f:id:andron:20190112164337p:plain

Bootstrap4にしてるせいでレイアウトの修正は破壊的になりますね(笑)……。

<!-- app/views/layouts/_header.html.erb 一部抜粋 -->
        <% if logged_in? %>
          <li class="nav-item ml-2"><%= link_to "Users", '#', class: "text-light" %></li>
          <div class="dropdown">
             <a href="#" class="dropdown-toggle text-light" data-toggle="dropdown">
            Account <b class="caret"></b>
            </a>
            <div class="dropdown-menu">
              <a class="dropdown-item"><%= link_to "Profile", current_user, class: "ml-2 text-dark" %></a>
              <a class="dropdown-item"><%= link_to "Settings", '#', class: "ml-2 text-dark"  %></a>
              <a class="divider"></a>
              <a class="dropdown-item"><%= link_to "Log out", logout_path, method: :delete, class: "ml-2 text-dark" %></a>
            </div>
          </div>
        <% else %>
          <li class="nav-item ml-2"><%= link_to "Log in", login_path, class: "text-light" %></li>
        <% end %>


以下作成したソース。
コントローラ

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  # get    '/login',   to: 'sessions#new'
  def new
  end

  ### ユーザーログイン後にユーザー情報のページにリダイレクト
  ### ログインできない場合は、エラーメッセージを表示
  # post   '/login',   to: 'sessions#create'
  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

  ### ユーザーログアウト後にセッション情報を削除しホームへリダイレクト
  #  delete '/logout',  to: 'sessions#destroy'
  def destroy
    log_out
    redirect_to root_url    
  end  
end

ヘルパー

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

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

  # ユーザーがログインしていればtrue、その他ならfalseを返す
  def logged_in?
    !current_user.nil?
  end

  # 現在のユーザーをログアウトする
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end

### 備考
### app/controllers/application_controller.rb
### include SessionsHelper
end

ルーティングのコメントは後付けですがコントローラの方にちょろちょろコメント付けたからヘルパーとコントローラをいったきたりしなくてすんだ。ところで風の噂の情報なんですけど、「有償IDE使うと自分で作った処理も補完してくれるようになるってきいたんですけどマジですか?」さいつよじゃん。



んでテストの方は以下の通り。

# ログイン系の結合テスト作成
$ rails generate integration_test users_login
# test/integration/users_login_test.rb 一部省略
require 'test_helper'
class UsersLoginTest < ActionDispatch::IntegrationTest
  def setup
    @user = users(:michael)
  end

  test "login with invalid information" do
    get login_path
    assert_template 'sessions/new'
    post login_path, params: { session: { email: "", password: "" } }
    assert_template 'sessions/new'
    assert_not flash.empty?
    get root_path
    assert flash.empty?
  end

  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email: @user.email, password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
    assert_template 'users/show'
    delete logout_path
    assert_not is_logged_in?
    assert_redirected_to root_url
    follow_redirect!
  end    
end

assert_selectはタグ拾ってこれるかのチェックだし省略。こうやって雑なテストを書くからレイアウトも雑になるんだろうね(白い目)。

第八章の感想

セッションのいじり方を学ぼうということでログインとログアウトができるようになりました。とりあえず「fixture」の使い方とかが勉強になった。内容としては短いですがそんな感じです。


次回はハッテン的ログイン機構だそうです。楽しみですね。


つづく……。


参考: fixture
fixtures - リファレンス - - Railsドキュメント