Это довольно просто на самом деле. Автозагрузчик rails не знает, что app/services/leader_board/fetch_board_members_service.rb
объявляет константу LeaderBoard::BoardType
и как это может быть?
Это не имеет ничего общего с тем фактом, что это "Enum", который на самом деле не вещь в Ruby. Это просто модуль, который объявляет несколько констант и, таким образом, ничем не отличается от любого другого модуля, это просто шаблон, который отдаленно напоминает типы enum в других языках, таких как C ++ и Java.
При поиске константы автозагрузчик делает предположения на основе местоположения файла и ожидает, что файл будет находиться в одном из путей автозагрузки. Пути загрузки в вашем среднем приложении rails - это каждый подкаталог /app
. Поэтому, когда вы ссылаетесь на LeaderBoard::BoardType
Rails ожидает, что он будет определен в /app/**/leader_board/board_type.rb
.
Как вы уже поняли, это работает, если вы уже ссылались на LeaderBoard::BoardType::FetchBoardMembersService
, поскольку app/services/leader_board/fetch_board_members_service.rb
уже требовалось.
Решение также простое: выложите свой код правильно. «root файл модуля» должен объявлять любые константы, которые не находятся в отдельных файлах.
# app/services/leader_board.rb
module LeaderBoard
module BoardType
TOTAL = 'total'.freeze
IN_SESSION = 'in_session'.freeze
GROUP = 'group'.freeze
end.freeze
end
# app/services/leader_board/fetch_board_members_service.rb
module LeaderBoard
class FetchBoardMembersService < BaseService
end
end
Это работает, так как Rails сначала "поднимет" вложенность модуля и автоматически загрузит "внешние модули". Это не только делает его автозагрузкой должным образом - это также помогает другим разработчикам найти код, так как это логичное место для поиска, если оно не определено в его собственном файле.