3
2

More than 3 years have passed since last update.

【Rails】フレンドリーフォワーディング【Rails Tutorial 10章まとめ】

Posted at

認可機能によって、ログインしていないユーザーが編集ページにアクセスしようとすると、ログインページにリダイレクトされる。
その後ログインするとプロフィールページに移動するが、ここでもともとアクセスしようとしていた編集ページに移動してくれると親切である。
これをフレンドリーフォワーディングと呼ぶ。

フレンドリーフォワーディングのテスト

フレンドリーフォワーディングは少し複雑なので、テスト駆動開発で進める。
編集成功時のテストを修正する。

test/integration/users_edit_test.rb
  test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_redirected_to edit_user_url(@user)
    name  = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), params: { user: { name:  name,
                                              email: email,
                                              password:              "",
                                              password_confirmation: "" } }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name,  @user.name
    assert_equal email, @user.email
  end

編集ページにアクセス→ログインページにリダイレクトしてログイン→編集ページにリダイレクト、という流れになる。

フレンドリーフォワーディングの実装

store_locationとredirec_back_orメソッド

ユーザーを希望のページに転送するには、リクエスト時点のページを保存しておく必要がある。

app/helpers/sessions_helper.rb
  # 記憶したURL (もしくはデフォルト値) にリダイレクト
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

  # アクセスしようとしたURLを覚えておく
  def store_location
    session[:forwarding_url] = request.original_url if request.get?
  end

store_locationメソッドでは、session[:forwarding_url]に、リクエスト先を取得するrequest.original_urlを入れる。
この時、セキュリティ上の問題を解決するために、request.getを使ってGETリクエストの場合のみとする。

redirect_back_orメソッドでは、or演算子||を使って、session[:forwarding_url]がある場合はそちらにリダイレクトし、無い場合は引数のURLにリダイレクトする。
リダイレクト後はsession[:forwarding_url]を削除しておく。

store_locationメソッドを使って、非ログイン時に編集ページにアクセスしたらURLを保存する。

app/controllers/users_controller.rb
    # beforeアクション

    # ログイン済みユーザーかどうか確認
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

redirect_back_orメソッドを使って、ログイン後に保存したURLにリダイレクトする。

app/controllers/sessions_controller.rb
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      redirect_back_or user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2