【问题标题】:Understanding moneky patched implementation of Pundit from Rails 3 to 4从 Rails 3 到 4 了解 Pundit 的货币补丁实现
【发布时间】:2021-07-12 12:05:56
【问题描述】:

作为我一直在做的迁移工作的一部分,我遇到了 pundit 的猴子补丁初始化。我大部分都理解它,但有一部分导致我出错:

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

启动服务器时出错:

/.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)

我尝试将此模块移动到concerns 文件夹,但如果我这样做,authorize 方法将不会被调用。

Pundit 模块我包含在 ApplicationController 中。

有什么想法吗?我知道我之前遇到过这个错误,我什至在这里描述了它,但这次我没有像其他文件一样命名空间。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 pundit


    【解决方案1】:

    我不确定这个monkeypatch 真正应该完成什么。但是避免错误的一种方法是不使用 ActiveSupport::Concern#included。相反,只需使用它抽象出来的实际 Ruby 钩子 (Module#included):

    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
    

    【讨论】:

    • 再次感谢!我不得不将def included 更改为def self.included
    猜你喜欢
    • 2015-08-15
    • 1970-01-01
    • 2011-03-26
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多