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.
Nando Sousa,

2
@NandoSousa. Ні. Проблеми ActiveSupport стосуються спільної поведінки. Те, як ви використовуєте моделі.
berkes

Відповіді:


116

За замовчуванням Rails не додає підпапки каталогу model до шляху автоматичного завантаження. Ось чому він може знаходити лише моделі з простором імен - простір імен підсвічує підкаталог для пошуку.

Щоб додати всі підпапки програми / моделей до шляху автозавантаження, додайте в config / application.rb таке :

config.autoload_paths += Dir[Rails.root.join("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 .

ОНОВЛЕННЯ

Виправлені приклади шляху автоматичного завантаження у наведеному вище коді для використання {*/}замість {**}. Не забудьте прочитати коментар muichkine для детальної інформації про це.


6
Спробував, але не вдається, оскільки не вдається автоматично завантажити константу User :: Credits, очікується /srv/books/app/models/user/credits.rb для її визначення. Таким чином, все ще не потрібно, щоб файли були названі з інтервалом. Розмістіть їх над записом lib, як запропоновано.
Rubytastic

1
Ця помилка насправді є хорошою новиною. Це означає, що він знайшов файл. Але ви використовуєте тут дивну плюралізацію. Якщо ім'я файлу , app/models/user/credits.rbто переконаєтеся , що ім'я класу в файлі також у множині class Credits. Але я б рекомендував використовувати стандарт Rails і зробити його, class Creditа також ім'я файлу app/models/user/credit.rb(моделі повинні бути в однині). У будь-якому випадку, це має бути проблемою. Дай мені знати!
pdobb

1
У Rails 4.1 config я використовуюconfig.autoload_paths += %W( #{Rails.root}/app/models/namespace #{Rails.root}/app/models/other_namespace )
Epigene

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 a path/namespace/model. Очевидно, це може збігатися лише тоді, коли pathє каталог. Як правило, autoload_pathsдля максимальної ефективності у вас повинні бути лише каталоги . Сподіваюся, це допоможе.
muichkine
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.