Kevin Yu
Kevin Yu

Reputation: 1473

How to programmatically list all controllers in Rails

I'm trying to build a RESTful app to actually manage many kind of configurable objects, so there are a large amount of "resource" types, and hence a lot of controllers. I'm still at the POC phase, so it will be nice if I can show all controllers in a first navigation page, so any easy way (programmable) to do that?

Upvotes: 33

Views: 22858

Answers (7)

nurettin
nurettin

Reputation: 11756

In Rails 3.1+:

Rails.application.routes

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

For 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 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 working for Rails 4.2.7. To extract the list of controllers (per actual question), you can simply extract the controller and uniq

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

Upvotes: 45

arzezak
arzezak

Reputation: 31

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

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

You can reject [:internal] if needed:

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

Upvotes: 3

Kiran Chamarthi
Kiran Chamarthi

Reputation: 21

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 as it appears within the controller file.

Upvotes: 2

ecoologic
ecoologic

Reputation: 10430

I particularly liked @jdl solution

ApplicationController.subclasses

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

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

Upvotes: 8

Jakub Hampl
Jakub Hampl

Reputation: 40563

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

Therefore a better method is to use:

::ApplicationController.descendants

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

Upvotes: 10

Jim
Jim

Reputation: 5617

Google: 'rails list controllers'

First result.

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


After learning about the subclasses, I think the 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

Upvotes: 4

jdl
jdl

Reputation: 17790

ApplicationController.subclasses

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

Upvotes: 30

Related Questions