Using Pundit and getting Render and / or redirection called multiple times
I am getting the following error when the user is not allowed to view the authorization rules page using pundit:
Render and / or redirection was called multiple times in this action. Please note that you can only call render or redirection, and no more than once per action. Also note that neither the redirect nor the render completes the action, so if you want to exit the action after the redirect, you need to do something like "redirect_to (...) and return".
This is application_controller.rb :
class ApplicationController < ActionController::Base
# Includes Authorization mechanism
include Pundit
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
# Globally rescue Authorization Errors in controller.
# Returning 403 Forbidden if permission is denied
rescue_from Pundit::NotAuthorizedError, with: :permission_denied
# Enforces access right checks for individuals resources
# after_filter :verify_authorized, :except => :index
# Enforces access right checks for collections
# after_filter :verify_policy_scoped, :only => :index
private
def permission_denied
flash[:error] = "You don't have the proper permissions to view this page. If you think you are supposed to then please contact us at permissions@inrtracker.com"
# this is giving a redirect loop error
redirect_to(request.referrer || root_path)
end
end
stat_policy.rb
class StatPolicy
attr_reader :current_user, :model
def initialize(current_user, model)
@current_user = current_user
@stat = model
end
def index?
@current_user.admin?
end
end
stats_controller.rb:
class StatsController < ApplicationController
after_action :authorize_stat
def index
@stats = Stat.all
@stat = Stat.new
render layout: "stat_layout"
end
private
def authorize_stat
authorize @stat
end
# Use callbacks to share common setup or constraints between actions.
def set_stat
@stat = Stat.find(params[:id])
end
end
source to share
There's a strange order of operations that happens with after_action
. If you set the parameter to a response_body
value nil
, it should fix your problem.
def permission_denied
flash[:error] = "You don't have the proper permissions to view this page. If you think you are supposed to then please contact us at permissions@inrtracker.com"
self.response_body = nil # This should resolve the redirect root.
redirect_to(request.referrer || root_path)
end
source to share
As per Garrett's solution, the problem is with Turbolinks in combination with the Rails render thread. Rather than uninstalling Turbolinks, which is extremely useful, I suggest posting a:
data-turbolinks="false"
On links pointing to pages causing the problem. In my case, this only happened on pages with forms, such as "new" actions.
source to share