From 784298008bf25c901564929d319eb631eb1a5639 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 25 Feb 2007 20:13:19 +0000 Subject: Allow routing requirements on map.resource(s) (closes #7633) [quixoten] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6232 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/CHANGELOG | 4 ++++ actionpack/lib/action_controller/resources.rb | 23 +++++++++++++++-------- actionpack/test/controller/resources_test.rb | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 396fa98a76..1767443f12 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Allow routing requirements on map.resource(s) #7633 [quixoten]. Example: + + map.resources :network_interfaces, :requirements => { :id => /^\d+\.\d+\.\d+\.\d+$/ } + * Cookie session store: empty and unchanged sessions don't write a cookie. [Jeremy Kemper] * Added helper(:all) as a way to include all helpers from app/helpers/**/*.rb in ApplicationController [DHH] diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb index d55e7f02ce..d5aeaf1d45 100644 --- a/actionpack/lib/action_controller/resources.rb +++ b/actionpack/lib/action_controller/resources.rb @@ -11,7 +11,7 @@ module ActionController @singular = options[:singular] || plural.to_s.singularize @options = options - + arrange_actions add_default_actions set_prefixes @@ -21,6 +21,13 @@ module ActionController @controller ||= (options[:controller] || plural).to_s end + def requirements(with_id = false) + @requirements ||= @options[:requirements] || {} + @id_requirement ||= { :id => @requirements.delete(:id) || /[^#{Routing::SEPARATORS.join}]+/ } + + with_id ? @requirements.merge(@id_requirement) : @requirements + end + def path @path ||= "#{path_prefix}/#{plural}" end @@ -389,14 +396,14 @@ module ActionController def action_options_for(action, resource, method = nil) default_options = { :action => action.to_s } - require_id = resource.kind_of?(SingletonResource) ? {} : { :requirements => { :id => Regexp.new("[^#{Routing::SEPARATORS.join}]+") } } + require_id = !resource.kind_of?(SingletonResource) case default_options[:action] - when "index", "new" : default_options.merge(conditions_for(method || :get)) - when "create" : default_options.merge(conditions_for(method || :post)) - when "show", "edit" : default_options.merge(conditions_for(method || :get)).merge(require_id) - when "update" : default_options.merge(conditions_for(method || :put)).merge(require_id) - when "destroy" : default_options.merge(conditions_for(method || :delete)).merge(require_id) - else default_options.merge(conditions_for(method)) + when "index", "new" : default_options.merge(conditions_for(method || :get)).merge(resource.requirements) + when "create" : default_options.merge(conditions_for(method || :post)).merge(resource.requirements) + when "show", "edit" : default_options.merge(conditions_for(method || :get)).merge(resource.requirements(require_id)) + when "update" : default_options.merge(conditions_for(method || :put)).merge(resource.requirements(require_id)) + when "destroy" : default_options.merge(conditions_for(method || :delete)).merge(resource.requirements(require_id)) + else default_options.merge(conditions_for(method)).merge(resource.requirements) end end end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index e5605dff62..2b65ae21c2 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -57,6 +57,31 @@ class ResourcesTest < Test::Unit::TestCase end end + def test_irregular_id_with_no_requirements_should_raise_error + expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'} + + with_restful_routing :messages do + assert_raises(ActionController::RoutingError) do + assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get) + end + end + end + + def test_irregular_id_with_requirements_should_pass + expected_options = {:controller => 'messages', :action => 'show', :id => '1.1.1'} + + with_restful_routing(:messages, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}) do + assert_recognizes(expected_options, :path => 'messages/1.1.1', :method => :get) + end + end + + def test_with_path_prefix_requirements + expected_options = {:controller => 'messages', :action => 'show', :thread_id => '1.1.1', :id => '1'} + with_restful_routing :messages, :path_prefix => '/thread/:thread_id', :requirements => {:thread_id => /[0-9]\.[0-9]\.[0-9]/} do + assert_recognizes(expected_options, :path => 'thread/1.1.1/messages/1', :method => :get) + end + end + def test_with_path_prefix with_restful_routing :messages, :path_prefix => '/thread/:thread_id' do assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } -- cgit v1.2.3