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)