aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_dispatch/routing.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/inspector.rb127
-rw-r--r--actionpack/test/dispatch/routing/inspector_test.rb68
-rw-r--r--guides/source/routing.md2
-rw-r--r--railties/CHANGELOG.md19
-rw-r--r--railties/lib/rails/commands/routes/routes_command.rb8
-rw-r--r--railties/test/application/rake_test.rb40
-rw-r--r--railties/test/commands/routes_test.rb47
8 files changed, 232 insertions, 82 deletions
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 72f7407c6e..776058d98e 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -243,7 +243,8 @@ module ActionDispatch
#
# rails routes
#
- # Target specific controllers by prefixing the command with <tt>-c</tt> option.
+ # Target specific controllers by prefixing the command with <tt>-c</tt> option. Use
+ # <tt>--expanded</tt> to turn on the expanded table formatting mode.
#
module Routing
extend ActiveSupport::Autoload
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb
index 22336c59b6..8c0cf74667 100644
--- a/actionpack/lib/action_dispatch/routing/inspector.rb
+++ b/actionpack/lib/action_dispatch/routing/inspector.rb
@@ -126,61 +126,114 @@ module ActionDispatch
end
class ConsoleFormatter
- def initialize
- @buffer = []
- end
+ class Sheet
+ def initialize
+ @buffer = []
+ end
- def result
- @buffer.join("\n")
- end
+ def result
+ @buffer.join("\n")
+ end
- def section_title(title)
- @buffer << "\n#{title}:"
- end
+ def section_title(title)
+ @buffer << "\n#{title}:"
+ end
- def section(routes)
- @buffer << draw_section(routes)
- end
+ def section(routes)
+ @buffer << draw_section(routes)
+ end
- def header(routes)
- @buffer << draw_header(routes)
- end
+ def header(routes)
+ @buffer << draw_header(routes)
+ end
- def no_routes(routes)
- @buffer <<
- if routes.none?
- <<~MESSAGE
+ def no_routes(routes)
+ @buffer <<
+ if routes.none?
+ <<~MESSAGE
You don't have any routes defined!
Please add some routes in config/routes.rb.
- MESSAGE
- else
- "No routes were found for this controller"
+ MESSAGE
+ else
+ "No routes were found for this controller"
+ end
+ @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
end
- @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
- end
- private
- def draw_section(routes)
- header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
- name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
+ private
+
+ def draw_section(routes)
+ header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length)
+ name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
- routes.map do |r|
- "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
+ routes.map do |r|
+ "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
+ end
+ end
+
+ def draw_header(routes)
+ name_width, verb_width, path_width = widths(routes)
+
+ "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
+ end
+
+ def widths(routes)
+ [routes.map { |r| r[:name].length }.max || 0,
+ routes.map { |r| r[:verb].length }.max || 0,
+ routes.map { |r| r[:path].length }.max || 0]
end
+ end
+
+ class Expanded < ConsoleFormatter
+ def initialize
+ @buffer = []
end
- def draw_header(routes)
- name_width, verb_width, path_width = widths(routes)
+ def result
+ @buffer.join("")
+ end
+
+ def section_title(title)
+ @buffer << "\n#{"[ #{title} ]"}\n"
+ end
- "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action"
+ def section(routes)
+ @buffer << draw_expanded_section(routes)
end
- def widths(routes)
- [routes.map { |r| r[:name].length }.max || 0,
- routes.map { |r| r[:verb].length }.max || 0,
- routes.map { |r| r[:path].length }.max || 0]
+ def header(routes)
+ @buffer
end
+
+ def no_routes(routes)
+ @buffer <<
+ if routes.none?
+ <<~MESSAGE
+ You don't have any routes defined!
+
+ Please add some routes in config/routes.rb.\n
+ MESSAGE
+ else
+ "No routes were found for this controller\n"
+ end
+ @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
+ end
+
+ private
+
+ def draw_expanded_section(routes)
+ routes.map.each_with_index do |r, i|
+ <<~MESSAGE
+ --[ Route #{i + 1} ]#{'-' * 60}
+ Prefix | #{r[:name]}
+ Verb | #{r[:verb]}
+ URI | #{r[:path]}
+ Controller#Action | #{r[:reqs]}
+ MESSAGE
+ end
+ end
+ end
end
class HtmlTableFormatter
diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb
index 438a918567..127212b228 100644
--- a/actionpack/test/dispatch/routing/inspector_test.rb
+++ b/actionpack/test/dispatch/routing/inspector_test.rb
@@ -19,10 +19,10 @@ module ActionDispatch
@set = ActionDispatch::Routing::RouteSet.new
end
- def draw(options = nil, &block)
+ def draw(options = nil, formater = ActionDispatch::Routing::ConsoleFormatter::Sheet.new, &block)
@set.draw(&block)
inspector = ActionDispatch::Routing::RoutesInspector.new(@set.routes)
- inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options).split("\n")
+ inspector.format(formater, options).split("\n")
end
def test_displaying_routes_for_engines
@@ -321,6 +321,70 @@ module ActionDispatch
" DELETE /posts/:id(.:format) posts#destroy"], output
end
+ def test_routes_when_expanded
+ engine = Class.new(Rails::Engine) do
+ def self.inspect
+ "Blog::Engine"
+ end
+ end
+ engine.routes.draw do
+ get "/cart", to: "cart#show"
+ end
+
+ output = draw(nil, ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do
+ get "/custom/assets", to: "custom_assets#show"
+ get "/custom/furnitures", to: "custom_furnitures#show"
+ mount engine => "/blog", :as => "blog"
+ end
+
+ assert_equal ["--[ Route 1 ]------------------------------------------------------------",
+ "Prefix | custom_assets",
+ "Verb | GET",
+ "URI | /custom/assets(.:format)",
+ "Controller#Action | custom_assets#show",
+ "--[ Route 2 ]------------------------------------------------------------",
+ "Prefix | custom_furnitures",
+ "Verb | GET",
+ "URI | /custom/furnitures(.:format)",
+ "Controller#Action | custom_furnitures#show",
+ "--[ Route 3 ]------------------------------------------------------------",
+ "Prefix | blog",
+ "Verb | ",
+ "URI | /blog",
+ "Controller#Action | Blog::Engine",
+ "",
+ "[ Routes for Blog::Engine ]",
+ "--[ Route 1 ]------------------------------------------------------------",
+ "Prefix | cart",
+ "Verb | GET",
+ "URI | /cart(.:format)",
+ "Controller#Action | cart#show"], output
+ end
+
+
+ def test_no_routes_matched_filter_when_expanded
+ output = draw("rails/dummy", ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do
+ get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/
+ end
+
+ assert_equal [
+ "No routes were found for this controller",
+ "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
+ def test_not_routes_when_expanded
+ output = draw("rails/dummy", ActionDispatch::Routing::ConsoleFormatter::Expanded.new) {}
+
+ assert_equal [
+ "You don't have any routes defined!",
+ "",
+ "Please add some routes in config/routes.rb.",
+ "",
+ "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
+ ], output
+ end
+
def test_routes_can_be_filtered_with_namespaced_controllers
output = draw("admin/posts") do
resources :articles
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 1e75cbf362..98aa841938 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -1183,7 +1183,7 @@ $ bin/rails routes -c Comments
$ bin/rails routes -c Articles::CommentsController
```
-TIP: You'll find that the output from `rails routes` is much more readable if you widen your terminal window until the output lines don't wrap.
+TIP: You'll find that the output from `rails routes` is much more readable if you widen your terminal window until the output lines don't wrap. You can also use --expanded option to turn on the expanded table formatting mode.
### Testing Routes
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 51f6e1f0ac..a38888afe5 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,5 +1,24 @@
## Rails 6.0.0.alpha (Unreleased) ##
+* Add "rails routes --expanded" option to output routes in expanded mode like
+ "psql --expanded". Result looks like:
+
+ ```
+ $ rails routes --expanded
+ --[ Route 1 ]------------------------------------------------------------
+ Prefix | high_scores
+ Verb | GET
+ URI | /high_scores(.:format)
+ Controller#Action | high_scores#index
+ --[ Route 2 ]------------------------------------------------------------
+ Prefix | new_high_score
+ Verb | GET
+ URI | /high_scores/new(.:format)
+ Controller#Action | high_scores#new
+ ```
+
+ *Benoit Tigeot*
+
* Rails 6 requires Ruby 2.4.1 or newer.
*Jeremy Daer*
diff --git a/railties/lib/rails/commands/routes/routes_command.rb b/railties/lib/rails/commands/routes/routes_command.rb
index c4fd6c7eb5..c4f3717095 100644
--- a/railties/lib/rails/commands/routes/routes_command.rb
+++ b/railties/lib/rails/commands/routes/routes_command.rb
@@ -7,12 +7,14 @@ module Rails
class RoutesCommand < Base # :nodoc:
class_option :controller, aliases: "-c", type: :string, desc: "Specifies the controller."
class_option :grep_pattern, aliases: "-g", type: :string, desc: "Specifies grep pattern."
+ class_option :expanded_format, aliases: "--expanded", type: :string, desc: "Turn on expanded format mode."
no_commands do
def help
say "Usage: Print out all defined routes in match order, with names."
say ""
say "Target specific controller with -c option, or grep routes using -g option"
+ say "Use expanded format with --expanded option"
say ""
end
end
@@ -24,7 +26,11 @@ module Rails
all_routes = Rails.application.routes.routes
inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
- say inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, routes_filter)
+ if options.has_key?("expanded_format")
+ say inspector.format(ActionDispatch::Routing::ConsoleFormatter::Expanded.new, routes_filter)
+ else
+ say inspector.format(ActionDispatch::Routing::ConsoleFormatter::Sheet.new, routes_filter)
+ end
end
private
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index f7d301e125..9683230d07 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -122,46 +122,6 @@ module ApplicationTests
rails("stats")
end
- def test_rails_routes_calls_the_route_inspector
- app_file "config/routes.rb", <<-RUBY
- Rails.application.routes.draw do
- get '/cart', to: 'cart#show'
- end
- RUBY
-
- output = rails("routes")
- assert_equal <<~MESSAGE, output
- Prefix Verb URI Pattern Controller#Action
- cart GET /cart(.:format) cart#show
- rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
- rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show
- rails_blob_preview GET /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) active_storage/previews#show
- rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
- update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
- rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
- MESSAGE
- end
-
- def test_singular_resource_output_in_rake_routes
- app_file "config/routes.rb", <<-RUBY
- Rails.application.routes.draw do
- resource :post
- end
- RUBY
-
- expected_output = [" Prefix Verb URI Pattern Controller#Action",
- " new_post GET /post/new(.:format) posts#new",
- "edit_post GET /post/edit(.:format) posts#edit",
- " post GET /post(.:format) posts#show",
- " PATCH /post(.:format) posts#update",
- " PUT /post(.:format) posts#update",
- " DELETE /post(.:format) posts#destroy",
- " POST /post(.:format) posts#create\n"].join("\n")
-
- output = rails("routes", "-c", "PostController")
- assert_equal expected_output, output
- end
-
def test_logger_is_flushed_when_exiting_production_rake_tasks
add_to_config <<-RUBY
rake_tasks do
diff --git a/railties/test/commands/routes_test.rb b/railties/test/commands/routes_test.rb
index 030dcc7217..24af5de73a 100644
--- a/railties/test/commands/routes_test.rb
+++ b/railties/test/commands/routes_test.rb
@@ -119,6 +119,53 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
MESSAGE
end
+ test "test rails routes with expanded option" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get '/cart', to: 'cart#show'
+ end
+ RUBY
+
+ output = rails("routes", "--expanded")
+ assert_equal <<~MESSAGE, output
+ --[ Route 1 ]------------------------------------------------------------
+ Prefix | cart
+ Verb | GET
+ URI | /cart(.:format)
+ Controller#Action | cart#show
+ --[ Route 2 ]------------------------------------------------------------
+ Prefix | rails_service_blob
+ Verb | GET
+ URI | /rails/active_storage/blobs/:signed_id/*filename(.:format)
+ Controller#Action | active_storage/blobs#show
+ --[ Route 3 ]------------------------------------------------------------
+ Prefix | rails_blob_variation
+ Verb | GET
+ URI | /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format)
+ Controller#Action | active_storage/variants#show
+ --[ Route 4 ]------------------------------------------------------------
+ Prefix | rails_blob_preview
+ Verb | GET
+ URI | /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format)
+ Controller#Action | active_storage/previews#show
+ --[ Route 5 ]------------------------------------------------------------
+ Prefix | rails_disk_service
+ Verb | GET
+ URI | /rails/active_storage/disk/:encoded_key/*filename(.:format)
+ Controller#Action | active_storage/disk#show
+ --[ Route 6 ]------------------------------------------------------------
+ Prefix | update_rails_disk_service
+ Verb | PUT
+ URI | /rails/active_storage/disk/:encoded_token(.:format)
+ Controller#Action | active_storage/disk#update
+ --[ Route 7 ]------------------------------------------------------------
+ Prefix | rails_direct_uploads
+ Verb | POST
+ URI | /rails/active_storage/direct_uploads(.:format)
+ Controller#Action | active_storage/direct_uploads#create
+ MESSAGE
+ end
+
private
def run_routes_command(args = [])