Rails 7.1 adds routes --unused option to detect extraneous routes
Rails routes are essential for mapping URLs to specific actions, controllers, and views in your application. As your Rails app grows, more and more routes get added. However, some routes may become obsolete or irrelevant as your application evolves or undergoes refactoring. It is essential to keep your routes up to date to ensure efficient and accurate URL handling.
When adding a new controller to a Rails app,
developers often add the resources
directive to the routes file.
This directive creates all seven default actions for the controller,
even if the application only needs a few of them.
The unused actions
and
routes will remain in the application unless the developer
adds the except
or only
option to the resources
directive.
Before Rails 7.1
No built-in method was available in Rails to detect unused routes before Rails 7.1 However, you could use a few third-party gems and scripts for this purpose.
-
traceroute gem: One option was to use the traceroute gem. This gem would print a list of all the routes in your application, and any unreachable action methods.
-
rake routes: Another option was to run the
rake routes
command and manually remove any routes you did not use. -
Custom Script: You could also create a script to extract your application's unused routes.
unused_routes = {}
Rails.application.routes.routes.each do |r|
name = r.requirements[:controller].to_s.camelize
action = r.requirements[:action].to_s
controller = "#{name}Controller"
if Object.const_defined?(controller) && !controller.constantize.new.respond_to?(action)
unless Dir.glob(Rails.root.join("app", "views", name.downcase, "#{action}.*")).any?
unused_routes[controller] = [] if unused_routes[controller].nil?
unused_routes[controller] << action
end
end
end
unused_routes
The script currently only checks if the view files are present
or
not.
It must be modified to handle cases where the route is defined,
but the controller is missing from the application.
Using the Object.const_defined?
method,
you can check if the controller class exists.
If the controller class does not exist,
the route is considered to be unused.
In Rails 7.1
Rails made it easy to identify the unused route.
Rails 7.1 adds --unused option to rake routes command to identify extraneous routes. You must execute the below command on your terminal to get your application's list of unused routes.
> bin/rails routes --unused
# An example output of the above command will be as below:
Found 2 unused routes:
Prefix Verb URI Pattern Controller#Action
get_token GET /get_token(.:format) users#get_token
upgrade_token GET /upgrade_token(.:format) users#upgrade_token
If the application has no unused routes, the output will be:
> bin/rails routes --unused
No unused routes found.
You can also add the grep -g
option to filter the
unused routes result.
If your application has a lot of unused routes
and
you want to verify if the particular action
or
the controller is unused,
you can pass the -g
option as below:
> bin/rails routes --unused -g upgrade_token
Found 1 unused route:
Prefix Verb URI Pattern Controller#Action
upgrade_token GET /upgrade_token(.:format) users#upgrade_token
If there are no unused routes when filtered by the -g
command,
we see the following message:
> bin/rails routes --unused -g degrade_token
No unused routes found for this grep pattern.
You can filter unused routes by passing the controller name
using the -c
option.
The unused routes command with the -c
option works
similarly to the -g
command.
If unused routes associated with that controller are present,
they will be displayed
else;
no unused routes for this controller message get rendered.
> bin/rails routes --unused -c users
Found 2 unused routes:
Prefix Verb URI Pattern Controller#Action
get_token GET /get_token(.:format) users#get_token
upgrade_token GET /upgrade_token(.:format) users#upgrade_token
> bin/rails routes --unused -c random
No unused routes found for this controller.
This feature to detect unused routes in Rails will be very helpful for large and legacy applications. The feature will not significantly affect the boot time or performance of the application, but it will help to remove dead code.
This feature is handy when adding a new controller to an application. By detecting unused routes, you can ensure your application is clean and contains no dead code. This helps prevent confusion when working with large route files.
To know more about this feature, please refer to this PR.