diff options
5 files changed, 111 insertions, 21 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 15980db39b..7cfe4693c1 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1042,7 +1042,7 @@ module ActionDispatch class Resource #:nodoc: attr_reader :controller, :path, :options, :param - def initialize(entities, options = {}) + def initialize(entities, api_only = false, options = {}) @name = entities.to_s @path = (options[:path] || @name).to_s @controller = (options[:controller] || @name).to_s @@ -1050,10 +1050,15 @@ module ActionDispatch @param = (options[:param] || :id).to_sym @options = options @shallow = false + @api_only = api_only end def default_actions - [:index, :create, :new, :show, :update, :destroy, :edit] + if @api_only + [:index, :create, :show, :update, :destroy] + else + [:index, :create, :new, :show, :update, :destroy, :edit] + end end def actions @@ -1120,7 +1125,7 @@ module ActionDispatch end class SingletonResource < Resource #:nodoc: - def initialize(entities, options) + def initialize(entities, api_only, options) super @as = nil @controller = (options[:controller] || plural).to_s @@ -1128,7 +1133,11 @@ module ActionDispatch end def default_actions - [:show, :create, :update, :destroy, :new, :edit] + if @api_only + [:show, :create, :update, :destroy] + else + [:show, :create, :update, :destroy, :new, :edit] + end end def plural @@ -1178,7 +1187,7 @@ module ActionDispatch return self end - resource_scope(:resource, SingletonResource.new(resources.pop, options)) do + resource_scope(:resource, SingletonResource.new(resources.pop, api_only?, options)) do yield if block_given? concerns(options[:concerns]) if options[:concerns] @@ -1336,7 +1345,7 @@ module ActionDispatch return self end - resource_scope(:resources, Resource.new(resources.pop, options)) do + resource_scope(:resources, Resource.new(resources.pop, api_only?, options)) do yield if block_given? concerns(options[:concerns]) if options[:concerns] @@ -1768,6 +1777,10 @@ module ActionDispatch delete :destroy if parent_resource.actions.include?(:destroy) end end + + def api_only? + @set.api_only? + end end # Routing Concerns allow you to declare common routes that can be reused diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index cf35e85b40..454593b59f 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -319,17 +319,23 @@ module ActionDispatch end def self.new_with_config(config) + route_set_config = DEFAULT_CONFIG + + # engines apparently don't have this set if config.respond_to? :relative_url_root - new Config.new config.relative_url_root - else - # engines apparently don't have this set - new + route_set_config.relative_url_root = config.relative_url_root + end + + if config.respond_to? :api_only + route_set_config.api_only = config.api_only end + + new route_set_config end - Config = Struct.new :relative_url_root + Config = Struct.new :relative_url_root, :api_only - DEFAULT_CONFIG = Config.new(nil) + DEFAULT_CONFIG = Config.new(nil, false) def initialize(config = DEFAULT_CONFIG) self.named_routes = NamedRouteCollection.new @@ -352,6 +358,10 @@ module ActionDispatch @config.relative_url_root end + def api_only? + @config.api_only + end + def request_class ActionDispatch::Request end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 62c99a2edc..77f86b7a62 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -167,6 +167,46 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal '/session/reset', reset_session_path end + def test_session_singleton_resource_for_api_app + self.class.stub_controllers do |_| + config = ActionDispatch::Routing::RouteSet::Config.new + config.api_only = true + + routes = ActionDispatch::Routing::RouteSet.new(config) + + routes.draw do + resource :session do + get :create + post :reset + end + end + @app = RoutedRackApp.new routes + end + + get '/session' + assert_equal 'sessions#create', @response.body + assert_equal '/session', session_path + + post '/session' + assert_equal 'sessions#create', @response.body + + put '/session' + assert_equal 'sessions#update', @response.body + + delete '/session' + assert_equal 'sessions#destroy', @response.body + + post '/session/reset' + assert_equal 'sessions#reset', @response.body + assert_equal '/session/reset', reset_session_path + + get '/session/new' + assert_equal 'Not Found', @response.body + + get '/session/edit' + assert_equal 'Not Found', @response.body + end + def test_session_info_nested_singleton_resource draw do resource :session do @@ -509,6 +549,41 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal '/projects/1/edit', edit_project_path(:id => '1') end + def test_projects_for_api_app + self.class.stub_controllers do |_| + config = ActionDispatch::Routing::RouteSet::Config.new + config.api_only = true + + routes = ActionDispatch::Routing::RouteSet.new(config) + routes.draw do + resources :projects, controller: :project + end + @app = RoutedRackApp.new routes + end + + get '/projects' + assert_equal 'project#index', @response.body + assert_equal '/projects', projects_path + + post '/projects' + assert_equal 'project#create', @response.body + + get '/projects.xml' + assert_equal 'project#index', @response.body + assert_equal '/projects.xml', projects_path(format: 'xml') + + get '/projects/1' + assert_equal 'project#show', @response.body + assert_equal '/projects/1', project_path(id: '1') + + get '/projects/1.xml' + assert_equal 'project#show', @response.body + assert_equal '/projects/1.xml', project_path(id: '1', format: 'xml') + + get '/projects/1/edit' + assert_equal 'Not Found', @response.body + end + def test_projects_with_post_action_and_new_path_on_collection draw do resources :projects, :controller => :project do 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 17d22768ed..7472e5f071 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 @@ -24,9 +24,7 @@ module Rails end # inserts the primary resource - resources = "resources :#{file_name.pluralize}" - resources << ", except: [:new, :edit]" if options.api? - write(resources, route_length + 1) + write("resources :#{file_name.pluralize}", route_length + 1) # ends blocks regular_class_path.each_index do |index| diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index f73169c6fb..581d80d60e 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -85,10 +85,4 @@ class ResourceGeneratorTest < Rails::Generators::TestCase assert_no_match(/resources :accounts$/, route) end end - - def test_api_only_does_not_generate_edit_route - run_generator ["Account", "--api"] - - assert_file "config/routes.rb", /resources :accounts, except: \[:new, :edit\]$/ - end end |