Rails チュートリアル 第8章 備忘録

第8章の備忘録です。

##環境
Rails 6.0.3
Ruby 2.6.3

##目次
[1 セッションとcookies](#1-セッションとcookies)
[2 フラッシュメッセージ表示](#2-フラッシュメッセージ表示)
[3 ヘルパーメソッドを作成して利用するまでの流れ](#3-ヘルパーメソッドを作成して利用するまでの流れ)
[4 jqueryとbootstrapの導入方法](#4-jqueryとbootstrapの導入方法)
[5 signupした後に再度ログインさせない](#5-signupした後に再度ログインさせない)



##1 セッションとcookies
日頃通信する時に利用されている**HTTP**は**ステートレスなプロトコル**である。
そのステートレスとは、
ブラウザ側が、〇〇のページを表示してください（リクエスト）→サーバー側が、〇〇のページです！（レスポンス）のやりとりをトランザクションというのだが、一度そのやりとりを終えるとすっかり忘れてしまうのである。

つまり、会員サイトでログインした後に、この商品の購入ページを表示してくださいとリクエストを送ると、以前のログインしたやりとりを忘れてしまっているので、**あなたは誰ですか？**となってしまう。

それを防ぐために、ユーザーのIDを保持しておくための設定がセッションである。

そして、そのセッションを実装するために使われるのが、**cookies**である。cookiesはブラウザに保存することができる小さなでキストデータである。ここにログインしたらユーザーのIDを保管、ログアウトしたらcookiesに保管したものを削除することで、ログインの機能を作っているのである。

##2 フラッシュメッセージ表示
第7章で実装した、新規登録時に表示されるフラッシュメッセージは、ActiveRecordオブジェクトに関連づけられていたものだが、セッション時にはActiveRecordを使用していないので、別の方法で作成する必要がある。

```app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
  end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      # ユーザーログイン後にユーザー情報のページにリダイレクトする
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
  .
  .
end
```

実装の流れとしては、
表示したいタイミングで、flashメソッドを使用。`application.html.erb`でCSS含めレイアウトしてあるので、この1行で自動的に表示される。

また、flashメソッドだけだと、再レンダリングしても消えない小さなバグが発生するため、flashメッセージを表示した後に、リクエストが発生したら表示を消す機能を含んだ、`flash.now`メソッドを使用する

##3 ヘルパーメソッドを作成して利用するまでの流れ
ここまで来ると、各Controller毎に、ログインしているかどうかでの条件分岐が多発してくる。毎度毎度のコードを簡潔にメソッドとしてまとめておくと、コードが簡略化されるため、自身でメソッドを作成し使用するまでの流れをまとめる。

1. `application_controller.rb`に、ヘルパーモジュールを読み込む（今回は`sessions_helper.rb`）

```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include SessionsHelper
end
```

2. 自作メソッドをhelperファイルに作成(今回はlog_inメソッド)

```app/helpers/sessions_helper.rb
module SessionHelper
  def log_in(user)
    session[:user_id] = user.id
  end
end
```

3. Controllerファイルで使用

```appp/controllers/sessions_controller.rb
.
.
  def create
  .
  .
  log_in user
  .
  end
.
```

こうすることで、実際にメソッドを使用することができる。
今回はlog_inメソッドの中身も1行であるが、今後複数行のメソッドを作ることも想定し同じ動作を繰り返すのであれば、このようにすることで、メソッド名を設定することで可読性も上がり、DRYであることに繋がる。

##4 jqueryとbootstrapの導入方法
Rails6から設定方法が変わった？かもしれないらしいので、今回はRails6での設定方法をまとめる。

1. yarnでインストール

```
$ yarn add jquery@3.4.1 bootstrap@3.4.1
```

2. WebpackにjQueryの設定を追加

```config/webpack/environment.js
const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)

module.exports = environment
```

3. 必要なJSファイルをrequire / import

```app/javascript/packs/application.js
.
.
require("jquery")
import "bootstrap"
```

##5 signupした後に再度ログインさせない
signupの機能を作った後に、login機能を作るとうっかり忘れがちになりそう？なのだが、実際にsignupすると、ログイン状態にならない。

実際の動きは、`redirect_to @user`で`/users/◯`の**show**ビューが表示されているのだが、セッションにユーザーIDを保存していないので、セッションを用いて作成した`current_user`や`logged_in`メソッドが使えない、もしくはfalseを返す。

こうならないためにも、signup時の`create`アクションでユーザーが保存されたら、`log_in @user`を忘れない。



わざわざ書くまでのことではないのかもしれないが、ユーザー登録自体がめんどくさいと思ってしまう自分だったら、仮に新規登録した後に、ログイン画面で再度入力しなければならなくなった場合、そっとそのアプリを閉じると思う。。笑

ちょっとしたユーザービリティも考えて一応メモ。