フレンドリーフォワーディング
ログインしていないユーザーが編集ページにアクセスしようとしていたなら、ユーザーがログインした後にはその編集ページにリダイレクトされるようにする
フレンドリーフォワーディングのテスト
test/integration/users_edit_test.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
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を追加する
.
.
.
# ログイン済みユーザーかどうか確認
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
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ハッシュをオン、オフにする
# 1がオン remember(user)を行う
# 0がオフ forget(user)を行う
# remember(user) ダイジェストをデータベースに記憶させる
redirect_back_or @user
else
flash.now[:danger] = 'Invalid email/password combination'
# flash.nowでリクエストが発生後メッセージを消滅する
# エラーメッセージを作成する
render 'new'
# newアクションのビューを表示
end
end
.
.
.
end
演習
フレンドリーフォワーディングで、渡されたURLに初回のみ転送されていることを、テストを書いて確認してみましょう。次回以降のログインのときには、転送先のURLはデフォルト(プロフィール画面)に戻っている必要があります。ヒント: リスト 10.29のsession[:forwarding_url]が正しい値かどうか確認するテストを追加してみましょう
.
.
.
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)
.
.
.
7.1.3で紹介したdebuggerメソッドをSessionsコントローラのnewアクションに置いてみましょう。その後、ログアウトして /users/1/edit にアクセスしてみてください(デバッガーが途中で処理を止めるはずです)。ここでコンソールに移り、session[:forwarding_url]の値が正しいかどうか確認してみましょう。また、newアクションにアクセスしたときのrequest.get?の値も確認してみましょう(デバッガーを使っていると、ときどき予期せぬ箇所でターミナルが止まったり、おかしい挙動を見せたりします。熟練の開発者になった気になって(コラム 1.2)、落ち着いて対処してみましょう)。
できなかった。