Rails 4: организовать модели рельсов в подпутье без моделей пространства имен?

80

Возможно ли такое?

app/models/
app/models/users/user.rb
app/models/users/education.rb

Цель состоит в том, чтобы лучше организовать папку / app / models , но без необходимости создавать пространство имен для моделей.

Вопрос без ответа для Rails 3 находится здесь: Rails 3.2.9 и модели во вложенных папках .

Кажется, что указание table_name с пространствами имен работает (см. Подпапку модели Rails 4 ), но я хочу сделать это без пространства имен .

Рубитастик
источник
Я понял, что вам не нужно пространство имен, но я думаю, что лучший способ сделать это - использовать ActiveSupport Concerns.
Nando Sousa
2
@NandoSousa. Нет. ActiveSupport касается общего поведения. Как вы используете модели.
Berkes

Ответы:

116

По умолчанию Rails не добавляет вложенные папки каталога моделей в путь автозагрузки. Вот почему он может находить только модели с именами - пространство имен освещает подкаталог для поиска.

Чтобы добавить все подпапки app / models в путь автозагрузки, добавьте в config / application.rb следующее :

config.autoload_paths += Dir[Rails.root.join("app", "models", "{*/}")]

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

config.autoload_paths += Rails.root.join("app", "models", "<my_subfolder_name1>")
config.autoload_paths += Rails.root.join("app", "models", "<my_subfolder_name2>")

ОБНОВЛЕНИЕ для Rails 4.1+

Начиная с Rails 4.1, генератор приложений config.autoload_pathsпо умолчанию не включает . Итак, обратите внимание, что приведенное выше действительно относится к config / application.rb .

ОБНОВИТЬ

Исправлены примеры пути автозагрузки в приведенном выше коде для использования {*/}вместо {**}. Обязательно прочтите комментарий Мючкина, чтобы узнать подробности об этом.

pdobb
источник
6
Пробовал, но не получается из-за невозможности автозагрузки константы User :: Credits, ожидалось, что /srv/books/app/models/user/credits.rb его определит. Так что имена файлов по-прежнему не должны быть разделены. Поместите их над записью библиотеки, как предлагается.
Rubytastic
1
Эта ошибка на самом деле хорошая новость. Значит файл нашел. Но здесь вы используете нечетное множественное число. Если имя файла , app/models/user/credits.rbто убедитесь , что имя класса в файле также во множественном числе class Credits. Но я бы рекомендовал использовать стандарт Rails и сделать его class Creditи имя файла таким app/models/user/credit.rb(модели должны быть в единственном числе). В любом случае, это должно быть проблемой. Дай мне знать!
pdobb
1
В конфиге Rails 4.1, который я используюconfig.autoload_paths += %W( #{Rails.root}/app/models/namespace #{Rails.root}/app/models/other_namespace )
Epigene 02
14
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]работает, но замедляет работу приложения, особенно в режиме разработки, когда приложение часто перезагружается. Причина в том, что вы не должны добавлять все файлы в autoload_paths, а только в корневые папки, из которых могут быть выведены имена файлов и модули. Проще говоря, если у вас есть только один уровень подпапок в моделях и нет моделей пространств имен, вы должны делать только то, config.autoload_paths += Dir[Rails.root.join('app', 'models', '*/')]что добавляет только первый уровень подкаталогов. То же самое для libдругих путей.
muichkine
3
@pdobb это опыт :) если вы посмотрите, как работает автоматическая загрузка, вы увидите, что она вообще зацикливается, auto_loading_pathsк чему добавляет логический вывод для модели. Например, если он у вас есть, NameSpace::Modelон попытается найти во всех autoloading_paths файл path/namespace/model. Очевидно, это может совпадать только тогда, когда pathэто каталог. Как правило, autoload_pathsдля максимальной эффективности вы должны иметь только каталоги в . Надеюсь, поможет.
muichkine