namespace :routes do desc 'Print out all defined routes in match order, with names, per constraint class. Target specific constraint class with CONSTRAINT=x. Target specific controller with CONTROLLER=x.' task constrained: :environment do Rails.application.reload_routes! constraints_routes = Hash.new Rails.application.routes.routes.each do |route| group = (route.app.class == ActionDispatch::Routing::Mapper::Constraints ? route.app.send( :constraints ).first.to_s : 'No constraint class') constraints_routes[group] ||= [] constraints_routes[group] << route end requested_constraint = ENV[ 'CONSTRAINT' ] constraints_routes.each do |group, all_routes| if requested_constraint.nil? or group == requested_constraint puts "\n\nConstraint class : #{group}\n\n" if ENV[ 'CONTROLLER' ] all_routes = all_routes.select { |route| route.defaults[ :controller ] == ENV[ 'CONTROLLER' ] } end routes = all_routes.collect do |route| reqs = route.requirements.dup reqs[ :to ] = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/ reqs = reqs.empty? ? '' : reqs.inspect {name: route.name.to_s, verb: route.verb.source.gsub( /[\^\$]/, '' ), path: route.path, reqs: reqs} end routes.reject! { |r| r[ :path ].spec.to_s =~ %r{/rails/info/properties|/assets} } # Skip the route if it's internal route name_width = routes.map { |r| r[ :name ].length }.max verb_width = routes.map { |r| r[ :verb ].length }.max path_width = routes.map { |r| r[ :path ].spec.to_s.length }.max routes.each do |r| puts "#{r[ :name] .rjust( name_width )} #{r[ :verb ].ljust( verb_width )} #{r[ :path ].spec.to_s.ljust( path_width )} #{r[ :reqs ]}" end end end end end