railsチュートリアル第10章 フレンドリーフォワーディング

###フレンドリーフォワーディング
ログインしていないユーザーが編集ページにアクセスしようとしていたなら、ユーザーがログインした後にはその編集ページにリダイレクトされるようにする
####フレンドリーフォワーディングのテスト
test/integration/users_edit_test.rb

```rb
 require 'test_helper'
 # test_helper.rbのパラメータ群を指定

class UsersEditTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end
.
.
.
 test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    # URLで指定したファイルの送信を要求
    log_in_as(@user)
    # テストユーザーとしてログインする
    assert_redirected_to edit_user_url(@user)
    # リダイレクト先がどうなっているかバリデーション
    # edit_user_url(@user)になっているか？
    name  = "Foo Bar"
    email = "foo@bar.com"
    # テスト情報を代入
    patch user_path(@user), params: { user: { name:  name,
                                              email: email,
                                              password:              "",
                                              password_confirmation: "" } }
    # user_path(@user)にparamasの情報を更新する
    # ここ編集の場合パスワードを変更しない
    assert_not flash.empty?
    # flashは表示されたか？ false 空じゃない
    assert_redirected_to @user
    # リダイレクト Webサイト全体やページなどを
    #               新しいURLに変更したときに、
    #               自動的に新しいURLに転送する仕組み
    # ユーザーページに転送したら本当に行っているか?
    @user.reload
    # レコードを再取得
    # @userはモデル（データ）
    # モデルとはアプリケーションが扱うデータや処理を表現する仕組み
    # データを表している
    # レコードとは、データベース内のテーブルを構成する単位のひとつで、
    #  一行分のデータを指します。
    # ユーザーのデータを取得する
    assert_equal name,  @user.name
    assert_equal email, @user.email
    # 名前とemailが変更されているかを確認
  end
end
```

####フレンドリーフォワーディングの実装 
app/helpers/sessions_helper.rb

```rb
module SessionsHelper
.
.
.
  # 記憶したURL（もしくはデフォルト値）にリダイレクト
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    # ||は又は
    # URLを指定して表示
    session.delete(:forwarding_url)
    # カラムを削除する
  end

  # アクセスしようとしたURLを覚えておく
  def store_location
    session[:forwarding_url] = request.original_url if request.get?
    # GETリクエストが送られたとき
  end
end
```
####ログインユーザー用beforeフィルターにstore_locationを追加する
```rb
.
.
.
    # ログイン済みユーザーかどうか確認
    def logged_in_user
      unless logged_in?
      # もしも、評価が偽(false)であれば○○する
        store_location
        flash[:danger] = "Please log in."
        # ログインされていなければメッセージを表示する
        redirect_to login_url
        # ログインページを表示させる
      end
    end
    
    # 正しいユーザーかどうか確認
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
      # データベースと照らし合わせて無かったらホーム画面にいく。
    end
end

```

####フレンドリーフォワーディングを備えたcreateアクション
app/controllers/sessions_controller.rb

```rb
class SessionsController < ApplicationController

  def new
  end
  
  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    # 送信されたメアドを使ってデータベースから取り出す。
    #emailを小文字にする
    if @user &.authenticate(params[:session][:password])
    # user  取得したユーザーが有効かどうか？
    # その後にデータベース上にパスワードがあるか？
    # ユーザーログイン後にユーザー情報のページにリダイレクトする
    # &.は省略型
      log_in @user
      # ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      # ログイン中のremember_meハッシュをオン、オフにする
      # １がオン remember(user)を行う　
      # ０がオフ forget(user)を行う
      # remember(user) ダイジェストをデータベースに記憶させる
      redirect_back_or @user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      # flash.nowでリクエストが発生後メッセージを消滅する
      # エラーメッセージを作成する
        render 'new'
        # newアクションのビューを表示
    end
  end
.
.
.
end

```
###演習
1.
フレンドリーフォワーディングで、渡されたURLに初回のみ転送されていることを、テストを書いて確認してみましょう。次回以降のログインのときには、転送先のURLはデフォルト（プロフィール画面）に戻っている必要があります。ヒント: リスト 10.29のsession[:forwarding_url]が正しい値かどうか確認するテストを追加してみましょう

```rb
.
.
.
 test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    # URLで指定したファイルの送信を要求
    assert_equal session[:forwarding_url], edit_user_url(@user) 
    #自分の編集ページかどうか
    log_in_as(@user)
    # テストユーザーとしてログインする
    assert_nil session[:forwarding_url]
    # 空かどうか？
    assert_redirected_to edit_user_url(@user)
.
.
.
```
2.
7.1.3で紹介したdebuggerメソッドをSessionsコントローラのnewアクションに置いてみましょう。その後、ログアウトして /users/1/edit にアクセスしてみてください（デバッガーが途中で処理を止めるはずです）。ここでコンソールに移り、session[:forwarding_url]の値が正しいかどうか確認してみましょう。また、newアクションにアクセスしたときのrequest.get?の値も確認してみましょう（デバッガーを使っていると、ときどき予期せぬ箇所でターミナルが止まったり、おかしい挙動を見せたりします。熟練の開発者になった気になって（コラム 1.2）、落ち着いて対処してみましょう）。

できなかった。