Day11です!もうすぐで2週間!
9月も時間の流れが早いですね。
今日はシュレッダーを紙でつまらせ、時間を取られ、全然チュートリアルできませんでした。
もう1枚ずつしか入れない。
今日もがんばっていきましょー!
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
[Day11]第十章10.2.1〜10.2.3作業ログ
ユーザーの認可
前回でユーザー情報の編集ができるようになった。
でも今はその編集ページのURLにアクセスすればだれでも情報を変更できるようになっている。
ログインしている自分の情報しか変更できないように変えよう。
edit,updateアクションの前に、ログインユーザーかどうか確認
edit,updateアクションの前に、ログインユーザーかどうかチェックするアクションを経由するように設計。
before_action :logged_in_user, only: [:edit, :update]
このbefore_action
を使うことによって、それが実現できる。
第二引数のonly: [:edit, :update]
を設定すると、特定のアクションの前だけ、before_action
を適用できる。
:logged_in_user
アクションは、current_userが存在しているかをチェックするlogged_in?
アクションを使って、ログイン済みかどうかチェック。
ログインしていなかったら、フラッシュメッセージとともにトップページへリダイレクトするように。
実際のコードはこんな感じ。
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
...
private
...
# beforeアクション
# ログイン済みユーザーかどうか確認
def logged_in_user
unless logged_in?
flash[:danger] = "Please log in."
redirect_to login_url
end
end
end
自分のユーザー情報だけ編集可能に
今はログイン済みであれば、他のユーザー情報も変更できてしまう。
さっきのbefore_action
を使って、current_userと編集対象のユーザーが同じであればOK、違っていたらリダイレクトするようにする。
編集対象のユーザーは編集ページのURL(users/4/edit)から、params[:id]でとってこれる。
実際のコードはこんな感じ。
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update]
...
private
...
# 正しいユーザーかどうか確認
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless @user == current_user
end
end
フレンドリーフォワーディング
ちょっと細かいところだけど、もしログインしていないユーザーが編集ページにアクセスしようとした時、ユーザーがログインした後はその編集ページにリダイレクトされるようにが親切な設計。
つまり、リダイレクト先はユーザーが開こうとしていたページにするのがベター。
このフレンドリーフォワーディングを実装するには、開こうとしていたページ情報を変数に保存する必要がある。
普通の変数だとアクションが終われば、忘れてしまうので、一時的にデータを蓄えておけるsessionを使ってあげる。
session[:forwarding_url]にリクエスト先立ったURLを保存してあげればOK。
またリクエスト先URLはrequest.original_url
で所得できる。
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.original_url if request.get?
end
end
あとは、ログインユーザーかどうか確認してるところに、store_location
アクション、情報を更新するcreateアクションに、redirect_back_or(default)
を設定してあげればOK。
タケシなりの演習の回答
何故editアクションとupdateアクションを両方とも保護する必要があるのでしょうか? 考えてみてください。
editアクションは個人情報保護のため(emailが覗かれる)、updateは情報の変更を阻止するため。
もしかしたら、ユーザー情報の変更を阻止するだけなら、updateアクションを制限するだけでもいいのかも。
上記のアクションのうち、どちらがブラウザで簡単にテストできるアクションでしょうか?
ブラウザでのチェックがしやすいのは、GETリクエストで調べられるeditアクションの方。
PATCHアクションはURLに乗せて情報を送れないので、ブラウザでのチェックは難しい。
フレンドリーフォワーディングで、渡されたURLに初回のみ転送されていることを、テストを書いて確認してみましょう。次回以降のログインのときには、転送先のURLはデフォルト (プロフィール画面) に戻っている必要があります。
リダイレクト後、session[:forwarding_url]がnilになっていればOK。
require 'test_helper'
class UsersEditTest < ActionDispatch::IntegrationTest
...
test "successful edit with friendly forwarding" do
get edit_user_path(@user)
log_in_as(@user)
assert_redirected_to edit_user_url(@user)
assert_nil session[:forwarding_url]
name = "Foo Bar"
email = "foo@bar.com"
...
end
end
[Day11]まとめ
- 学習範囲:10.2.1〜10.2.3
- 学習時間:1時間40分
- 総学習時間:46時間20分
- 反省点:家のシュレッダーをつまらせ、3時間以上時間を取られました。。反省。おかげで全然チュートリアルできなかった。
- 備考:特になし
シュレッダーを詰まらせて3時間無駄にしました😇
なおまだ直ってない😇
— 森タケシ (@rabotiku_sato) 2018年9月11日
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
コメントを残す