Search code examples
ruby-on-railsruby-on-rails-4model-view-controllerauthorizationpundit

Redirect to specific view if Pundit not authorized for show action


I have the following action for my proposals controller:

      def show
        @proposal = Proposal.find(params[:id])
        authorize @proposal
      end

I have the following policy:

class ProposalPolicy
  attr_reader :current_user, :proposal

How can I redirect to a specific page. Say index proposals or root page if the permission is denied when trying to go to the show page?

When I navigate to it without the right permission I just get a rails error page with the following:

not allowed to show? this<proposal OBJ ispsum lorem>

I just want them to have a simple notification and redirected to another page. What is best way to do this? I am guessing with some sort of if statement in the show view but nothing has worked so far.

  def initialize(current_user, proposal)
    @current_user = current_user
    @proposal = proposal
  end

  def show?
    @proposal.published? or @proposal.proposer == @current_user
  end
end

Solution

  • Pundit has a mechanism for this. You'll create a private method in your controller called user_not_authorized - in it you'll be able to create a flash notification and add a location.

    class ApplicationController < ActionController::Base
      protect_from_forgery
      include Pundit
    
      rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
    
      private
    
      def user_not_authorized
        flash[:alert] = "You are not authorized to perform this action."
        redirect_to(request.referrer || root_path)
      end
    end
    

    More information here: https://github.com/elabs/pundit#rescuing-a-denied-authorization-in-rails