Модули Rails как строгие пространства имен - PullRequest
0 голосов
/ 02 июля 2018

Я довольно новичок в рельсах, и я немного запутался, как модули работают здесь. У меня есть такая структура проекта:

# app/models/foo.rb
class Foo < ActiveRecord

# lib/external_service/foo.rb
module ExternalService
  class Foo

# lib/external_service/bar.rb
module ExternalService
  class Bar
    attribute :foo, Foo # not the model

Я работал со многими языками кодирования и раньше, и я ожидал, что легко будет использовать 'Foo' внутри Bar и ExternalService, но

LoadError: Невозможно автоматически загрузить константу Foo, ожидаемый lib / external_service / foo.rb для ее определения

ExternalService :: Foo обычно даже не виден вне ExternalService, но весь проект умирает от этой вещи

Я просто пропускаю что-то вроде «строгого режима» или что-то еще, чтобы убедиться, что я явно имею в виду ExternalService :: Foo внутри сервиса и не позволяю сервису убить мою модель?

Я знаю, что могу просто добавить модуль, но я хочу, чтобы код читался. Было бы хорошо, если бы кто-то мог помочь мне в этом случае :)

Спасибо

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

так что вы используете рельсы 4

если вы хотите создать модуль, сначала вам нужно импортировать или автоматически загрузить папку lib

например, в application.rb вы можете добавить папку lib в автозагрузку:

config.autoload_paths << Rails.root.join('lib')

после этого, поскольку вы используете rails, вы должны создать иерархию папок с именем в виде змеи в иерархии вашего модуля. например, если у вас есть:

module ExternalService
  class Foo
    ...
  end
end

Ваш файл foo.rb должен находиться в папке с именем 'external_service'

{{project_root}}/lib/external_service/foo.rb

иерархия папок является соглашением рельсов.

0 голосов
/ 18 ноября 2018

Хорошо, чтобы ответить на мой собственный вопрос .. Ruby ведет себя так же, и это совершенно нормально.

В этом случае Foo-модель уже загружена, поэтому ruby ​​предпочитает ее вместо локальной. Также в алфавитном порядке приложение / до lib /

Не очень красивое, но быстрое решение - просто назвать это так: attribute :foo, ExternalService::Foo

0 голосов
/ 02 июля 2018
...