Hi Pundit Team, I know that this gem is technically not tied to Ruby on Rails, but I have a Ruby on Rails specific issue and am looking for some advice. When I use the after_filters provided by this gem, instead of neatly handling the issue as expected with the code provided in the README, I receive a DoubleRenderError.
1) CompaniesController GET 'index' returns http success
Failure/Error: get :index
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
# ./app/controllers/application_controller.rb:8:in `block in class:ApplicationController'
This is application controller, line 8 is the redirect_to line below:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
rescue_from Pundit::NotAuthorizedError do |exception|
redirect_to root_url, alert: exception.message, status: :forbidden #HTTP 403
@logged_in_user ||= current_admin || current_user
#pundit gem @OVERRIDE
My controller is very simple:
class BaseController < ApplicationController
after_filter :verify_authorized, :except => [:index, :home]
after_filter :verify_policy_scoped, :only => :index
@resources = infer_class_from_controller_name.scoped
#@resources = policy_scope(infer_class_from_controller_name) #does not cause the issue
@resources = @resources.page(params[:page])
@klass = infer_class_from_controller_name
@resource = @klass.find(params[:id])
class CompaniesController < BaseController
#just an empty controller that inherits all behavior from BaseController above
It seems that this after_filter doesn't work properly when included in an ActionController instance. Any thoughts? Me personally, I propose that the README be updated to not mention the two after_filters, and instead have the policy_scope and authorize methods raise Pundit::NotAuthorizedError directly inside of the controller methods. In the Rails controller action, if we raise the exception inside of the controller method, we would avoid the DoubleRenderError shown above.
I'll create a new pull request and link this issue so I can demonstrate what I'm referring to above with code.
Thanks for listening!
Hi Dan, thanks for asking. Could you try return redirect_to root_url .. and see if it makes any difference?
return redirect_to root_url ..
Hi @thomasklemm, I tried it just to see but it didn't change the error in my tests. The return is implied I believe. I think that during execution of this particular request the controller returned twice, once after the index action finished and again in the rescue_from block.
I think you're on the right track, this is something we should definitely solve.
I'll try to get a pull request put together and we can see what a potential solution could be. I love this gem and would like it to play nicely with Rails :)
@BigNerdRanchDan Did some research and tests in Rails 4. Could you see if the solution proposed in #53 works in for you, too?
As I mentioned in #53, I don't think this is really a problem. The verify_authorized filter is really only for development, and you probably should not catch this error and take action. If it ever occurs in production, you probably made a mistake and want this to throw a 500.
Perhaps updating the README to reflect this would help?