ruby-on-railsrubyruby-on-rails-4pundit

Understanding moneky patched implementation of Pundit from Rails 3 to 4


As part of this migration work I have been doing, I came across a monkey patched initialization of pundit. I'm understanding it for the most part but there is a part that is causing me errors:

module Pundit

  class << self
    def authorize; raise 'DoNotUseThisMethod'; end
    def authorize!; raise 'DoNotUseThisMethod'; end
  end

  included do
    if respond_to?(:rescue_from)
      rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
    end

    if respond_to?(:helper_method)
      helper_method :authorize
      helper_method :can?
    end
  end

  protected

  ... 
  # authorize, authorize! and other methods defined

Error when bring the server up:

/.rvm/gems/ruby-2.3.3/gems/activesupport-4.2.11.3/lib/active_support/concern.rb:126:in `included': Cannot define multiple 'included' blocks for a Concern (ActiveSupport::Concern::MultipleIncludedBlocks)

I tried moving this module to the concerns folder, but if I do that, the authorize methods are not called.

The Pundit module I included on the ApplicationController.

Any ideas? I know I've had this error before and I've even described it here but in this time I'm not namespacing as the other files.


Solution

  • I'm not sure what this monkeypatch is really supposed to accomplish. But one way of avoiding the error is by not using ActiveSupport::Concern#included. Instead just use the actual Ruby hook (Module#included) that it abstracts away:

    module Pundit
    
      class << self
        def authorize; raise 'DoNotUseThisMethod'; end
        def authorize!; raise 'DoNotUseThisMethod'; end
    
        def self.included(base)
          base.class_eval do
            if respond_to?(:rescue_from)
              rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
            end
    
            if respond_to?(:helper_method)
              helper_method :authorize
              helper_method :can?
            end
         end
        end
      end
    end