読者です 読者をやめる 読者になる 読者になる

ぞえの技術めも

Ruby on Rails勉強中

【104日目】【1日20分のRailsチュートリアル】【第9章】フレンドリーフォワーディング機能を実装する

Ruby on Railsチュートリアル(第3版)

今日は「9.2.3 フレンドリーフォワーディング」の実装するところから。

9.2.3 フレンドリーフォワーディング

失敗するテストが書けたので、ようやくフレンドリーフォワーディングを実装する準備ができました。
ユーザーを希望のページに転送するには、リクエスト時点のページをどこかに保存しておき、その場所にリダイレクトさせる必要があります。

Sessionsヘルパーにリクエスト時点のページを保存するメソッドと保存したページにリダイレクトさせるメソッドを追加。

app/helpers/sessions_helper.rb

module SessionsHelper
  :
  # 記憶した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.url if request.get?
  end
end

ただし、GETリクエストが送られたときだけ格納するようにしておきます。

稀なケースに対応するために必要らしい。

こういったケースに対処しておかないと、POSTや PATCH、DELETEリクエストを期待しているURLに対して (リダイレクトを通して) GETリクエストが送られてしまい、場合によってはエラーが発生します。

不整合が発生するので対応しておく感じなのかな。。。なんかよく分からないけど今はいいや。

先ほど定義したstore_locationメソッドを使って、早速beforeフィルターのlogged_in_userを修正してみます (リスト9.28)。

logged_in_userメソッドにstore_locationを追加。

app/controllers/users_controller.rb

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

フォワーディング自体を実装するには、redirect_back_orメソッドを使用します。
(中略)
デフォルトのURLは、Sessionコントローラのcreateアクションに追加し、サインイン成功後にリダイレクトします (リスト9.29)。

Sessionコントローラのcreateアクションにてredirect_back_orメソッドを使うように変更。

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
      :
    end
  end

サンプルソースuserだけど私のコード@user使ってる。。。
なんかどっかで直した気がするのでとりあえず@userのままで。問題はないはず。

session.delete(:forwarding_url) という式を通して転送用のURLを削除している点に注意してください。
これをやっておかないと、次回ログインしたときに保護されたページに転送されてしまい、ブラウザを閉じるまでこれが繰り返されてしまいます。

redirect_back_orメソッドの中身の話。
確かにこれうっかり忘れそうだな。使ったら初期化しておく。

実装が終わったのでテスト実行して問題ないことを確認。
これで基本ユーザー認証機能とページ保護機能の実装は完了。

$ bundle exec rake test
35 tests, 84 assertions, 0 failures, 0 errors, 0 skips

今日の学習時間は【26分】

次は「9.3 すべてのユーザーを表示する」から。