[ACCEPTED]-How to programmatically list all controllers in Rails-ruby-on-rails

Accepted answer
Score: 45

In Rails 3.1+:

Rails.application.routes

This will give you all the 7 controllers, actions and their routes if 6 you have their paths in your routes.rb file.

For 5 example:

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

Update: For Rails 3.2, Journal engine 4 path changed, so the code becomes:

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

Update: Still 3 working for Rails 4.2.7. To extract the 2 list of controllers (per actual question), you 1 can simply extract the controller and uniq

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

It'll get you started, but keep in mind 4 that in development mode you won't see much, because 3 it will only show you what's actually been 2 loaded. Fire it up in production mode, and 1 you should see a list of all of your controllers.

Score: 11

While @jdl's method will work in a number 6 of situations it fails if you have controller 5 subclasses (e.g. ContactPageController inherits from PageController which inherits 4 from ApplicationController) .

Therefore a better method is to 3 use:

::ApplicationController.descendants

Using routes may not work if you have a complex 2 app where parts are abstracted as engines, these 1 will be hidden.

Score: 9

I particularly liked @jdl solution

ApplicationController.subclasses

But in 3 my case, where I really needed all the controller 2 names in underscore format (I don't have 1 subdirs eg: /admin) I used the following:

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

Google: 'rails list controllers'

First result.

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


After 2 learning about the subclasses, I think the 1 code from my link could be done simply as..

ApplicationController.subclasses.each do |c|
  puts "Controller: #{c}"
  puts "Actions: #{c.constantize.action_methods.collect{|a| a.to_s}.join(', ')}"
end
Score: 3

Another solution (if you're in Rails 5) and 3 in Development and need to map controllers 2 and actions:

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

You can reject [:internal] if 1 needed:

.reject { |route| route[:internal] }
Score: 2
Dir[Rails.root.join('app/controllers/*_controller.rb')].map { |path| (path.match(/(\w+)_controller.rb/); $1).camelize+"Controller" }

This gives us the exact name of the controller 1 as it appears within the controller file.

More Related questions