From 0eae869147b28f0ac77871c0cf748d8105817236 Mon Sep 17 00:00:00 2001 From: Balazs Nagy Date: Fri, 19 Feb 2010 09:39:27 +0100 Subject: [PATCH] Add support for :shallow => true in resources. It is aware of subpath shallowing, and a pre-merge bug which made name_prefixes start with _ are fixed. Signed-off-by: Balazs Nagy --- actionpack/lib/action_dispatch/routing/mapper.rb | 68 ++++++++++++++++++++-- actionpack/test/dispatch/routing_test.rb | 37 ++++++++++++ 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index bead321..13c0c90 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -473,10 +473,17 @@ module ActionDispatch end resource = Resource.new(resources.pop, options) + if (options.delete(:shallow)) + @scope[:shallow] = save_scope + elsif @scope.has_key? :shallow + orig_scope = save_scope + end scope(:path => resource.name.to_s, :controller => resource.controller) do with_scope_level(:resources, resource) do - yield if block_given? + with_shallow_scope(orig_scope) do + yield if block_given? + end with_scope_level(:collection) do get :index if resource.actions.include?(:index) @@ -486,15 +493,23 @@ module ActionDispatch with_scope_level(:member) do scope(':id') do - get :show if resource.actions.include?(:show) - put :update if resource.actions.include?(:update) - delete :destroy if resource.actions.include?(:destroy) - get :edit, :as => resource.singular if resource.actions.include?(:edit) + with_shallow_scope(orig_scope) do + get :show if resource.actions.include?(:show) + put :update if resource.actions.include?(:update) + delete :destroy if resource.actions.include?(:destroy) + get :edit, :as => resource.singular if resource.actions.include?(:edit) + end end end end end + if orig_scope + restore_scope(orig_scope) + elsif @scope.has_key? :shallow + @scope.delete(:shallow) + end + self end @@ -638,6 +653,49 @@ module ActionDispatch @scope[:scope_level] = old @scope[:scope_level_resource] = old_resource end + + def save_scope + { + :path => @scope[:path], + :name_prefix => @scope[:name_prefix] + } + end + + def restore_scope(hsh) + @scope[:path] = hsh[:path] + @scope[:name_prefix] = hsh[:name_prefix] + end + + def with_shallow_scope(curr_scope) + if !block_given? + raise "with_shallow_scope expects a block" + end + _saved_scope = save_scope + shallow_scope(curr_scope) + yield + restore_scope(_saved_scope) + end + + def shallow_scope(ref_scope) + return if ref_scope.nil? + return unless @scope.has_key? :shallow + root_scope = @scope[:shallow] + unless @scope[:path].start_with? ref_scope[:path] and + @scope[:path].start_with? root_scope[:path].to_s + raise 'shallow_scope path mismatch' + end + + [:path, :name_prefix].each do |index| + @scope[index] = if root_scope[index].nil? + '' + else + @scope[index][0..root_scope[index].length-1] + end << @scope[index][ref_scope[index].length..-1] + if @scope[index].empty? + @scope[index] = nil + end + end + end end include Base diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 0cd1fdd..18d2d21 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -157,6 +157,20 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resources :descriptions root :to => 'projects#index' end + + # http://guides.rails.info/routing.html#shallow-nesting with a twist + resources :publishers, :shallow => true do + resources :magazines do + resources :photos + end + end + resources :hosts do + resources :publishers, :shallow => true do + resources :magazines do + resources :photos + end + end + end end end @@ -726,6 +740,29 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + # http://guides.rails.info/routing.html#shallow-nesting with a twist + def test_shallow_nesting + with_test_routes do + assert_equal '/publishers', publishers_path + assert_equal '/publishers/1', publisher_path(1) + assert_equal '/publishers/1/magazines', publisher_magazines_path(1) + assert_equal '/magazines/2', magazine_path(2) + assert_equal '/magazines/2/photos', magazine_photos_path(2) + assert_equal '/photos/3', photo_path(3) + end + end + def test_shallow_nesting_with_a_twist + with_test_routes do + assert_equal '/hosts/1', host_path(1) + assert_equal '/hosts/1/publishers', host_publishers_path(1) + assert_equal '/hosts/1/publishers/1', host_publisher_path(1, 1) + assert_equal '/hosts/1/publishers/1/magazines', host_publisher_magazines_path(1, 1) + assert_equal '/hosts/1/magazines/2', host_magazine_path(1, 2) + assert_equal '/hosts/1/magazines/2/photos', host_magazine_photos_path(1, 2) + assert_equal '/hosts/1/photos/3', host_photo_path(1, 3) + end + end + private def with_test_routes real_routes, temp_routes = ActionController::Routing::Routes, Routes -- 1.6.6.1