Cómo enumerar programáticamente todos los controladores en Rails

Estoy tratando de construir una aplicación RESTful para administrar realmente muchos tipos de objetos configurables, por lo que hay una gran cantidad de tipos de “recursos” y, por lo tanto, una gran cantidad de controladores. Todavía estoy en la fase POC, por lo que sería bueno si puedo mostrar todos los controladores en una primera página de navegación, por lo que cualquier forma fácil (progtwigble) para hacer eso?

En Rails 3.1+:

Rails.application.routes 

Esto le dará todos los controladores, acciones y sus rutas si tiene sus rutas en su archivo routes.rb.

Por ejemplo:

 routes= Rails.application.routes.routes.map do |route| {alias: route.name, path: route.path, controller: route.defaults[:controller], action: route.defaults[:action]} end 

Actualización: para Rails 3.2, la ruta del motor de Journal cambió, por lo que el código se convierte en:

 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 

Actualización: sigue trabajando para Rails 4.2.7. Para extraer la lista de controladores (por pregunta real), simplemente puede extraer el controlador y uniq

 controllers = Rails.application.routes.routes.map do |route| route.defaults[:controller] end.uniq 
 ApplicationController.subclasses 

Te ayudará a empezar, pero ten en cuenta que en el modo de desarrollo no verás mucho, porque solo te mostrará lo que se ha cargado realmente. Enciéndalo en modo de producción, y debería ver una lista de todos sus controladores.

Si bien el método de @ jdl funcionará en una serie de situaciones, falla si tiene subclases de controlador (por ejemplo, ContactPageController hereda de PageController que hereda de ApplicationController ).

Por lo tanto, un mejor método es usar:

 ::ApplicationController.descendants 

El uso de routes puede no funcionar si tiene una aplicación compleja donde las partes se abstraen como motores, estas se ocultarán.

Me gustó especialmente la solución @jdl

 ApplicationController.subclasses 

Pero en mi caso, donde realmente necesitaba todos los nombres de controlador en formato de guión bajo (no tengo subdirectores, por ejemplo: /admin ) utilicé lo siguiente:

 Dir[Rails.root.join('app/controllers/*_controller.rb')].map { |path| path.match(/(\w+)_controller.rb/); $1 }.compact 

Google: ‘controladores de listas de Rails’

Primer resultado

http://snippets.dzone.com/posts/show/4792


Después de aprender sobre las subclases, creo que el código de mi enlace podría hacerse simplemente como …

 ApplicationController.subclasses.each do |c| puts "Controller: #{c}" puts "Actions: #{c.constantize.action_methods.collect{|a| a.to_s}.join(', ')}" end 
 Dir[Rails.root.join('app/controllers/*_controller.rb')].map { |path| (path.match(/(\w+)_controller.rb/); $1).camelize+"Controller" } 

Esto nos da el nombre exacto del controlador tal como aparece en el archivo del controlador.

Otra solución (si está en Rails 5) y en Desarrollo y necesita asignar controladores y acciones:

 Rails.application.routes.set.anchored_routes.map(&:defaults) 

Puede rechazar [: interno] si es necesario:

 .reject { |route| route[:internal] }