From d01dcb3a937b88d12b8ac6b0d3089e815d62d262 Mon Sep 17 00:00:00 2001 From: Balazs Nagy Date: Fri, 12 Feb 2010 15:21:26 +0100 Subject: [PATCH] Added support for shallow nesting. Add support for :shallow => true in resources. Signed-off-by: Balazs Nagy --- actionpack/lib/action_dispatch/routing/mapper.rb | 51 +++++++++++++++++++--- actionpack/test/dispatch/routing_test.rb | 18 ++++++++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 8de68b3..50d9600 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -473,10 +473,16 @@ module ActionDispatch end resource = Resource.new(resources.pop, options) + original_shallow, shallow = @scope[:shallow], options.delete(:shallow) + if @scope[:shallow] || shallow + @scope[:shallow] = save_scope + end scope(:path => resource.name.to_s, :controller => resource.controller) do with_scope_level(:resources, resource) do - yield if block_given? + intersect_scope_if(@scope[:shallow], @scope[:shallow]) do + yield if block_given? + end with_scope_level(:collection) do get :index if resource.actions.include?(:index) @@ -485,16 +491,18 @@ module ActionDispatch end 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) + scope(":id") do + intersect_scope_if(@scope[:shallow], @scope[:shallow]) 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 - + @scope[:shallow] = original_shallow self end @@ -638,6 +646,35 @@ module ActionDispatch @scope[:scope_level] = old @scope[:scope_level_resource] = old_resource end + + def save_scope + [@scope[:path], @scope[:name_prefix]] + end + + def intersect_scope_if(t, ary) + if t + _saved_scope = save_scope + intersect_scope(ary) + end + if block_given? + yield + if t + restore_scope(_saved_scope) + end + end + end + + def intersect_scope(ary) + if @scope[:path].starts_with? ary[0] + @scope[:path] = @scope[:path][ary[0].length+1..-1] + @scope[:name_prefix] = @scope[:name_prefix][ary[1].length+1..-1] + end + + end + + def restore_scope(ary) + (@scope[:path], @scope[:name_prefix]) = ary + end end include Base diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index bcb97e4..8c4dd96 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -155,6 +155,13 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resources :descriptions root :to => 'projects#index' end + + # http://guides.rails.info/routing.html#shallow-nesting + resources :publishers, :shallow => true do + resources :magazines do + resources :photos + end + end end end @@ -719,6 +726,17 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + # http://guides.rails.info/routing.html#shallow-nesting + def test_shallow_nesting + with_test_routes do + 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 + private def with_test_routes real_routes, temp_routes = ActionController::Routing::Routes, Routes -- 1.6.6.1