Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6113

Show
Ignore:
Timestamp:
02/04/07 19:07:08 (2 years ago)
Author:
rick
Message:

fix form_for example in ActionController::Resources documentation. Closes #7362 [gnarg], Added enhanced docs to routing assertions. Closes #7359 [Rob Sanheim], improve error message for Routing for named routes. Closes #7346 [Rob Sanheim]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r6096 r6113  
    11*SVN* 
     2 
     3* improve error message for Routing for named routes.  Closes #7346 [Rob Sanheim] 
     4 
     5* Added enhanced docs to routing assertions.  Closes #7359 [Rob Sanheim] 
     6 
     7* fix form_for example in ActionController::Resources documentation.  Closes #7362 [gnarg] 
    28 
    39* Make sure that the string returned by TextHelper#truncate is actually a string, not a char proxy -- that should only be used internally while working on a multibyte-safe way of truncating [DHH] 
  • trunk/actionpack/lib/action_controller/assertions/routing_assertions.rb

    r5309 r6113  
    44      # Asserts that the routing of the given path was handled correctly and that the parsed options match. 
    55      # 
    6       #   assert_recognizes({:controller => 'items', :action => 'index'}, 'items') 
     6      #   assert_recognizes({:controller => 'items', :action => 'index'}, 'items') # check the default action 
     7      #   assert_recognizes({:controller => 'items', :action => 'list'}, 'items/list') # check a specific action 
     8      #   assert_recognizes({:controller => 'items', :action => 'list', :id => '1'}, 'items/list/1') # check an action with a parameter 
    79      # 
    810      # Pass a hash in the second argument to specify the request method.  This is useful for routes 
    9       # requiring a specific method. 
     11      # requiring a specific HTTP method.  The hash should contain a :path with the incoming request path 
     12      # and a :method containing the required HTTP verb. 
    1013      # 
     14      #   # assert that POSTing to /items will call the create action on ItemsController 
    1115      #   assert_recognizes({:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post}) 
    1216      # 
     17      # You can also pass in "extras" with a hash containing URL parameters that would normally be in the query string.  This can be used 
     18      # to assert that values in the query string string will end up in the params hash correctly.  To test query strings you must use the 
     19      # extras argument, appending the query string on the path directly will not work.  For example:  
     20      # 
     21      #   # assert that a path of '/items/list/1?view=print' returns the correct options 
     22      #   assert_recognizes({:controller => 'items', :action => 'list', :id => '1', :view => 'print'}, 'items/list/1', { :view => "print" })  
    1323      def assert_recognizes(expected_options, path, extras={}, message=nil) 
    1424        if path.is_a? Hash 
     
    3444      end 
    3545 
    36       # Asserts that the provided options can be used to generate the provided path. 
     46      # Asserts that the provided options can be used to generate the provided path.  This is the inverse of assert_recognizes. 
     47      # For example: 
     48      # 
     49      #   assert_generates("/items", :controller => "items", :action => "index") 
     50      #   assert_generates("/items/list", :controller => "items", :action => "list") 
     51      #   assert_generates("/items/list/1", { :controller => "items", :action => "list", :id => "1" })  
    3752      def assert_generates(expected_path, options, defaults={}, extras = {}, message=nil) 
    3853        clean_backtrace do  
     
    5469 
    5570      # Asserts that path and options match both ways; in other words, the URL generated from  
    56       # options is the same as path, and also that the options recognized from path are the same as options 
     71      # options is the same as path, and also that the options recognized from path are the same as options.  This 
     72      # essentially combines assert_recognizes and assert_generates into one step. 
    5773      def assert_routing(path, options, defaults={}, extras={}, message=nil) 
    5874        assert_recognizes(options, path, extras, message) 
  • trunk/actionpack/lib/action_controller/resources.rb

    r6062 r6113  
    159159    # or  
    160160    #    
    161     #   <% form_for :message, @message, message_path(@message), :html => {:method => :put} do |f| %> 
     161    #   <% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %> 
    162162    #  
    163163    # The #resources method accepts various options, too, to customize the resulting 
  • trunk/actionpack/lib/action_controller/routing.rb

    r6082 r6113  
    12411241        if named_route 
    12421242          path = named_route.generate(options, merged, expire_on) 
    1243           raise RoutingError, "#{named_route_name}_url failed to generate from #{options.inspect}, expected: #{named_route.requirements.inspect}, diff: #{named_route.requirements.diff(options).inspect}" if path.nil? 
    1244           return path 
     1243          if path.nil?  
     1244            raise_named_route_error(options, named_route, named_route_name) 
     1245          else 
     1246            return path 
     1247          end 
    12451248        else 
    12461249          merged[:action] ||= 'index' 
     
    12701273        raise RoutingError, "No route matches #{options.inspect}" 
    12711274      end 
     1275       
     1276      # try to give a helpful error message when named route generation fails 
     1277      def raise_named_route_error(options, named_route, named_route_name) 
     1278        diff = named_route.requirements.diff(options) 
     1279        unless diff.empty? 
     1280          raise RoutingError, "#{named_route_name}_url failed to generate from #{options.inspect}, expected: #{named_route.requirements.inspect}, diff: #{named_route.requirements.diff(options).inspect}" 
     1281        else 
     1282          required_segments = named_route.segments.select {|seg| (!seg.optional?) && (!seg.is_a?(DividerSegment)) } 
     1283          required_keys_or_values = required_segments.map { |seg| seg.key rescue seg.value } # we want either the key or the value from the segment 
     1284          raise RoutingError, "#{named_route_name}_url failed to generate from #{options.inspect} - you may have ambiguous routes, or you may need to supply additional parameters for this route.  content_url has the following required parameters: #{required_keys_or_values.inspect} - are they all satisifed?" 
     1285        end 
     1286      end 
    12721287   
    12731288      def recognize(request) 
  • trunk/actionpack/test/controller/routing_test.rb

    r6082 r6113  
    243243    end 
    244244  end 
    245  
     245   
     246  def test_should_list_options_diff_when_routing_requirements_dont_match 
     247    rs.draw do |map| 
     248      map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} 
     249    end 
     250    exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") } 
     251    assert_match /^post_url failed to generate/, exception.message 
     252    from_match = exception.message.match(/from \{[^\}]+\}/).to_s 
     253    assert_match /:bad_param=>"foo"/,   from_match 
     254    assert_match /:action=>"show"/,     from_match 
     255    assert_match /:controller=>"post"/, from_match 
     256     
     257    expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s 
     258    assert_no_match /:bad_param=>"foo"/,   expected_match 
     259    assert_match    /:action=>"show"/,     expected_match 
     260    assert_match    /:controller=>"post"/, expected_match 
     261 
     262    diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s 
     263    assert_match    /:bad_param=>"foo"/,   diff_match 
     264    assert_no_match /:action=>"show"/,     diff_match 
     265    assert_no_match /:controller=>"post"/, diff_match 
     266  end 
     267 
     268  # this specifies the case where your formerly would get a very confusing error message with an empty diff 
     269  def test_should_have_better_error_message_when_options_diff_is_empty 
     270    rs.draw do |map| 
     271      map.content '/content/:query', :controller => 'content', :action => 'show' 
     272    end 
     273    exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") } 
     274    expected_message = %[content_url failed to generate from {:action=>"show", :controller=>"content"} - you may have ambiguous routes, or you may need to supply additional parameters for this route.  content_url has the following required parameters: ["content", :query] - are they all satisifed?] 
     275    assert_equal expected_message, exception.message 
     276  end 
     277   
    246278  def test_dynamic_path_allowed 
    247279    rs.draw do |map| 
  • trunk/actionpack/test/template/form_helper_test.rb

    r6089 r6113  
    240240      _erbout.concat f.text_area(:body) 
    241241      _erbout.concat f.check_box(:secret) 
    242       _erbout.concat f.submit 'Create post' 
     242      _erbout.concat f.submit('Create post') 
    243243    end 
    244244