aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG10
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb29
-rw-r--r--actionpack/test/dispatch/routing_test.rb39
3 files changed, 75 insertions, 3 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index faa0d674dc..119d0bbc02 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,15 @@
*Rails 3.0.0 [beta 4/release candidate] (unreleased)*
+* Add shallow routes back to the new router [Diego Carrion]
+
+ resources :posts do
+ shallow do
+ resources :comments
+ end
+ end
+
+ You can now use comment_path for /comments/1 instead of post_comment_path for /posts/1/comments/1.
+
* Remove middleware laziness [José Valim]
* Make session stores rely on request.cookie_jar and change set_session semantics to return the cookie value instead of a boolean. [José Valim]
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index ae4417b56c..b64c57f985 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -350,6 +350,10 @@ module ActionDispatch
scope(:constraints => constraints) { yield }
end
+ def shallow
+ scope(:shallow => true) { yield }
+ end
+
def defaults(defaults = {})
scope(:defaults => defaults) { yield }
end
@@ -374,12 +378,21 @@ module ActionDispatch
@scope_options ||= private_methods.grep(/^merge_(.+)_scope$/) { $1.to_sym }
end
+ def merge_shallow_scope(parent, child)
+ parent or child
+ end
+
def merge_path_scope(parent, child)
- Mapper.normalize_path("#{parent}/#{child}")
+ parent_path = (@scope[:shallow] and child.eql?(':id')) ? parent.split('/').last : parent
+ Mapper.normalize_path "#{parent_path}/#{child}"
end
def merge_name_prefix_scope(parent, child)
- parent ? "#{parent}_#{child}" : child
+ if @scope[:shallow]
+ child
+ else
+ parent ? "#{parent}_#{child}" : child
+ end
end
def merge_module_scope(parent, child)
@@ -514,6 +527,10 @@ module ActionDispatch
options["#{singular}_id".to_sym] = id_constraint if id_constraint?
options
end
+
+ def shallow?
+ options[:shallow]
+ end
end
class SingletonResource < Resource #:nodoc:
@@ -581,8 +598,12 @@ module ActionDispatch
resource = Resource.new(resources.pop, options)
- scope(:path => resource.path, :controller => resource.controller) do
+ scope(:path => resource.path, :controller => resource.controller, :shallow => resource.shallow?) do
with_scope_level(:resources, resource) do
+ if @scope[:shallow] && @scope[:name_prefix]
+ @scope[:path] = "/#{@scope[:name_prefix].pluralize}/:#{@scope[:name_prefix]}_id/#{resource.path}"
+ end
+
yield if block_given?
with_scope_level(:collection) do
@@ -596,6 +617,8 @@ module ActionDispatch
with_scope_level(:member) do
scope(':id') do
scope(resource.options) do
+ @scope[:name_prefix] = nil if @scope[:shallow]
+
get :show if resource.actions.include?(:show)
put :update if resource.actions.include?(:update)
delete :destroy if resource.actions.include?(:destroy)
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index ffa4f50b00..82c45f3161 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -34,6 +34,33 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ resources :users do
+ shallow do
+ resources :photos do
+ resources :types do
+ member do
+ post :preview
+ end
+ collection do
+ delete :erase
+ end
+ end
+ end
+ end
+ end
+
+ shallow do
+ resources :teams do
+ resources :players
+ end
+
+ resources :countries do
+ resources :cities do
+ resources :places
+ end
+ end
+ end
+
match 'account/logout' => redirect("/logout"), :as => :logout_redirect
match 'account/login', :to => redirect("/login")
@@ -728,6 +755,18 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_shallow_routes
+ with_test_routes do
+ assert_equal '/photos/4', photo_path(4)
+ assert_equal '/types/10/edit', edit_type_path(10)
+ assert_equal '/types/5/preview', preview_type_path(5)
+ assert_equal '/photos/2/types', photo_types_path(2)
+ assert_equal '/cities/1/places', url_for(:controller => :places, :action => :index, :city_id => 1, :only_path => true)
+ assert_equal '/teams/new', url_for(:controller => :teams, :action => :new, :only_path => true)
+ assert_equal '/photos/11/types/erase', url_for(:controller => :types, :action => :erase, :photo_id => 11, :only_path => true)
+ end
+ end
+
def test_update_project_person
with_test_routes do
get '/projects/1/people/2/update'