before_actionを特定の場所に効かせるために
初めに
- application_controllerで以下のものを定義して、ログインしていないユーザーに対してアクセス制限をかけるようにした。
def authenticate_user if @current_user == nil flash[:notice] = "ログインが必要です" redirect_to("/login") end end
- 今回はposts_controllerの全てのアクション、users_controllerのindex,show,update,editアクションのみに制限をかけたい
問題
- アクセス制限をかけたくないhomes_controllerのtop,aboutアクションにもアクセス制限がかかっていた。
コード
application_controller
class ApplicationController < ActionController::Base before_action :set_current_user before_action:authenticate_user def set_current_user @current_user = User.find_by(id: session[:user_id]) end def authenticate_user if @current_user == nil flash[:notice] = "ログインが必要です" redirect_to("/login") end end end
posts_controller
class PostsController < ApplicationController before_action :authenticate_user def index @posts = Post.all.order(created_at: :desc) end def show @post = Post.find_by(id: params[:id]) end def new @post = Post.new end def create @post = Post.new(content: params[:content]) if @post.save flash[:notice] = "投稿を作成しました" redirect_to("/posts/index") else render("posts/new") end end def edit @post = Post.find_by(id: params[:id]) end def update @post = Post.find_by(id: params[:id]) @post.content = params[:content] if @post.save flash[:notice] = "投稿を編集しました" redirect_to("/posts/index") else render("posts/edit") end end def destroy @post = Post.find_by(id: params[:id]) @post.destroy flash[:notice] = "投稿を削除しました" redirect_to("/posts/index") end end
users_controller
class UsersController < ApplicationController before_action :authenticate_user ,{only:[:index,:show,:edit,:update]} def index @users = User.all end def show @user = User.find_by(id: params[:id]) end def new @user = User.new end def create @user = User.new( name: params[:name], email: params[:email], image_name:"default_user.jpg", password: params[:password] ) if @user.save session[:user_id] = @user.id flash[:notice] = "ユーザー登録が完了しました" redirect_to("/users/#{@user.id}") else @email = params[:email] @password = params[:password] @name = params[:name] render("users/new") end end def edit @user = User.find_by(id: params[:id]) end def update @user = User.find_by(id: params[:id]) @user.name = params[:name] @user.email = params[:email] if params[:image] @user.image_name = "#{@user.id}.jpg" image = params[:image] File.binwrite("public/user_images/#{@user.image_name}",image.read) end if @user.save flash[:notice] = "ユーザー情報を編集しました" redirect_to("/users/#{@user.id}") else render("users/edit") end end def login_form end def login @user = User.find_by(password: params[:password], email: params[:email]) if @user session[:user_id] = @user.id flash[:notice] = "ログインしました" redirect_to("/posts/index") else @email = params[:email] @password = params[:password] @error_message = "メールアドレスまたはパスワードが間違っています" render("users/login_form") end end def logout session[:user_id] = nil flash[:notice] = "ログアウトしました" redirect_to("/login") end end
home_controller
class HomeController < ApplicationController def top end def about end end
原因
application_controllerでbefore_action:authenticate_userを定義しているために全てのcontrollerにアクセス制限をかけてしまっていた。
application_controllerでbefore_action:authenticate_userを削除してアクセス制限をかけたいcontrollerでbefore_action:authenticateを定義する。
結語
application_controllerでbefore_actionを定義してしまうと全てのcontrollerに影響を与えてしまう
application_controllerで定義したメソッドは他のcontrollerで利用できるので 今回はアクセス制限をかけたいcontroller内でbefore_actionを定義しなくてはいけない。