Я пытаюсь создать приложение RESTful для управления многими типами настраиваемых объектов, поэтому существует большое количество "ресурсных" типов и, следовательно, множество контроллеров. Я все еще на этапе POC, так что будет хорошо, если я смогу показать все контроллеры на первой странице навигации, поэтому любой простой способ (программируемый) сделать это?
Как программно перечислить все контроллеры в Rails
Ответ 1
В Rails 3.1 +:
Rails.application.routes
Это даст вам все контроллеры, действия и их маршруты, если у вас есть их пути в файле routes.rb.
Например:
routes= Rails.application.routes.routes.map do |route|
{alias: route.name, path: route.path, controller: route.defaults[:controller], action: route.defaults[:action]}
end
Обновление: Для Rails 3.2 изменился путь движка журнала, поэтому код будет выглядеть следующим образом:
routes= Rails.application.routes.routes.map do |route|
{alias: route.name, path: route.path.spec.to_s, controller: route.defaults[:controller], action: route.defaults[:action]}
end
Обновление:
Все еще работает для Rails 4.2.7. Чтобы извлечь список контроллеров (по фактическому вопросу), вы можете просто извлечь контроллер и uniq
controllers = Rails.application.routes.routes.map do |route|
route.defaults[:controller]
end.uniq
Ответ 2
ApplicationController.subclasses
Это поможет вам начать, но имейте в виду, что в режиме разработки вы не увидите многого, потому что он покажет только то, что на самом деле было загружено. Запустите его в режиме производства, и вы увидите список всех ваших контроллеров.
Ответ 3
Хотя метод @jdl будет работать в нескольких ситуациях, он не сработает, если у вас есть подклассы контроллера (например, ContactPageController
наследует от PageController
, который наследует от ApplicationController
).
Поэтому лучший способ - использовать:
::ApplicationController.descendants
Использование routes
может не сработать, если у вас есть сложное приложение, где части абстрагируются как движки, они будут скрыты.
Ответ 4
Мне особенно понравилось решение @jdl
ApplicationController.subclasses
Но в моем случае, когда мне действительно нужны все имена контроллеров в формате подчеркивания (у меня нет поддиректоров, например: /admin
), я использовал следующее:
Dir[Rails.root.join('app/controllers/*_controller.rb')].map { |path| path.match(/(\w+)_controller.rb/); $1 }.compact
Ответ 5
Google: "контроллеры списка рельсов"
Первый результат.
http://snippets.dzone.com/posts/show/4792
Узнав о подклассах, я думаю, что код из моей ссылки может быть выполнен просто как..
ApplicationController.subclasses.each do |c|
puts "Controller: #{c}"
puts "Actions: #{c.constantize.action_methods.collect{|a| a.to_s}.join(', ')}"
end
Ответ 6
Dir[Rails.root.join('app/controllers/*_controller.rb')].map { |path| (path.match(/(\w+)_controller.rb/); $1).camelize+"Controller" }
Это дает нам точное имя контроллера, как оно появляется в файле контроллера.
Ответ 7
Другое решение (если вы находитесь в Rails 5) и в разработке и необходимо сопоставить контроллеры и действия:
Rails.application.routes.set.anchored_routes.map(&:defaults)
При необходимости вы можете отклонить [: internal]:
.reject { |route| route[:internal] }