我有两个命名空间,每个都有自己的 Controller 和演示器类:
成员::DocumentsController
成员::DocumentPresenter
guest ::DocumentsController
Guest::DocumentPresenter
两个演示者都继承自 ::DocumentPresenter
。
Controller 在没有指定命名空间的情况下访问各自的演示者,例如:
class Guest::DocumentsController < ActionController::Base
def show
DocumentPresenter.new(find_document)
end
end
这通常会在同一个命名空间中调用演示者。但是有时在开发环境中我看到正在使用 base::DocumentPresenter。
我怀疑原因是 base::DocumentPresenter 已经加载,所以 Rails 类自动加载不会费心去进一步查看。这可能是这种情况吗?它也可以发生在生产环境中吗?
我可以想到两种解决方案:
- 将基类重命名为 DocumentPresenterBase
- 在 Controller 文件中明确要求适当的演示文件
有没有更好的解决方案?
最佳答案
你的假设是正确的 - 如果你没有指定命名空间,Ruby 从当前命名空间开始并向上寻找类,并且因为命名空间类还没有自动加载,::DocumentPresenter
找到并且自动加载器不触发。
作为解决方案 我建议将 ::DocumentPresenter
重命名为 DocumentPresenterBase
,因为当您忘记命名空间或显式要求时,这可以保护您免受错误的影响某处。
要考虑的第二个选项实际上是在所有地方使用特定的命名空间类名,但是当您不小心忘记为某些调用命名空间时,这会产生错误。
class Guest::DocumentsController < ActionController::Base
def show
Guest::DocumentPresenter.new(find_document)
end
end
第三个选项 将是您的第二个选项 - 事先明确要求初始化程序中的所有类。我已经使用 Rails 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 - 当加载根命名空间中的另一个同名类时,Rails 类加载会跳过命名空间类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13236083/