diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index b6225cd8c0..8b525ae86e 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -254,7 +254,12 @@ module Rails # Make an entry in Rails routing file config/routes.rb # # route "root 'welcome#index'" - def route(routing_code) + # route "root 'admin#index'", namespace: :admin + def route(routing_code, namespace: nil) + routing_code = Array(namespace).reverse.reduce(routing_code) do |code, ns| + "namespace :#{ns} do\n#{indent(code, 2)}\nend" + end + log :route, routing_code sentinel = /\.routes\.draw do\s*\n/m @@ -327,12 +332,7 @@ module Rails # Returns optimized string with indentation def optimize_indentation(value, amount = 0) # :doc: return "#{value}\n" unless value.is_a?(String) - - if value.lines.size > 1 - value.strip_heredoc.indent(amount) - else - "#{value.strip.indent(amount)}\n" - end + "#{value.strip_heredoc.indent(amount).chomp}\n" end # Indent the +Gemfile+ to the depth of @indentation diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb index 2ccc1c18c0..618954741e 100644 --- a/railties/lib/rails/generators/rails/controller/controller_generator.rb +++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb @@ -17,7 +17,8 @@ module Rails def add_routes return if options[:skip_routes] return if actions.empty? - route generate_routing_code + routing_code = actions.map { |action| "get '#{file_name}/#{action}'" }.join("\n") + route routing_code, namespace: regular_class_path end hook_for :template_engine, :test_framework, :helper, :assets do |generator| @@ -32,45 +33,6 @@ module Rails def remove_possible_suffix(name) name.sub(/_?controller$/i, "") end - - # This method creates nested route entry for namespaced resources. - # For e.g. rails g controller foo/bar/baz index show - # Will generate - - # namespace :foo do - # namespace :bar do - # get 'baz/index' - # get 'baz/show' - # end - # end - def generate_routing_code - depth = 0 - lines = [] - - # Create 'namespace' ladder - # namespace :foo do - # namespace :bar do - regular_class_path.each do |ns| - lines << indent("namespace :#{ns} do\n", depth * 2) - depth += 1 - end - - # Create route - # get 'baz/index' - # get 'baz/show' - actions.each do |action| - lines << indent(%{get '#{file_name}/#{action}'\n}, depth * 2) - end - - # Create `end` ladder - # end - # end - until depth.zero? - depth -= 1 - lines << indent("end\n", depth * 2) - end - - lines.join - end end end end diff --git a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb index 9a92991efe..24ef9e7ff0 100644 --- a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb +++ b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb @@ -16,32 +16,7 @@ module Rails # end def add_resource_route return if options[:actions].present? - - depth = 0 - lines = [] - - # Create 'namespace' ladder - # namespace :foo do - # namespace :bar do - regular_class_path.each do |ns| - lines << indent("namespace :#{ns} do\n", depth * 2) - depth += 1 - end - - # inserts the primary resource - # Create route - # resources 'products' - lines << indent(%{resources :#{file_name.pluralize}\n}, depth * 2) - - # Create `end` ladder - # end - # end - until depth.zero? - depth -= 1 - lines << indent("end\n", depth * 2) - end - - route lines.join + route "resources :#{file_name.pluralize}", namespace: regular_class_path end end end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 5d6d7f1595..8c90d4b9f5 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -494,57 +494,59 @@ class ActionsTest < Rails::Generators::TestCase end end - def test_route_should_add_data_to_the_routes_block_in_config_routes + test "route should add route" do run_generator - route_command = "route '/login', controller: 'sessions', action: 'new'" - action :route, route_command - assert_file "config/routes.rb", /#{Regexp.escape(route_command)}/ + route_commands = ["get 'foo'", "get 'bar'", "get 'baz'"] + route_commands.each do |route_command| + action :route, route_command + end + assert_routes route_commands end - def test_route_should_be_idempotent + test "route should indent routing code" do run_generator - route_path = File.expand_path("config/routes.rb", destination_root) + route_commands = ["get 'foo'", "get 'bar'", "get 'baz'"] + action :route, route_commands.join("\n") + assert_routes route_commands + end - # runs first time, not asserting - action :route, "root 'welcome#index'" - content_1 = File.read(route_path) + test "route should be idempotent" do + run_generator + route_command = "root 'welcome#index'" + + # runs first time + action :route, route_command + assert_routes route_command + + content = File.read(File.expand_path("config/routes.rb", destination_root)) # runs second time - action :route, "root 'welcome#index'" - content_2 = File.read(route_path) - - assert_equal content_1, content_2 + action :route, route_command + assert_file "config/routes.rb", content end - def test_route_should_add_data_with_an_new_line + test "route with namespace option should nest route" do run_generator - action :route, "root 'welcome#index'" - route_path = File.expand_path("config/routes.rb", destination_root) - content = File.read(route_path) + action :route, "get 'foo'\nget 'bar'", namespace: :baz + assert_routes <<~ROUTING_CODE.chomp + namespace :baz do + get 'foo' + get 'bar' + end + ROUTING_CODE + end - # Remove all of the comments and blank lines from the routes file - content.gsub!(/^ \#.*\n/, "") - content.gsub!(/^\n/, "") - - File.write(route_path, content) - - routes = <<-F -Rails.application.routes.draw do - root 'welcome#index' -end -F - - assert_file "config/routes.rb", routes - - action :route, "resources :product_lines" - - routes = <<-F -Rails.application.routes.draw do - resources :product_lines - root 'welcome#index' -end -F - assert_file "config/routes.rb", routes + test "route with namespace option array should deeply nest route" do + run_generator + action :route, "get 'foo'\nget 'bar'", namespace: %w[baz qux] + assert_routes <<~ROUTING_CODE.chomp + namespace :baz do + namespace :qux do + get 'foo' + get 'bar' + end + end + ROUTING_CODE end def test_readme @@ -584,4 +586,18 @@ F def action(*args, &block) capture(:stdout) { generator.send(*args, &block) } end + + def assert_routes(*route_commands) + route_regexps = route_commands.flatten.map do |route_command| + %r{ + ^#{Regexp.escape("Rails.application.routes.draw do")}\n + (?:[ ]{2}.+\n|\n)* + #{Regexp.escape(route_command.indent(2))}\n + (?:[ ]{2}.+\n|\n)* + end\n + }x + end + + assert_file "config/routes.rb", *route_regexps + end end