actionpack 3.0.0.beta4 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (102) hide show
  1. data/CHANGELOG +36 -0
  2. data/{README → README.rdoc} +79 -137
  3. data/lib/abstract_controller.rb +1 -0
  4. data/lib/abstract_controller/asset_paths.rb +1 -1
  5. data/lib/abstract_controller/base.rb +3 -12
  6. data/lib/abstract_controller/rendering.rb +2 -2
  7. data/lib/abstract_controller/view_paths.rb +2 -1
  8. data/lib/action_controller.rb +1 -2
  9. data/lib/action_controller/base.rb +3 -9
  10. data/lib/action_controller/log_subscriber.rb +56 -0
  11. data/lib/action_controller/metal.rb +10 -3
  12. data/lib/action_controller/metal/helpers.rb +5 -4
  13. data/lib/action_controller/metal/hide_actions.rb +3 -3
  14. data/lib/action_controller/metal/instrumentation.rb +2 -1
  15. data/lib/action_controller/metal/mime_responds.rb +13 -10
  16. data/lib/action_controller/metal/rack_delegation.rb +0 -4
  17. data/lib/action_controller/metal/request_forgery_protection.rb +1 -1
  18. data/lib/action_controller/metal/rescue.rb +9 -0
  19. data/lib/action_controller/metal/responder.rb +13 -5
  20. data/lib/action_controller/metal/streaming.rb +2 -0
  21. data/lib/action_controller/metal/url_for.rb +5 -5
  22. data/lib/action_controller/railtie.rb +14 -23
  23. data/lib/action_controller/record_identifier.rb +6 -25
  24. data/lib/action_controller/test_case.rb +18 -6
  25. data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -0
  26. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -0
  27. data/lib/action_dispatch.rb +6 -0
  28. data/lib/action_dispatch/http/cache.rb +2 -2
  29. data/lib/action_dispatch/http/filter_parameters.rb +10 -66
  30. data/lib/action_dispatch/http/mime_type.rb +1 -1
  31. data/lib/action_dispatch/http/parameter_filter.rb +72 -0
  32. data/lib/action_dispatch/http/parameters.rb +31 -2
  33. data/lib/action_dispatch/http/request.rb +4 -1
  34. data/lib/action_dispatch/http/upload.rb +2 -2
  35. data/lib/action_dispatch/middleware/callbacks.rb +4 -4
  36. data/lib/action_dispatch/middleware/cookies.rb +39 -6
  37. data/lib/action_dispatch/middleware/flash.rb +9 -2
  38. data/lib/action_dispatch/middleware/session/abstract_store.rb +121 -36
  39. data/lib/action_dispatch/middleware/session/cookie_store.rb +26 -19
  40. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -1
  41. data/lib/action_dispatch/middleware/show_exceptions.rb +2 -2
  42. data/lib/action_dispatch/middleware/stack.rb +12 -5
  43. data/lib/action_dispatch/railtie.rb +1 -1
  44. data/lib/action_dispatch/routing.rb +11 -13
  45. data/lib/action_dispatch/routing/deprecated_mapper.rb +6 -388
  46. data/lib/action_dispatch/routing/mapper.rb +364 -234
  47. data/lib/action_dispatch/routing/polymorphic_routes.rb +186 -0
  48. data/lib/action_dispatch/routing/route.rb +11 -2
  49. data/lib/action_dispatch/routing/route_set.rb +62 -28
  50. data/lib/action_dispatch/routing/url_for.rb +2 -1
  51. data/lib/action_dispatch/testing/assertions.rb +0 -2
  52. data/lib/action_dispatch/testing/assertions/routing.rb +0 -1
  53. data/lib/action_dispatch/testing/assertions/selector.rb +20 -24
  54. data/lib/action_dispatch/testing/integration.rb +2 -2
  55. data/lib/action_dispatch/testing/test_response.rb +2 -2
  56. data/lib/action_pack/version.rb +1 -1
  57. data/lib/action_view.rb +1 -0
  58. data/lib/action_view/base.rb +20 -21
  59. data/lib/action_view/context.rb +9 -12
  60. data/lib/action_view/helpers.rb +0 -2
  61. data/lib/action_view/helpers/active_model_helper.rb +17 -2
  62. data/lib/action_view/helpers/asset_tag_helper.rb +15 -33
  63. data/lib/action_view/helpers/atom_feed_helper.rb +5 -3
  64. data/lib/action_view/helpers/cache_helper.rb +4 -2
  65. data/lib/action_view/helpers/capture_helper.rb +4 -4
  66. data/lib/action_view/helpers/csrf_helper.rb +3 -1
  67. data/lib/action_view/helpers/date_helper.rb +10 -5
  68. data/lib/action_view/helpers/debug_helper.rb +3 -1
  69. data/lib/action_view/helpers/form_helper.rb +36 -30
  70. data/lib/action_view/helpers/form_options_helper.rb +7 -6
  71. data/lib/action_view/helpers/form_tag_helper.rb +17 -6
  72. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  73. data/lib/action_view/helpers/number_helper.rb +16 -45
  74. data/lib/action_view/helpers/prototype_helper.rb +14 -16
  75. data/lib/action_view/helpers/raw_output_helper.rb +9 -0
  76. data/lib/action_view/helpers/record_tag_helper.rb +5 -0
  77. data/lib/action_view/helpers/sanitize_helper.rb +26 -20
  78. data/lib/action_view/helpers/scriptaculous_helper.rb +6 -5
  79. data/lib/action_view/helpers/tag_helper.rb +2 -1
  80. data/lib/action_view/helpers/text_helper.rb +24 -111
  81. data/lib/action_view/helpers/translation_helper.rb +17 -10
  82. data/lib/action_view/helpers/url_helper.rb +26 -33
  83. data/lib/action_view/log_subscriber.rb +28 -0
  84. data/lib/action_view/lookup_context.rb +2 -0
  85. data/lib/action_view/paths.rb +1 -0
  86. data/lib/action_view/railtie.rb +15 -3
  87. data/lib/action_view/render/layouts.rb +2 -1
  88. data/lib/action_view/render/partials.rb +3 -1
  89. data/lib/action_view/render/rendering.rb +2 -1
  90. data/lib/action_view/template.rb +12 -8
  91. data/lib/action_view/template/error.rb +1 -0
  92. data/lib/action_view/template/handlers.rb +1 -0
  93. data/lib/action_view/template/resolver.rb +2 -1
  94. data/lib/action_view/template/text.rb +1 -0
  95. data/lib/action_view/test_case.rb +42 -20
  96. metadata +44 -23
  97. data/lib/action_controller/polymorphic_routes.rb +0 -182
  98. data/lib/action_controller/railties/log_subscriber.rb +0 -56
  99. data/lib/action_controller/railties/url_helpers.rb +0 -14
  100. data/lib/action_dispatch/testing/assertions/model.rb +0 -19
  101. data/lib/action_view/helpers/record_identification_helper.rb +0 -20
  102. data/lib/action_view/railties/log_subscriber.rb +0 -24
@@ -0,0 +1,186 @@
1
+ module ActionDispatch
2
+ module Routing
3
+ # Polymorphic URL helpers are methods for smart resolution to a named route call when
4
+ # given an Active Record model instance. They are to be used in combination with
5
+ # ActionController::Resources.
6
+ #
7
+ # These methods are useful when you want to generate correct URL or path to a RESTful
8
+ # resource without having to know the exact type of the record in question.
9
+ #
10
+ # Nested resources and/or namespaces are also supported, as illustrated in the example:
11
+ #
12
+ # polymorphic_url([:admin, @article, @comment])
13
+ #
14
+ # results in:
15
+ #
16
+ # admin_article_comment_url(@article, @comment)
17
+ #
18
+ # == Usage within the framework
19
+ #
20
+ # Polymorphic URL helpers are used in a number of places throughout the Rails framework:
21
+ #
22
+ # * <tt>url_for</tt>, so you can use it with a record as the argument, e.g.
23
+ # <tt>url_for(@article)</tt>;
24
+ # * ActionView::Helpers::FormHelper uses <tt>polymorphic_path</tt>, so you can write
25
+ # <tt>form_for(@article)</tt> without having to specify <tt>:url</tt> parameter for the form
26
+ # action;
27
+ # * <tt>redirect_to</tt> (which, in fact, uses <tt>url_for</tt>) so you can write
28
+ # <tt>redirect_to(post)</tt> in your controllers;
29
+ # * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs
30
+ # for feed entries.
31
+ #
32
+ # == Prefixed polymorphic helpers
33
+ #
34
+ # In addition to <tt>polymorphic_url</tt> and <tt>polymorphic_path</tt> methods, a
35
+ # number of prefixed helpers are available as a shorthand to <tt>:action => "..."</tt>
36
+ # in options. Those are:
37
+ #
38
+ # * <tt>edit_polymorphic_url</tt>, <tt>edit_polymorphic_path</tt>
39
+ # * <tt>new_polymorphic_url</tt>, <tt>new_polymorphic_path</tt>
40
+ #
41
+ # Example usage:
42
+ #
43
+ # edit_polymorphic_path(@post) # => "/posts/1/edit"
44
+ # polymorphic_path(@post, :format => :pdf) # => "/posts/1.pdf"
45
+ module PolymorphicRoutes
46
+ # Constructs a call to a named RESTful route for the given record and returns the
47
+ # resulting URL string. For example:
48
+ #
49
+ # # calls post_url(post)
50
+ # polymorphic_url(post) # => "http://example.com/posts/1"
51
+ # polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
52
+ # polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
53
+ # polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
54
+ # polymorphic_url(Comment) # => "http://example.com/comments"
55
+ #
56
+ # ==== Options
57
+ #
58
+ # * <tt>:action</tt> - Specifies the action prefix for the named route:
59
+ # <tt>:new</tt> or <tt>:edit</tt>. Default is no prefix.
60
+ # * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
61
+ # Default is <tt>:url</tt>.
62
+ #
63
+ # ==== Examples
64
+ #
65
+ # # an Article record
66
+ # polymorphic_url(record) # same as article_url(record)
67
+ #
68
+ # # a Comment record
69
+ # polymorphic_url(record) # same as comment_url(record)
70
+ #
71
+ # # it recognizes new records and maps to the collection
72
+ # record = Comment.new
73
+ # polymorphic_url(record) # same as comments_url()
74
+ #
75
+ # # the class of a record will also map to the collection
76
+ # polymorphic_url(Comment) # same as comments_url()
77
+ #
78
+ def polymorphic_url(record_or_hash_or_array, options = {})
79
+ if record_or_hash_or_array.kind_of?(Array)
80
+ record_or_hash_or_array = record_or_hash_or_array.compact
81
+ record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1
82
+ end
83
+
84
+ record = extract_record(record_or_hash_or_array)
85
+ record = record.to_model if record.respond_to?(:to_model)
86
+
87
+ args = case record_or_hash_or_array
88
+ when Hash; [ record_or_hash_or_array ]
89
+ when Array; record_or_hash_or_array.dup
90
+ else [ record_or_hash_or_array ]
91
+ end
92
+
93
+ inflection = if options[:action].to_s == "new"
94
+ args.pop
95
+ :singular
96
+ elsif (record.respond_to?(:persisted?) && !record.persisted?)
97
+ args.pop
98
+ :plural
99
+ elsif record.is_a?(Class)
100
+ args.pop
101
+ :plural
102
+ else
103
+ :singular
104
+ end
105
+
106
+ args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
107
+ named_route = build_named_route_call(record_or_hash_or_array, inflection, options)
108
+
109
+ url_options = options.except(:action, :routing_type)
110
+ unless url_options.empty?
111
+ args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
112
+ end
113
+
114
+ send(named_route, *args)
115
+ end
116
+
117
+ # Returns the path component of a URL for the given record. It uses
118
+ # <tt>polymorphic_url</tt> with <tt>:routing_type => :path</tt>.
119
+ def polymorphic_path(record_or_hash_or_array, options = {})
120
+ polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
121
+ end
122
+
123
+ %w(edit new).each do |action|
124
+ module_eval <<-EOT, __FILE__, __LINE__ + 1
125
+ def #{action}_polymorphic_url(record_or_hash, options = {}) # def edit_polymorphic_url(record_or_hash, options = {})
126
+ polymorphic_url( # polymorphic_url(
127
+ record_or_hash, # record_or_hash,
128
+ options.merge(:action => "#{action}")) # options.merge(:action => "edit"))
129
+ end # end
130
+ #
131
+ def #{action}_polymorphic_path(record_or_hash, options = {}) # def edit_polymorphic_path(record_or_hash, options = {})
132
+ polymorphic_url( # polymorphic_url(
133
+ record_or_hash, # record_or_hash,
134
+ options.merge(:action => "#{action}", :routing_type => :path)) # options.merge(:action => "edit", :routing_type => :path))
135
+ end # end
136
+ EOT
137
+ end
138
+
139
+ private
140
+ def action_prefix(options)
141
+ options[:action] ? "#{options[:action]}_" : ''
142
+ end
143
+
144
+ def routing_type(options)
145
+ options[:routing_type] || :url
146
+ end
147
+
148
+ def build_named_route_call(records, inflection, options = {})
149
+ unless records.is_a?(Array)
150
+ record = extract_record(records)
151
+ route = ''
152
+ else
153
+ record = records.pop
154
+ route = records.inject("") do |string, parent|
155
+ if parent.is_a?(Symbol) || parent.is_a?(String)
156
+ string << "#{parent}_"
157
+ else
158
+ string << ActiveModel::Naming.plural(parent).singularize
159
+ string << "_"
160
+ end
161
+ end
162
+ end
163
+
164
+ if record.is_a?(Symbol) || record.is_a?(String)
165
+ route << "#{record}_"
166
+ else
167
+ route << ActiveModel::Naming.plural(record)
168
+ route = route.singularize if inflection == :singular
169
+ route << "_"
170
+ route << "index_" if ActiveModel::Naming.uncountable?(record) && inflection == :plural
171
+ end
172
+
173
+ action_prefix(options) + route + routing_type(options).to_s
174
+ end
175
+
176
+ def extract_record(record_or_hash_or_array)
177
+ case record_or_hash_or_array
178
+ when Array; record_or_hash_or_array.last
179
+ when Hash; record_or_hash_or_array[:id]
180
+ else record_or_hash_or_array
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+
@@ -2,9 +2,10 @@ module ActionDispatch
2
2
  module Routing
3
3
  class Route #:nodoc:
4
4
  attr_reader :app, :conditions, :defaults, :name
5
- attr_reader :path, :requirements
5
+ attr_reader :path, :requirements, :set
6
6
 
7
- def initialize(app, conditions, requirements, defaults, name, anchor)
7
+ def initialize(set, app, conditions, requirements, defaults, name, anchor)
8
+ @set = set
8
9
  @app = app
9
10
  @defaults = defaults
10
11
  @name = name
@@ -24,6 +25,9 @@ module ActionDispatch
24
25
  h[k] = Rack::Mount::RegexpWithNamedGroups.new(v)
25
26
  h
26
27
  }
28
+
29
+ @conditions.delete_if{ |k,v| k != :path_info && !valid_condition?(k) }
30
+ @requirements.delete_if{ |k,v| !valid_condition?(k) }
27
31
  end
28
32
 
29
33
  def verb
@@ -50,6 +54,11 @@ module ActionDispatch
50
54
  "%-6s %-40s %s" % [(verb || :any).to_s.upcase, path, requirements.inspect]
51
55
  end
52
56
  end
57
+
58
+ private
59
+ def valid_condition?(method)
60
+ segment_keys.include?(method) || set.valid_conditions.include?(method)
61
+ end
53
62
  end
54
63
  end
55
64
  end
@@ -24,7 +24,7 @@ module ActionDispatch
24
24
  return [404, {'X-Cascade' => 'pass'}, []]
25
25
  end
26
26
 
27
- controller.action(params[:action]).call(env)
27
+ dispatch(controller, params[:action], env)
28
28
  end
29
29
 
30
30
  def prepare_params!(params)
@@ -32,29 +32,43 @@ module ActionDispatch
32
32
  split_glob_param!(params) if @glob_param
33
33
  end
34
34
 
35
- def controller(params, raise_error=true)
35
+ # If this is a default_controller (i.e. a controller specified by the user)
36
+ # we should raise an error in case it's not found, because it usually means
37
+ # an user error. However, if the controller was retrieved through a dynamic
38
+ # segment, as in :controller(/:action), we should simply return nil and
39
+ # delegate the control back to Rack cascade. Besides, if this is not a default
40
+ # controller, it means we should respect the @scope[:module] parameter.
41
+ def controller(params, default_controller=true)
36
42
  if params && params.key?(:controller)
37
43
  controller_param = params[:controller]
38
- unless controller = @controllers[controller_param]
39
- controller_name = "#{controller_param.camelize}Controller"
40
- controller = @controllers[controller_param] =
41
- ActiveSupport::Dependencies.ref(controller_name)
42
- end
43
-
44
- controller.get
44
+ controller_reference(controller_param)
45
45
  end
46
46
  rescue NameError => e
47
- raise ActionController::RoutingError, e.message, e.backtrace if raise_error
47
+ raise ActionController::RoutingError, e.message, e.backtrace if default_controller
48
48
  end
49
49
 
50
- private
51
- def merge_default_action!(params)
52
- params[:action] ||= 'index'
53
- end
50
+ private
54
51
 
55
- def split_glob_param!(params)
56
- params[@glob_param] = params[@glob_param].split('/').map { |v| URI.unescape(v) }
52
+ def controller_reference(controller_param)
53
+ unless controller = @controllers[controller_param]
54
+ controller_name = "#{controller_param.camelize}Controller"
55
+ controller = @controllers[controller_param] =
56
+ ActiveSupport::Dependencies.ref(controller_name)
57
57
  end
58
+ controller.get
59
+ end
60
+
61
+ def dispatch(controller, action, env)
62
+ controller.action(action).call(env)
63
+ end
64
+
65
+ def merge_default_action!(params)
66
+ params[:action] ||= 'index'
67
+ end
68
+
69
+ def split_glob_param!(params)
70
+ params[@glob_param] = params[@glob_param].split('/').map { |v| URI.unescape(v) }
71
+ end
58
72
  end
59
73
 
60
74
  # A NamedRouteCollection instance is a collection of named routes, and also
@@ -185,9 +199,9 @@ module ActionDispatch
185
199
  end
186
200
  end
187
201
 
188
- attr_accessor :routes, :named_routes
202
+ attr_accessor :set, :routes, :named_routes
189
203
  attr_accessor :disable_clear_and_finalize, :resources_path_names
190
- attr_accessor :default_url_options, :request_class
204
+ attr_accessor :default_url_options, :request_class, :valid_conditions
191
205
 
192
206
  def self.default_resources_path_names
193
207
  { :new => 'new', :edit => 'edit' }
@@ -199,7 +213,11 @@ module ActionDispatch
199
213
  self.resources_path_names = self.class.default_resources_path_names.dup
200
214
  self.controller_namespaces = Set.new
201
215
  self.default_url_options = {}
216
+
202
217
  self.request_class = request_class
218
+ self.valid_conditions = request_class.public_instance_methods.map { |m| m.to_sym }
219
+ self.valid_conditions.delete(:id)
220
+ self.valid_conditions.push(:controller, :action)
203
221
 
204
222
  @disable_clear_and_finalize = false
205
223
  clear!
@@ -262,10 +280,10 @@ module ActionDispatch
262
280
  # Yes plz - JP
263
281
  included do
264
282
  routes.install_helpers(self)
265
- singleton_class.send(:define_method, :_router) { routes }
283
+ singleton_class.send(:define_method, :_routes) { routes }
266
284
  end
267
285
 
268
- define_method(:_router) { routes }
286
+ define_method(:_routes) { routes }
269
287
  end
270
288
 
271
289
  helpers
@@ -277,7 +295,7 @@ module ActionDispatch
277
295
  end
278
296
 
279
297
  def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
280
- route = Route.new(app, conditions, requirements, defaults, name, anchor)
298
+ route = Route.new(self, app, conditions, requirements, defaults, name, anchor)
281
299
  @set.add_route(*route)
282
300
  named_routes[name] = route if name
283
301
  routes << route
@@ -312,7 +330,11 @@ module ActionDispatch
312
330
 
313
331
  def use_recall_for(key)
314
332
  if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
315
- @options[key] = @recall.delete(key)
333
+ if named_route_exists?
334
+ @options[key] = @recall.delete(key) if segment_keys.include?(key)
335
+ else
336
+ @options[key] = @recall.delete(key)
337
+ end
316
338
  end
317
339
  end
318
340
 
@@ -371,7 +393,7 @@ module ActionDispatch
371
393
 
372
394
  def generate
373
395
  error = ActionController::RoutingError.new("No route matches #{options.inspect}")
374
- path, params = @set.generate(:path_info, named_route, options, recall, opts)
396
+ path, params = @set.set.generate(:path_info, named_route, options, recall, opts)
375
397
 
376
398
  raise error unless path
377
399
 
@@ -392,7 +414,8 @@ module ActionDispatch
392
414
  elsif value.is_a?(Array)
393
415
  value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
394
416
  else
395
- Rack::Mount::Utils.escape_uri(value.to_param)
417
+ return nil unless param = value.to_param
418
+ param.split('/').map { |v| Rack::Mount::Utils.escape_uri(v) }.join("/")
396
419
  end
397
420
  end
398
421
  {:parameterize => parameterize}
@@ -402,6 +425,15 @@ module ActionDispatch
402
425
  return false unless current_controller
403
426
  controller.to_param != current_controller.to_param
404
427
  end
428
+
429
+ private
430
+ def named_route_exists?
431
+ named_route && set.named_routes[named_route]
432
+ end
433
+
434
+ def segment_keys
435
+ set.named_routes[named_route].segment_keys
436
+ end
405
437
  end
406
438
 
407
439
  # Generate the path indicated by the arguments, and return an array of
@@ -415,14 +447,14 @@ module ActionDispatch
415
447
  end
416
448
 
417
449
  def generate(options, recall = {}, extras = false)
418
- Generator.new(options, recall, @set, extras).generate
450
+ Generator.new(options, recall, self, extras).generate
419
451
  end
420
452
 
421
453
  RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash]
422
454
 
423
455
  def url_for(options)
424
456
  finalize!
425
- options = default_url_options.merge(options || {})
457
+ options = (options || {}).reverse_merge!(default_url_options)
426
458
 
427
459
  handle_positional_args(options)
428
460
 
@@ -445,9 +477,9 @@ module ActionDispatch
445
477
  path_options = yield(path_options) if block_given?
446
478
  path = generate(path_options, path_segments || {})
447
479
 
448
- # ROUTES TODO: This can be called directly, so script_name should probably be set in the router
480
+ # ROUTES TODO: This can be called directly, so script_name should probably be set in the routes
449
481
  rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
450
- rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor]
482
+ rewritten_url << "##{Rack::Mount::Utils.escape_uri(options[:anchor].to_param.to_s)}" if options[:anchor]
451
483
 
452
484
  rewritten_url
453
485
  end
@@ -477,6 +509,8 @@ module ActionDispatch
477
509
  end
478
510
 
479
511
  dispatcher = route.app
512
+ dispatcher = dispatcher.app while dispatcher.is_a?(Mapper::Constraints)
513
+
480
514
  if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, false)
481
515
  dispatcher.prepare_params!(params)
482
516
  return params
@@ -82,6 +82,7 @@ module ActionDispatch
82
82
  #
83
83
  module UrlFor
84
84
  extend ActiveSupport::Concern
85
+ include PolymorphicRoutes
85
86
 
86
87
  included do
87
88
  # TODO: with_routing extends @controller with url_helpers, trickling down to including this module which overrides its default_url_options
@@ -128,7 +129,7 @@ module ActionDispatch
128
129
  when String
129
130
  options
130
131
  when nil, Hash
131
- _router.url_for(url_options.merge((options || {}).symbolize_keys))
132
+ _routes.url_for((options || {}).reverse_merge!(url_options).symbolize_keys)
132
133
  else
133
134
  polymorphic_url(options)
134
135
  end
@@ -1,7 +1,6 @@
1
1
  module ActionDispatch
2
2
  module Assertions
3
3
  autoload :DomAssertions, 'action_dispatch/testing/assertions/dom'
4
- autoload :ModelAssertions, 'action_dispatch/testing/assertions/model'
5
4
  autoload :ResponseAssertions, 'action_dispatch/testing/assertions/response'
6
5
  autoload :RoutingAssertions, 'action_dispatch/testing/assertions/routing'
7
6
  autoload :SelectorAssertions, 'action_dispatch/testing/assertions/selector'
@@ -11,7 +10,6 @@ module ActionDispatch
11
10
 
12
11
  included do
13
12
  include DomAssertions
14
- include ModelAssertions
15
13
  include ResponseAssertions
16
14
  include RoutingAssertions
17
15
  include SelectorAssertions
@@ -53,7 +53,6 @@ module ActionDispatch
53
53
  extras.each_key { |key| expected_options.delete key } unless extras.nil?
54
54
 
55
55
  expected_options.stringify_keys!
56
- routing_diff = expected_options.diff(request.path_parameters)
57
56
  msg = build_message(message, "The recognized options <?> did not match <?>, difference: <?>",
58
57
  request.path_parameters, expected_options, expected_options.diff(request.path_parameters))
59
58
  assert_block(msg) { request.path_parameters == expected_options }