webアプリケーションで他人と投稿を編集したり消すことができたらまずいですよね。
そこで、ログイン機能において他者の投稿の編集や削除ができないようにするための処理を実装していきます。
この記事では簡単な掲示板サイトを想定して説明しております。
Messageモデルやmessagesコントローラーがあるとして、考えてみましょう。
$ rails g helper sessionsでhelperを用意して、current_userとlogged_in?を実装します。ここは、今回メインで解説する箇所ではないので、簡単な説明で留めておきます。
module SessionsHelper
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
def logged_in?
!!current_user
end
end
def current_userは、現在ログインしているユーザーを取得するメソッドです。
@current_user ||= User.find_by(id: session[:user_id])は
@current_userに現在のログインユーザーが代入されている場合 → 何もしません。
@current_userに現在のログインユーザーが代入されていない場合 → User.find_by(...) からログインユーザーを取得し、@current_userに代入します。
def logged_in?はユーザーがログインしている時はtrueを、ログインしていなければfalseを返します。
コントローラーについて考えていきます。
class MessagesController < ApplicationController
before_action :correct_user, only: [:edit, :destroy]
#中略
private
def correct_user
@message = current_user.messages.find_by(id: params[:id])
unless @message
redirect_back(fallback_location: root_path)
end
end
end
before_actionによって、editアクションとdestroyアクションが実行される前にcorrect_userメソッドが実行されます。
correct_userメソッドでは、編集もしくは削除をしようとしているMessageがログインユーザーが所有しているいるものかどうか、確認を行っています。
@message = current_user.messages.find_by(id: params[:id])は、ログインしているユーザーのMessages限定で検索をしています。
@messageが見つかった場合は、ここでは何も実行されず、editアクションやdestroyアクションが実行されます。
見つからなかったときは、unless @messageでnillを判定し、redirect_back(fallback_location: root_path)を実行します。
redirect_back(fallback_location: root_path)は、直前のページにリダイレクトしています。
例えば、message#indexで他者のMessageの編集をしたらmessage#indexに戻し、message#showで他者のMessageの削除をしたらmesssage#showに戻します。
unless @messageが実行された(直前のページへ戻した)際には、editアクションやdestroyアクションは実行されません。
このようにして、他の人が投稿したものを編集したり削除できないようする処理ができました。
以上です。
参照元
[直前のページにリダイレクト]
(https://railsdoc.com/page/redirect_back)