Search code examples
ruby-on-railsbefore-filter

how to run two method in before_filter?


My code for post controller is as follows. What I'm trying to do is user should be able to delete his own posts, and admin_user can delete any posts. The following code make admin_user can delete posts, but for normal user, when trying to delete his own post, it redirect to root_path

It seems do_authentication doesn't work properly, a normal user is trying to be authenticated as an admin instead of "correct_user"

What could be wrong?

Thanks!

class PostsController < ApplicationController
  before_filter :signed_in_user, only: [:index, :create, :destroy]
  before_filter :do_authentication,  only: :destroy
  .
  .
  .
def destroy
  @post.destroy
  flash[:success] = "Post deleted!"
  redirect_back_or user_path(current_user)
end

private
  def do_authentication
    correct_user || admin_user
  end

  def correct_user
    @post = current_user.posts.find_by_id(params[:id])
    redirect_to user_path(current_user) if @post.nil?
  end

  def admin_user
    @post = Post.find_by_id(params[:id])
    redirect_to(root_path) unless current_user.admin?
  end

Solution

  • First of all I would suggest using cancan for authorization. I think your problem is the return value of correct_user. You don't control that. If that method returns something that evaluates to false the do_authentication method will also call admin_user. Also looking at your code it seems that the admin authorization won't work also ...

    try this:

    def do_authentication
      @post = Post.find_by_id(params[:id])
      redirect_to redirect_location unless current_user.admin? or @post.user == current_user
    end
    
    def redirect_location
      return "redirect_location_for_admin" if current_user.admin?
      return "redirect_location_for_non_admins"
    end