Как программно перечислить все контроллеры в Rails

Я пытаюсь создать приложение RESTful для управления многими типами настраиваемых объектов, поэтому существует большое количество "ресурсных" типов и, следовательно, множество контроллеров. Я все еще на этапе POC, так что будет хорошо, если я смогу показать все контроллеры на первой странице навигации, поэтому любой простой способ (программируемый) сделать это?

Ответ 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] }