В Rails 5, как мне наследовать от модуля, который я определил? - PullRequest
0 голосов
/ 18 марта 2020

Я использую Ruby в Rails 5. Я создал этот базовый класс в lib / audit / top_level_service.rb

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

В другой части моего приложения, app / services / accounting_service. rb, я хотел бы наследовать от этого модуля, который я создал выше, поэтому я попытался

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

, но это приводит к ошибке «неинициализированная константа Audit :: Services». Как правильно ссылаться на мой базовый класс из моего обычного определения класса?

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Просто определите его вместо .

# 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 находится в путях автозагрузки.

0 голосов
/ 18 марта 2020

Причина этого Константы автозагрузки и перезагрузки . Когда вы пытаетесь получить доступ к PerkspotService, у него нет Audit::Services и нет файла audit/services.rb. Есть несколько способов решить эту проблему. Вы можете предопределить пространства имен в application.rb следующим образом:

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

Вы можете попытаться обернуть PerkspotService в пространство имен, например:

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

Наконец, и, возможно, правильный способ сделать это должно следовать правилам, описанным в предоставленной ссылке. Вам нужно будет сопоставить путь к файлу с именем определения. Таким образом, Audit::Services::TopLevelService должен быть файлом с именем: audit/services/top_level_service.rb в одной из папок автозагрузки.

...