我有两个 namespace ,每个 namespace 都有自己的 Controller 和Presenter类:Member::DocumentsControllerMember::DocumentPresenterGuest::DocumentsControllerGuest::DocumentPresenter
两位演示者都从::DocumentPresenter继承。

Controller 在未指定 namespace 的情况下访问其各自的演示者,例如:

class Guest::DocumentsController < ActionController::Base
    def show
        DocumentPresenter.new(find_document)
    end
end

这通常在同一 namespace 中调用presenter。但是有时在开发环境中,我看到正在使用基本:: DocumentPresenter。

我怀疑原因是基本:: DocumentPresenter已经加载,所以Rails类的自动加载不会费心寻找。可能是这样吗?它也可以在生产环境中发生吗?

我可以想到两种解决方案:
  • 将基类重命名为DocumentPresenterBase
  • 在 Controller 文件
  • 中明确要求适当的演示者文件

    有更好的解决方案吗?

    最佳答案

    您的假设是正确的-如果您未指定 namespace ,则Ruby从当前 namespace 开始并逐步查找该类,并且由于尚未自动加载该 namespace 的类,因此会找到::DocumentPresenter且不会触发自动加载器。

    作为解决方案,我建议将::DocumentPresenter重命名为DocumentPresenterBase,因为当您忘记命名空间或明确要求某个地方时,这可以保护您免受错误的侵害。

    要考虑的第二个选项实际上实际上会在各处使用特定的命名空间类名,但是当您不小心忘记对某些调用命名空间时,这会遇到一些bug。

    class Guest::DocumentsController < ActionController::Base
      def show
        Guest::DocumentPresenter.new(find_document)
      end
    end
    

    第三个选项是您的第二个选项-事先明确要求初始化器中的所有类。我已经用Rails API做到了这一点,该API接收JSON中的嵌入式模型,并且当尚未加载实际模型时,Rails倾向于为其命名空间。

    选项3.5 您可能会欺骗自动装带器来完成繁重的工作(尽管这似乎更像是一个hack):
    class Guest::DocumentsController < ActionController::Base
    
      # trigger autoload
      Guest::DocumentPresenter
    
      def show
        # This should refer Guest::DocumentPresenter
        DocumentPresenter.new(find_document)
      end
    
      def show
        # As will this
        DocumentPresenter.new(find_document)
      end
    end
    

    仍然最干净的方法是重命名基类。

    关于ruby-on-rails - 当加载根 namespace 中的另一个同名类时,Rails类的加载会跳过命名空间类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13236083/

    10-14 15:49