actionpack 2.1.2 → 2.2.2

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 (200) hide show
  1. data/CHANGELOG +223 -7
  2. data/README +6 -12
  3. data/Rakefile +11 -11
  4. data/lib/action_controller.rb +9 -9
  5. data/lib/action_controller/assertions/response_assertions.rb +29 -78
  6. data/lib/action_controller/assertions/routing_assertions.rb +33 -33
  7. data/lib/action_controller/assertions/selector_assertions.rb +9 -5
  8. data/lib/action_controller/base.rb +227 -161
  9. data/lib/action_controller/benchmarking.rb +37 -24
  10. data/lib/action_controller/caching/actions.rb +53 -21
  11. data/lib/action_controller/caching/fragments.rb +10 -36
  12. data/lib/action_controller/caching/sweeping.rb +3 -3
  13. data/lib/action_controller/cgi_ext/session.rb +2 -22
  14. data/lib/action_controller/cgi_process.rb +8 -46
  15. data/lib/action_controller/components.rb +4 -1
  16. data/lib/action_controller/cookies.rb +10 -0
  17. data/lib/action_controller/dispatcher.rb +49 -15
  18. data/lib/action_controller/filters.rb +48 -10
  19. data/lib/action_controller/headers.rb +16 -14
  20. data/lib/action_controller/helpers.rb +2 -2
  21. data/lib/action_controller/http_authentication.rb +1 -1
  22. data/lib/action_controller/integration.rb +57 -60
  23. data/lib/action_controller/layout.rb +27 -53
  24. data/lib/action_controller/mime_responds.rb +5 -1
  25. data/lib/action_controller/mime_type.rb +64 -42
  26. data/lib/action_controller/mime_types.rb +2 -1
  27. data/lib/action_controller/performance_test.rb +16 -0
  28. data/lib/action_controller/polymorphic_routes.rb +16 -9
  29. data/lib/action_controller/rack_process.rb +303 -0
  30. data/lib/action_controller/request.rb +205 -97
  31. data/lib/action_controller/request_forgery_protection.rb +2 -2
  32. data/lib/action_controller/request_profiler.rb +0 -0
  33. data/lib/action_controller/rescue.rb +20 -115
  34. data/lib/action_controller/resources.rb +186 -83
  35. data/lib/action_controller/response.rb +140 -26
  36. data/lib/action_controller/routing.rb +28 -30
  37. data/lib/action_controller/routing/builder.rb +45 -54
  38. data/lib/action_controller/routing/optimisations.rb +31 -21
  39. data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
  40. data/lib/action_controller/routing/route.rb +162 -147
  41. data/lib/action_controller/routing/route_set.rb +8 -7
  42. data/lib/action_controller/routing/routing_ext.rb +4 -1
  43. data/lib/action_controller/routing/segments.rb +50 -21
  44. data/lib/action_controller/session/cookie_store.rb +3 -2
  45. data/lib/action_controller/session/drb_server.rb +7 -7
  46. data/lib/action_controller/session_management.rb +6 -2
  47. data/lib/action_controller/streaming.rb +15 -8
  48. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  49. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  50. data/lib/action_controller/test_case.rb +66 -2
  51. data/lib/action_controller/test_process.rb +71 -66
  52. data/lib/action_controller/translation.rb +13 -0
  53. data/lib/action_controller/url_rewriter.rb +90 -13
  54. data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
  55. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
  56. data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
  57. data/lib/action_controller/verification.rb +2 -2
  58. data/lib/action_pack/version.rb +1 -1
  59. data/lib/action_view.rb +19 -11
  60. data/lib/action_view/base.rb +184 -150
  61. data/lib/action_view/helpers.rb +38 -0
  62. data/lib/action_view/helpers/active_record_helper.rb +56 -27
  63. data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
  64. data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
  65. data/lib/action_view/helpers/benchmark_helper.rb +3 -3
  66. data/lib/action_view/helpers/cache_helper.rb +1 -2
  67. data/lib/action_view/helpers/capture_helper.rb +19 -44
  68. data/lib/action_view/helpers/date_helper.rb +486 -296
  69. data/lib/action_view/helpers/debug_helper.rb +20 -13
  70. data/lib/action_view/helpers/form_helper.rb +71 -30
  71. data/lib/action_view/helpers/form_options_helper.rb +15 -85
  72. data/lib/action_view/helpers/form_tag_helper.rb +61 -38
  73. data/lib/action_view/helpers/javascript_helper.rb +80 -89
  74. data/lib/action_view/helpers/number_helper.rb +179 -74
  75. data/lib/action_view/helpers/prototype_helper.rb +216 -201
  76. data/lib/action_view/helpers/record_tag_helper.rb +4 -5
  77. data/lib/action_view/helpers/sanitize_helper.rb +65 -33
  78. data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
  79. data/lib/action_view/helpers/tag_helper.rb +39 -22
  80. data/lib/action_view/helpers/text_helper.rb +212 -118
  81. data/lib/action_view/helpers/translation_helper.rb +21 -0
  82. data/lib/action_view/helpers/url_helper.rb +100 -58
  83. data/lib/action_view/inline_template.rb +13 -14
  84. data/lib/action_view/locale/en.yml +91 -0
  85. data/lib/action_view/partials.rb +100 -55
  86. data/lib/action_view/paths.rb +125 -0
  87. data/lib/action_view/renderable.rb +102 -0
  88. data/lib/action_view/renderable_partial.rb +48 -0
  89. data/lib/action_view/template.rb +90 -101
  90. data/lib/action_view/template_error.rb +11 -21
  91. data/lib/action_view/template_handler.rb +8 -28
  92. data/lib/action_view/template_handlers.rb +45 -0
  93. data/lib/action_view/template_handlers/builder.rb +5 -15
  94. data/lib/action_view/template_handlers/erb.rb +9 -6
  95. data/lib/action_view/template_handlers/rjs.rb +2 -17
  96. data/lib/action_view/test_case.rb +7 -4
  97. data/test/abstract_unit.rb +4 -1
  98. data/test/active_record_unit.rb +28 -30
  99. data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
  100. data/test/controller/action_pack_assertions_test.rb +8 -37
  101. data/test/controller/addresses_render_test.rb +0 -3
  102. data/test/controller/assert_select_test.rb +51 -24
  103. data/test/controller/base_test.rb +4 -4
  104. data/test/controller/caching_test.rb +136 -66
  105. data/test/controller/capture_test.rb +1 -21
  106. data/test/controller/cgi_test.rb +157 -10
  107. data/test/controller/components_test.rb +41 -25
  108. data/test/controller/content_type_test.rb +49 -17
  109. data/test/controller/cookie_test.rb +1 -1
  110. data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
  111. data/test/controller/dispatcher_test.rb +9 -1
  112. data/test/controller/filter_params_test.rb +2 -2
  113. data/test/controller/filters_test.rb +13 -13
  114. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  115. data/test/controller/html-scanner/node_test.rb +21 -0
  116. data/test/controller/html-scanner/sanitizer_test.rb +14 -0
  117. data/test/controller/integration_test.rb +167 -6
  118. data/test/controller/layout_test.rb +11 -68
  119. data/test/controller/logging_test.rb +46 -0
  120. data/test/controller/mime_responds_test.rb +61 -59
  121. data/test/controller/mime_type_test.rb +6 -6
  122. data/test/controller/polymorphic_routes_test.rb +37 -2
  123. data/test/controller/rack_test.rb +323 -0
  124. data/test/controller/redirect_test.rb +72 -71
  125. data/test/controller/render_test.rb +1120 -108
  126. data/test/controller/request_forgery_protection_test.rb +66 -52
  127. data/test/controller/request_test.rb +103 -146
  128. data/test/controller/rescue_test.rb +20 -24
  129. data/test/controller/resources_test.rb +408 -25
  130. data/test/controller/routing_test.rb +1774 -1774
  131. data/test/controller/send_file_test.rb +0 -4
  132. data/test/controller/session/cookie_store_test.rb +53 -1
  133. data/test/controller/test_test.rb +15 -37
  134. data/test/controller/translation_test.rb +26 -0
  135. data/test/controller/url_rewriter_test.rb +27 -28
  136. data/test/controller/view_paths_test.rb +48 -47
  137. data/test/fixtures/_top_level_partial.html.erb +1 -0
  138. data/test/fixtures/_top_level_partial_only.erb +1 -0
  139. data/test/fixtures/developers/_developer.erb +1 -0
  140. data/test/fixtures/fun/games/_game.erb +1 -0
  141. data/test/fixtures/fun/serious/games/_game.erb +1 -0
  142. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
  143. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
  144. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
  145. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
  146. data/test/fixtures/layouts/_column.html.erb +2 -0
  147. data/test/fixtures/projects/_project.erb +1 -0
  148. data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
  149. data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
  150. data/test/fixtures/replies/_reply.erb +1 -0
  151. data/test/fixtures/test/_counter.html.erb +1 -0
  152. data/test/fixtures/test/_customer.erb +1 -1
  153. data/test/fixtures/test/_customer_with_var.erb +1 -0
  154. data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
  155. data/test/fixtures/test/_local_inspector.html.erb +1 -0
  156. data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
  157. data/test/fixtures/test/hello.builder +1 -1
  158. data/test/fixtures/test/hyphen-ated.erb +1 -0
  159. data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
  160. data/test/fixtures/test/nested_layout.erb +3 -0
  161. data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
  162. data/test/fixtures/test/sub_template_raise.html.erb +1 -0
  163. data/test/fixtures/test/template.erb +1 -0
  164. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
  165. data/test/template/active_record_helper_i18n_test.rb +46 -0
  166. data/test/template/active_record_helper_test.rb +24 -24
  167. data/test/template/asset_tag_helper_test.rb +161 -29
  168. data/test/template/atom_feed_helper_test.rb +114 -5
  169. data/test/template/compiled_templates_test.rb +59 -0
  170. data/test/template/date_helper_i18n_test.rb +113 -0
  171. data/test/template/date_helper_test.rb +403 -109
  172. data/test/template/form_helper_test.rb +213 -154
  173. data/test/template/form_options_helper_test.rb +249 -897
  174. data/test/template/form_tag_helper_test.rb +80 -32
  175. data/test/template/javascript_helper_test.rb +17 -18
  176. data/test/template/number_helper_i18n_test.rb +54 -0
  177. data/test/template/number_helper_test.rb +43 -13
  178. data/test/template/prototype_helper_test.rb +101 -84
  179. data/test/template/record_tag_helper_test.rb +24 -20
  180. data/test/template/render_test.rb +193 -0
  181. data/test/template/sanitize_helper_test.rb +3 -3
  182. data/test/template/tag_helper_test.rb +34 -14
  183. data/test/template/text_helper_test.rb +83 -9
  184. data/test/template/translation_helper_test.rb +28 -0
  185. data/test/template/url_helper_test.rb +55 -18
  186. metadata +57 -18
  187. data/lib/action_view/helpers/javascripts/controls.js +0 -963
  188. data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
  189. data/lib/action_view/helpers/javascripts/effects.js +0 -1120
  190. data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
  191. data/lib/action_view/partial_template.rb +0 -70
  192. data/lib/action_view/template_finder.rb +0 -177
  193. data/lib/action_view/template_handlers/compilable.rb +0 -128
  194. data/test/controller/custom_handler_test.rb +0 -45
  195. data/test/controller/new_render_test.rb +0 -945
  196. data/test/fixtures/test/block_content_for.erb +0 -2
  197. data/test/fixtures/test/erb_content_for.erb +0 -2
  198. data/test/template/deprecated_erb_variable_test.rb +0 -9
  199. data/test/template/template_finder_test.rb +0 -73
  200. data/test/template/template_object_test.rb +0 -95
@@ -3,6 +3,8 @@ require 'action_controller/test_case'
3
3
 
4
4
  module ActionController #:nodoc:
5
5
  class Base
6
+ attr_reader :assigns
7
+
6
8
  # Process a test request called with a TestRequest object.
7
9
  def self.process_test(request)
8
10
  new.process_test(request)
@@ -14,7 +16,12 @@ module ActionController #:nodoc:
14
16
 
15
17
  def process_with_test(*args)
16
18
  returning process_without_test(*args) do
17
- add_variables_to_assigns
19
+ @assigns = {}
20
+ (instance_variable_names - @@protected_instance_variables).each do |var|
21
+ value = instance_variable_get(var)
22
+ @assigns[var[1..-1]] = value
23
+ response.template.assigns[var[1..-1]] = value if response
24
+ end
18
25
  end
19
26
  end
20
27
 
@@ -23,7 +30,7 @@ module ActionController #:nodoc:
23
30
 
24
31
  class TestRequest < AbstractRequest #:nodoc:
25
32
  attr_accessor :cookies, :session_options
26
- attr_accessor :query_parameters, :request_parameters, :path, :session, :env
33
+ attr_accessor :query_parameters, :request_parameters, :path, :session
27
34
  attr_accessor :host, :user_agent
28
35
 
29
36
  def initialize(query_parameters = nil, request_parameters = nil, session = nil)
@@ -42,7 +49,7 @@ module ActionController #:nodoc:
42
49
  end
43
50
 
44
51
  # Wraps raw_post in a StringIO.
45
- def body
52
+ def body_stream #:nodoc:
46
53
  StringIO.new(raw_post)
47
54
  end
48
55
 
@@ -54,7 +61,7 @@ module ActionController #:nodoc:
54
61
 
55
62
  def port=(number)
56
63
  @env["SERVER_PORT"] = number.to_i
57
- @port_as_int = nil
64
+ port(true)
58
65
  end
59
66
 
60
67
  def action=(action_name)
@@ -68,6 +75,8 @@ module ActionController #:nodoc:
68
75
  @env["REQUEST_URI"] = value
69
76
  @request_uri = nil
70
77
  @path = nil
78
+ request_uri(true)
79
+ path(true)
71
80
  end
72
81
 
73
82
  def request_uri=(uri)
@@ -77,21 +86,26 @@ module ActionController #:nodoc:
77
86
 
78
87
  def accept=(mime_types)
79
88
  @env["HTTP_ACCEPT"] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
89
+ accepts(true)
80
90
  end
81
91
 
82
- def remote_addr=(addr)
83
- @env['REMOTE_ADDR'] = addr
92
+ def if_modified_since=(last_modified)
93
+ @env["HTTP_IF_MODIFIED_SINCE"] = last_modified
84
94
  end
85
95
 
86
- def remote_addr
87
- @env['REMOTE_ADDR']
96
+ def if_none_match=(etag)
97
+ @env["HTTP_IF_NONE_MATCH"] = etag
98
+ end
99
+
100
+ def remote_addr=(addr)
101
+ @env['REMOTE_ADDR'] = addr
88
102
  end
89
103
 
90
- def request_uri
104
+ def request_uri(*args)
91
105
  @request_uri || super
92
106
  end
93
107
 
94
- def path
108
+ def path(*args)
95
109
  @path || super
96
110
  end
97
111
 
@@ -113,17 +127,13 @@ module ActionController #:nodoc:
113
127
  end
114
128
  end
115
129
  @parameters = nil # reset TestRequest#parameters to use the new path_parameters
116
- end
117
-
130
+ end
131
+
118
132
  def recycle!
119
133
  self.request_parameters = {}
120
134
  self.query_parameters = {}
121
135
  self.path_parameters = {}
122
- @request_method, @accepts, @content_type = nil, nil, nil
123
- end
124
-
125
- def referer
126
- @env["HTTP_REFERER"]
136
+ unmemoize_all
127
137
  end
128
138
 
129
139
  private
@@ -135,7 +145,7 @@ module ActionController #:nodoc:
135
145
  @host = "test.host"
136
146
  @request_uri = "/"
137
147
  @user_agent = "Rails Testing"
138
- self.remote_addr = "0.0.0.0"
148
+ self.remote_addr = "0.0.0.0"
139
149
  @env["SERVER_PORT"] = 80
140
150
  @env['REQUEST_METHOD'] = "GET"
141
151
  end
@@ -157,16 +167,16 @@ module ActionController #:nodoc:
157
167
  module TestResponseBehavior #:nodoc:
158
168
  # The response code of the request
159
169
  def response_code
160
- headers['Status'][0,3].to_i rescue 0
170
+ status[0,3].to_i rescue 0
161
171
  end
162
-
172
+
163
173
  # Returns a String to ensure compatibility with Net::HTTPResponse
164
174
  def code
165
- headers['Status'].to_s.split(' ')[0]
175
+ status.to_s.split(' ')[0]
166
176
  end
167
177
 
168
178
  def message
169
- headers['Status'].to_s.split(' ',2)[1]
179
+ status.to_s.split(' ',2)[1]
170
180
  end
171
181
 
172
182
  # Was the response successful?
@@ -205,24 +215,13 @@ module ActionController #:nodoc:
205
215
  p.match(redirect_url) != nil
206
216
  end
207
217
 
208
- # Returns the template path of the file which was used to
209
- # render this response (or nil)
210
- def rendered_file(with_controller=false)
211
- unless template.first_render.nil?
212
- unless with_controller
213
- template.first_render
214
- else
215
- template.first_render.split('/').last || template.first_render
216
- end
217
- end
218
- end
219
-
220
- # Was this template rendered by a file?
221
- def rendered_with_file?
222
- !rendered_file.nil?
218
+ # Returns the template of the file which was used to
219
+ # render this response (or nil)
220
+ def rendered_template
221
+ template.instance_variable_get(:@_first_render)
223
222
  end
224
223
 
225
- # A shortcut to the flash. Returns an empyt hash if no session flash exists.
224
+ # A shortcut to the flash. Returns an empty hash if no session flash exists.
226
225
  def flash
227
226
  session['flash'] || {}
228
227
  end
@@ -254,11 +253,11 @@ module ActionController #:nodoc:
254
253
 
255
254
  # Does the specified template object exist?
256
255
  def has_template_object?(name=nil)
257
- !template_objects[name].nil?
256
+ !template_objects[name].nil?
258
257
  end
259
258
 
260
259
  # Returns the response cookies, converted to a Hash of (name => CGI::Cookie) pairs
261
- #
260
+ #
262
261
  # assert_equal ['AuthorOfNewPage'], r.cookies['author'].value
263
262
  def cookies
264
263
  headers['cookie'].inject({}) { |hash, cookie| hash[cookie.name] = cookie; hash }
@@ -277,8 +276,19 @@ module ActionController #:nodoc:
277
276
  end
278
277
  end
279
278
 
280
- class TestResponse < AbstractResponse #:nodoc:
279
+ # Integration test methods such as ActionController::Integration::Session#get
280
+ # and ActionController::Integration::Session#post return objects of class
281
+ # TestResponse, which represent the HTTP response results of the requested
282
+ # controller actions.
283
+ #
284
+ # See AbstractResponse for more information on controller response objects.
285
+ class TestResponse < AbstractResponse
281
286
  include TestResponseBehavior
287
+
288
+ def recycle!
289
+ headers.delete('ETag')
290
+ headers.delete('Last-Modified')
291
+ end
282
292
  end
283
293
 
284
294
  class TestSession #:nodoc:
@@ -324,7 +334,7 @@ module ActionController #:nodoc:
324
334
  #
325
335
  # Usage example, within a functional test:
326
336
  # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/spongebob.png', 'image/png')
327
- #
337
+ #
328
338
  # Pass a true third parameter to ensure the uploaded file is opened in binary mode (only required for Windows):
329
339
  # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/spongebob.png', 'image/png', :binary)
330
340
  require 'tempfile'
@@ -352,13 +362,14 @@ module ActionController #:nodoc:
352
362
  alias local_path path
353
363
 
354
364
  def method_missing(method_name, *args, &block) #:nodoc:
355
- @tempfile.send!(method_name, *args, &block)
365
+ @tempfile.__send__(method_name, *args, &block)
356
366
  end
357
367
  end
358
368
 
359
369
  module TestProcess
360
370
  def self.included(base)
361
371
  # execute the request simulating a specific HTTP method and set/volley the response
372
+ # TODO: this should be un-DRY'ed for the sake of API documentation.
362
373
  %w( get post put delete head ).each do |method|
363
374
  base.class_eval <<-EOV, __FILE__, __LINE__
364
375
  def #{method}(action, parameters = nil, session = nil, flash = nil)
@@ -380,9 +391,11 @@ module ActionController #:nodoc:
380
391
  end
381
392
 
382
393
  @request.recycle!
394
+ @response.recycle!
383
395
 
384
396
  @html_document = nil
385
397
  @request.env['REQUEST_METHOD'] ||= "GET"
398
+
386
399
  @request.action = action.to_s
387
400
 
388
401
  parameters ||= {}
@@ -397,32 +410,21 @@ module ActionController #:nodoc:
397
410
  def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
398
411
  @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
399
412
  @request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
400
- returning send!(request_method, action, parameters, session, flash) do
413
+ returning __send__(request_method, action, parameters, session, flash) do
401
414
  @request.env.delete 'HTTP_X_REQUESTED_WITH'
402
415
  @request.env.delete 'HTTP_ACCEPT'
403
416
  end
404
417
  end
405
418
  alias xhr :xml_http_request
406
419
 
407
- def follow_redirect
408
- redirected_controller = @response.redirected_to[:controller]
409
- if redirected_controller && redirected_controller != @controller.controller_name
410
- raise "Can't follow redirects outside of current controller (from #{@controller.controller_name} to #{redirected_controller})"
420
+ def assigns(key = nil)
421
+ if key.nil?
422
+ @response.template.assigns
423
+ else
424
+ @response.template.assigns[key.to_s]
411
425
  end
412
-
413
- get(@response.redirected_to.delete(:action), @response.redirected_to.stringify_keys)
414
426
  end
415
427
 
416
- deprecate :follow_redirect => "If you wish to follow redirects, you should use integration tests"
417
-
418
- def assigns(key = nil)
419
- if key.nil?
420
- @response.template.assigns
421
- else
422
- @response.template.assigns[key.to_s]
423
- end
424
- end
425
-
426
428
  def session
427
429
  @response.session
428
430
  end
@@ -441,7 +443,7 @@ module ActionController #:nodoc:
441
443
 
442
444
  def build_request_uri(action, parameters)
443
445
  unless @request.env['REQUEST_URI']
444
- options = @controller.send!(:rewrite_options, parameters)
446
+ options = @controller.__send__(:rewrite_options, parameters)
445
447
  options.update(:only_path => true, :action => action)
446
448
 
447
449
  url = ActionController::UrlRewriter.new(@request, parameters)
@@ -463,10 +465,13 @@ module ActionController #:nodoc:
463
465
  end
464
466
 
465
467
  def method_missing(selector, *args)
466
- return @controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
467
- return super
468
+ if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
469
+ @controller.send(selector, *args)
470
+ else
471
+ super
472
+ end
468
473
  end
469
-
474
+
470
475
  # Shortcut for <tt>ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + path, type)</tt>:
471
476
  #
472
477
  # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png')
@@ -477,7 +482,7 @@ module ActionController #:nodoc:
477
482
  # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png', :binary)
478
483
  def fixture_file_upload(path, mime_type = nil, binary = false)
479
484
  ActionController::TestUploadedFile.new(
480
- Test::Unit::TestCase.respond_to?(:fixture_path) ? Test::Unit::TestCase.fixture_path + path : path,
485
+ Test::Unit::TestCase.respond_to?(:fixture_path) ? Test::Unit::TestCase.fixture_path + path : path,
481
486
  mime_type,
482
487
  binary
483
488
  )
@@ -485,7 +490,7 @@ module ActionController #:nodoc:
485
490
 
486
491
  # A helper to make it easier to test different route configurations.
487
492
  # This method temporarily replaces ActionController::Routing::Routes
488
- # with a new RouteSet instance.
493
+ # with a new RouteSet instance.
489
494
  #
490
495
  # The new instance is yielded to the passed block. Typically the block
491
496
  # will create some routes using <tt>map.draw { map.connect ... }</tt>:
@@ -0,0 +1,13 @@
1
+ module ActionController
2
+ module Translation
3
+ def translate(*args)
4
+ I18n.translate *args
5
+ end
6
+ alias :t :translate
7
+
8
+ def localize(*args)
9
+ I18n.localize *args
10
+ end
11
+ alias :l :localize
12
+ end
13
+ end
@@ -1,19 +1,96 @@
1
1
  module ActionController
2
- # Write URLs from arbitrary places in your codebase, such as your mailers.
2
+ # In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse
3
+ # is also possible: an URL can be generated from one of your routing definitions.
4
+ # URL generation functionality is centralized in this module.
3
5
  #
4
- # Example:
6
+ # See ActionController::Routing and ActionController::Resources for general
7
+ # information about routing and routes.rb.
5
8
  #
6
- # class MyMailer
7
- # include ActionController::UrlWriter
8
- # default_url_options[:host] = 'www.basecamphq.com'
9
+ # <b>Tip:</b> If you need to generate URLs from your models or some other place,
10
+ # then ActionController::UrlWriter is what you're looking for. Read on for
11
+ # an introduction.
9
12
  #
10
- # def signup_url(token)
11
- # url_for(:controller => 'signup', action => 'index', :token => token)
13
+ # == URL generation from parameters
14
+ #
15
+ # As you may know, some functions - such as ActionController::Base#url_for
16
+ # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
17
+ # of parameters. For example, you've probably had the chance to write code
18
+ # like this in one of your views:
19
+ #
20
+ # <%= link_to('Click here', :controller => 'users',
21
+ # :action => 'new', :message => 'Welcome!') %>
22
+ #
23
+ # #=> Generates a link to: /users/new?message=Welcome%21
24
+ #
25
+ # link_to, and all other functions that require URL generation functionality,
26
+ # actually use ActionController::UrlWriter under the hood. And in particular,
27
+ # they use the ActionController::UrlWriter#url_for method. One can generate
28
+ # the same path as the above example by using the following code:
29
+ #
30
+ # include UrlWriter
31
+ # url_for(:controller => 'users',
32
+ # :action => 'new',
33
+ # :message => 'Welcome!',
34
+ # :only_path => true)
35
+ # # => "/users/new?message=Welcome%21"
36
+ #
37
+ # Notice the <tt>:only_path => true</tt> part. This is because UrlWriter has no
38
+ # information about the website hostname that your Rails app is serving. So if you
39
+ # want to include the hostname as well, then you must also pass the <tt>:host</tt>
40
+ # argument:
41
+ #
42
+ # include UrlWriter
43
+ # url_for(:controller => 'users',
44
+ # :action => 'new',
45
+ # :message => 'Welcome!',
46
+ # :host => 'www.example.com') # Changed this.
47
+ # # => "http://www.example.com/users/new?message=Welcome%21"
48
+ #
49
+ # By default, all controllers and views have access to a special version of url_for,
50
+ # that already knows what the current hostname is. So if you use url_for in your
51
+ # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
52
+ # argument.
53
+ #
54
+ # For convenience reasons, mailers provide a shortcut for ActionController::UrlWriter#url_for.
55
+ # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlWriter#url_for'
56
+ # in full. However, mailers don't have hostname information, and what's why you'll still
57
+ # have to specify the <tt>:host</tt> argument when generating URLs in mailers.
58
+ #
59
+ #
60
+ # == URL generation for named routes
61
+ #
62
+ # UrlWriter also allows one to access methods that have been auto-generated from
63
+ # named routes. For example, suppose that you have a 'users' resource in your
64
+ # <b>routes.rb</b>:
65
+ #
66
+ # map.resources :users
67
+ #
68
+ # This generates, among other things, the method <tt>users_path</tt>. By default,
69
+ # this method is accessible from your controllers, views and mailers. If you need
70
+ # to access this auto-generated method from other places (such as a model), then
71
+ # you can do that in two ways.
72
+ #
73
+ # The first way is to include ActionController::UrlWriter in your class:
74
+ #
75
+ # class User < ActiveRecord::Base
76
+ # include ActionController::UrlWriter # !!!
77
+ #
78
+ # def name=(value)
79
+ # write_attribute('name', value)
80
+ # write_attribute('base_uri', users_path) # !!!
12
81
  # end
13
- # end
82
+ # end
14
83
  #
15
- # In addition to providing +url_for+, named routes are also accessible after
16
- # including UrlWriter.
84
+ # The second way is to access them through ActionController::UrlWriter.
85
+ # The autogenerated named routes methods are available as class methods:
86
+ #
87
+ # class User < ActiveRecord::Base
88
+ # def name=(value)
89
+ # write_attribute('name', value)
90
+ # path = ActionController::UrlWriter.users_path # !!!
91
+ # write_attribute('base_uri', path) # !!!
92
+ # end
93
+ # end
17
94
  module UrlWriter
18
95
  # The default options for urls written by this writer. Typically a <tt>:host</tt>
19
96
  # pair is provided.
@@ -37,7 +114,7 @@ module ActionController
37
114
  # * <tt>:port</tt> - Optionally specify the port to connect to.
38
115
  # * <tt>:anchor</tt> - An anchor name to be appended to the path.
39
116
  # * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the
40
- # +relative_url_root+ set in ActionController::AbstractRequest.relative_url_root.
117
+ # +relative_url_root+ set in ActionController::Base.relative_url_root.
41
118
  # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
42
119
  #
43
120
  # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
@@ -67,7 +144,7 @@ module ActionController
67
144
  [:protocol, :host, :port, :skip_relative_url_root].each { |k| options.delete(k) }
68
145
  end
69
146
  trailing_slash = options.delete(:trailing_slash) if options.key?(:trailing_slash)
70
- url << ActionController::AbstractRequest.relative_url_root.to_s unless options[:skip_relative_url_root]
147
+ url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root]
71
148
  anchor = "##{CGI.escape options.delete(:anchor).to_param.to_s}" if options[:anchor]
72
149
  generated = Routing::Routes.generate(options, {})
73
150
  url << (trailing_slash ? generated.sub(/\?|\z/) { "/" + $& } : generated)
@@ -108,7 +185,7 @@ module ActionController
108
185
  end
109
186
 
110
187
  path = rewrite_path(options)
111
- rewritten_url << @request.relative_url_root.to_s unless options[:skip_relative_url_root]
188
+ rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root]
112
189
  rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
113
190
  rewritten_url << "##{options[:anchor]}" if options[:anchor]
114
191