代码之家  ›  专栏  ›  技术社区  ›  Dave

在Rails5中,如何从已定义的模块继承?

  •  0
  • Dave  · 技术社区  · 5 年前

    我使用的是rubyonrails5。我已经在lib/audit/top\u级别创建了这个基类_服务.rb

    module Audit::Services
      class TopLevelService
        ...
      end
    end
    

    在我的应用程序的另一部分,app/services/accounting_服务.rb,我想从上面创建的这个模块继承,所以我尝试了

    class AccountingService < Audit::Services::TopLevelService
    ...
    end
    

    但这会导致“uninitialized constant Audit::Services”错误。从普通类定义中引用基类的正确方法是什么?

    0 回复  |  直到 5 年前
        1
  •  0
  •   Igor Kapkov    5 年前

    原因是 Autoloading and Reloading Constants . 当你尝试访问 PerkspotService 它没有 Audit::Services 而且没有文件 audit/services.rb . 有多种方法可以解决它。您可以在中预定义名称空间 application.rb 这样地:

    Audit = Module.new
    Audit::Services = Module.new
    

    你可以试着包起来 Perkspot服务 在命名空间中,例如:

    module Audit::Services
      class PerkspotService < TopLevelService
      ...
      end
    end
    

    最后,可以说正确的方法是遵循所提供链接中描述的规则。您需要将文件路径与定义名称匹配。所以你 Audit::Services::TopLevelService 必须是名为的文件: audit/services/top_level_service.rb 在其中一个自动加载文件夹中。

        2
  •  0
  •   max Mike Williams    5 年前

    只要把它定义为 正确的方法 相反。

    # lib/audit/services/top_level_service.rb
    module Audit
      module Services
        class TopLevelService
        end
      end
    end
    

    不要使用范围解析运算符 :: 定义模块或类时!它没有创建正确的模块嵌套,结果可能非常令人吃惊。TopLevelService中的嵌套实际上是 ::Audit 而不是 ::Audit::Services . 它也会爆炸如果 Audit::Services 尚未加载。

    把它放在 lib/audit/services/top_level_service.rb 让自动加载程序只加载提供的文件 lib 在自动加载路径中。