Rails 4: split routes.rb в несколько файлов меньшего размера
Я хотел бы разбить маршруты в приложении rails 4. Для рельсов 3 на вопрос был дан ответ несколько раз:
Каким будет правильный способ сделать это в rails 4 +, как получить контроль над порядком загрузки маршрутов?
Предлагаемый из рельсов 3 вопроса:
application.rb
config.paths['config/routes'] = Dir["config/routes/*.rb"]
Сбой:
/Users/jordan/.rvm/gems/[email protected]/gems/railties-4.0.0/lib/rails/application/routes_reloader.rb:10:in `rescue in execute_if_updated ': Rails:: Application:: RoutesReloader # execute_if_updated делегировано updater.execute_if_updated, но updater равен нулю:
@route_sets = [#] > (RuntimeError)
Ответы
Ответ 1
Это было удалено из Rails 4 в июне 2012 года. 5e7d6bba возвращает предыдущую фиксацию, удаляя поддержку для загрузки нескольких внешних файлов маршрутов в качестве часть config.rb.
Для дальнейшего ознакомления ознакомьтесь с комментариями к этому commit.
Ответ 2
Я справился так:
# config/application.rb
config.autoload_paths << Rails.root.join('config/routes')
# config/routes.rb
Rails.application.routes.draw do
root to: 'home#index'
extend ApiRoutes
end
# config/routes/api_routes.rb
module ApiRoutes
def self.extended(router)
router.instance_exec do
namespace :api do
resources :tasks, only: [:index, :show]
end
end
end
end
Здесь я добавил каталог config/routes
для модулей автозагрузки, определенных в нем.
Это обеспечит перезагрузку маршрутов при изменении этих файлов.
Используйте extend
, чтобы включить эти модули в основной файл (они будут автоматически загружены, не нужно их требовать).
Используйте instance_exec
внутри self.extended
для рисования маршрутов в контексте маршрутизатора.
Ответ 3
Немного поздно для вечеринки, но вы можете сделать это в Rails 4 обезьяной, исправляющей картупер вверху вашего файла route.rb. то есть:
# config/routes.rb
class ActionDispatch::Routing::Mapper
def draw(routes_name)
instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
end
end
И затем с помощью метода draw
в routes.rb с:
Rails.application.routes.draw do
draw :api
end
Это ожидает файл в config/routes/api.rb.
Немного более полное объяснение с примерами разделения файла маршрутов здесь.
Ответ 4
Мне не нравятся ранее опубликованные решения - расширения с помощью мартышек-патчей - поскольку они тоже:
- прервать ООП (
File.read
+ instance_eval
- крипы) или
- запретить повторное использование: включая модули - вы можете сделать это только один раз - не берите в голову, что на втором вы понимаете, что включение модуля на самом деле является механизмом для выполнения небольшого количества кода, крипы
мы больше не находимся в 2000-х, недопустимо перемещать части исходных файлов и File.read
- instance_eval
их, а затем задаться вопросом, что произошло - или включить модули в качестве вызова функции бедного человека - если есть любая альтернатива.
Я делаю это, обратите внимание, что это гнездо:
scope :processing do
SomeModule::SomeDomain::Routes.call(self)
end
# and it reusable:
scope :some_other_scope do
SomeModule::SomeDomain::Routes.call(self)
end
Преимущество этого подхода заключается в том, что в конечном итоге он представляет собой простой исполняемый код ruby, который может быть легко перемещен и понят как вашей IDE, так и вашими коллегами-программистами.
Вы найдете вышеупомянутый фрагмент кода в routes.rb
, посмотрите на него, щелкните его, удерживая клавишу , и вы обнаружите, что ожидали:
module SomeModule::SomeDomain
class Routes
def self.call r
r.scope :some_scope do
r.match .....
end
end
end
это означает, что это чистый код.
Он также не застрял в "функционально-ориентированной организации кода", которая, по-видимому, уже давно применяется, но позволяет создавать доменные структуры со своими собственными деревьями маршрутов, что должно быть предпочтительной нормой.
PS
Я также использую модуль module, который делает класс кряком похожим на функцию - допускает компоновку с процессорами и многое другое - но в этом нет особой необходимости, он просто даст вам синтаксическую конфету высказывания SomeModule::SomeDomain::Routes[self]