actionpack 3.2.22.5 → 4.0.0.beta1

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 (265) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +641 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -288
  5. data/lib/abstract_controller.rb +1 -8
  6. data/lib/abstract_controller/asset_paths.rb +2 -2
  7. data/lib/abstract_controller/base.rb +39 -37
  8. data/lib/abstract_controller/callbacks.rb +101 -82
  9. data/lib/abstract_controller/collector.rb +7 -3
  10. data/lib/abstract_controller/helpers.rb +23 -11
  11. data/lib/abstract_controller/layouts.rb +68 -73
  12. data/lib/abstract_controller/logger.rb +1 -2
  13. data/lib/abstract_controller/rendering.rb +22 -13
  14. data/lib/abstract_controller/translation.rb +16 -1
  15. data/lib/abstract_controller/url_for.rb +6 -6
  16. data/lib/abstract_controller/view_paths.rb +1 -1
  17. data/lib/action_controller.rb +15 -6
  18. data/lib/action_controller/base.rb +46 -22
  19. data/lib/action_controller/caching.rb +46 -33
  20. data/lib/action_controller/caching/fragments.rb +23 -53
  21. data/lib/action_controller/deprecated.rb +5 -1
  22. data/lib/action_controller/deprecated/integration_test.rb +3 -0
  23. data/lib/action_controller/log_subscriber.rb +11 -8
  24. data/lib/action_controller/metal.rb +16 -30
  25. data/lib/action_controller/metal/conditional_get.rb +76 -32
  26. data/lib/action_controller/metal/data_streaming.rb +20 -26
  27. data/lib/action_controller/metal/exceptions.rb +19 -6
  28. data/lib/action_controller/metal/flash.rb +24 -9
  29. data/lib/action_controller/metal/force_ssl.rb +32 -9
  30. data/lib/action_controller/metal/head.rb +25 -4
  31. data/lib/action_controller/metal/helpers.rb +6 -9
  32. data/lib/action_controller/metal/hide_actions.rb +1 -2
  33. data/lib/action_controller/metal/http_authentication.rb +105 -87
  34. data/lib/action_controller/metal/implicit_render.rb +1 -1
  35. data/lib/action_controller/metal/instrumentation.rb +2 -1
  36. data/lib/action_controller/metal/live.rb +141 -0
  37. data/lib/action_controller/metal/mime_responds.rb +161 -47
  38. data/lib/action_controller/metal/params_wrapper.rb +112 -74
  39. data/lib/action_controller/metal/rack_delegation.rb +9 -3
  40. data/lib/action_controller/metal/redirecting.rb +15 -20
  41. data/lib/action_controller/metal/renderers.rb +11 -9
  42. data/lib/action_controller/metal/rendering.rb +8 -0
  43. data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
  44. data/lib/action_controller/metal/responder.rb +20 -19
  45. data/lib/action_controller/metal/streaming.rb +12 -18
  46. data/lib/action_controller/metal/strong_parameters.rb +516 -0
  47. data/lib/action_controller/metal/testing.rb +13 -18
  48. data/lib/action_controller/metal/url_for.rb +27 -25
  49. data/lib/action_controller/model_naming.rb +12 -0
  50. data/lib/action_controller/railtie.rb +33 -17
  51. data/lib/action_controller/railties/helpers.rb +22 -0
  52. data/lib/action_controller/record_identifier.rb +18 -72
  53. data/lib/action_controller/test_case.rb +215 -123
  54. data/lib/action_controller/vendor/html-scanner.rb +4 -19
  55. data/lib/action_dispatch.rb +27 -19
  56. data/lib/action_dispatch/http/cache.rb +63 -11
  57. data/lib/action_dispatch/http/filter_parameters.rb +18 -8
  58. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  59. data/lib/action_dispatch/http/headers.rb +27 -19
  60. data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
  61. data/lib/action_dispatch/http/mime_type.rb +145 -113
  62. data/lib/action_dispatch/http/mime_types.rb +1 -1
  63. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  64. data/lib/action_dispatch/http/parameters.rb +12 -5
  65. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  66. data/lib/action_dispatch/http/request.rb +49 -18
  67. data/lib/action_dispatch/http/response.rb +129 -35
  68. data/lib/action_dispatch/http/upload.rb +60 -17
  69. data/lib/action_dispatch/http/url.rb +53 -31
  70. data/lib/action_dispatch/journey.rb +5 -0
  71. data/lib/action_dispatch/journey/backwards.rb +5 -0
  72. data/lib/action_dispatch/journey/formatter.rb +146 -0
  73. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  74. data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
  75. data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
  76. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  77. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  78. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  79. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  80. data/lib/action_dispatch/journey/nodes/node.rb +124 -0
  81. data/lib/action_dispatch/journey/parser.rb +206 -0
  82. data/lib/action_dispatch/journey/parser.y +47 -0
  83. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  84. data/lib/action_dispatch/journey/path/pattern.rb +196 -0
  85. data/lib/action_dispatch/journey/route.rb +116 -0
  86. data/lib/action_dispatch/journey/router.rb +164 -0
  87. data/lib/action_dispatch/journey/router/strexp.rb +24 -0
  88. data/lib/action_dispatch/journey/router/utils.rb +54 -0
  89. data/lib/action_dispatch/journey/routes.rb +75 -0
  90. data/lib/action_dispatch/journey/scanner.rb +61 -0
  91. data/lib/action_dispatch/journey/visitors.rb +189 -0
  92. data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
  93. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  94. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  95. data/lib/action_dispatch/middleware/callbacks.rb +9 -4
  96. data/lib/action_dispatch/middleware/cookies.rb +168 -57
  97. data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
  98. data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
  99. data/lib/action_dispatch/middleware/flash.rb +58 -58
  100. data/lib/action_dispatch/middleware/params_parser.rb +14 -29
  101. data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
  102. data/lib/action_dispatch/middleware/reloader.rb +6 -6
  103. data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
  104. data/lib/action_dispatch/middleware/request_id.rb +2 -6
  105. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  106. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  107. data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
  108. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  109. data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
  110. data/lib/action_dispatch/middleware/ssl.rb +70 -0
  111. data/lib/action_dispatch/middleware/stack.rb +6 -1
  112. data/lib/action_dispatch/middleware/static.rb +5 -24
  113. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
  114. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
  115. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
  116. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
  117. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
  122. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
  124. data/lib/action_dispatch/railtie.rb +16 -6
  125. data/lib/action_dispatch/request/session.rb +181 -0
  126. data/lib/action_dispatch/routing.rb +41 -40
  127. data/lib/action_dispatch/routing/inspector.rb +240 -0
  128. data/lib/action_dispatch/routing/mapper.rb +501 -273
  129. data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
  130. data/lib/action_dispatch/routing/redirection.rb +46 -29
  131. data/lib/action_dispatch/routing/route_set.rb +203 -164
  132. data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
  133. data/lib/action_dispatch/routing/url_for.rb +48 -33
  134. data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
  135. data/lib/action_dispatch/testing/assertions/response.rb +32 -40
  136. data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
  137. data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
  138. data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
  139. data/lib/action_dispatch/testing/integration.rb +41 -22
  140. data/lib/action_dispatch/testing/test_process.rb +9 -6
  141. data/lib/action_dispatch/testing/test_request.rb +7 -3
  142. data/lib/action_pack.rb +1 -1
  143. data/lib/action_pack/version.rb +4 -4
  144. data/lib/action_view.rb +17 -8
  145. data/lib/action_view/base.rb +15 -34
  146. data/lib/action_view/buffers.rb +1 -1
  147. data/lib/action_view/context.rb +4 -4
  148. data/lib/action_view/dependency_tracker.rb +91 -0
  149. data/lib/action_view/digestor.rb +85 -0
  150. data/lib/action_view/flows.rb +1 -4
  151. data/lib/action_view/helpers.rb +2 -4
  152. data/lib/action_view/helpers/active_model_helper.rb +3 -4
  153. data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
  154. data/lib/action_view/helpers/asset_url_helper.rb +354 -0
  155. data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
  156. data/lib/action_view/helpers/cache_helper.rb +150 -18
  157. data/lib/action_view/helpers/capture_helper.rb +42 -29
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -2
  159. data/lib/action_view/helpers/date_helper.rb +268 -247
  160. data/lib/action_view/helpers/debug_helper.rb +10 -11
  161. data/lib/action_view/helpers/form_helper.rb +904 -547
  162. data/lib/action_view/helpers/form_options_helper.rb +341 -166
  163. data/lib/action_view/helpers/form_tag_helper.rb +188 -88
  164. data/lib/action_view/helpers/javascript_helper.rb +23 -16
  165. data/lib/action_view/helpers/number_helper.rb +148 -354
  166. data/lib/action_view/helpers/output_safety_helper.rb +3 -3
  167. data/lib/action_view/helpers/record_tag_helper.rb +17 -22
  168. data/lib/action_view/helpers/rendering_helper.rb +2 -4
  169. data/lib/action_view/helpers/sanitize_helper.rb +3 -6
  170. data/lib/action_view/helpers/tag_helper.rb +43 -37
  171. data/lib/action_view/helpers/tags.rb +39 -0
  172. data/lib/action_view/helpers/tags/base.rb +148 -0
  173. data/lib/action_view/helpers/tags/check_box.rb +64 -0
  174. data/lib/action_view/helpers/tags/checkable.rb +16 -0
  175. data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
  176. data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
  177. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
  178. data/lib/action_view/helpers/tags/collection_select.rb +28 -0
  179. data/lib/action_view/helpers/tags/color_field.rb +25 -0
  180. data/lib/action_view/helpers/tags/date_field.rb +13 -0
  181. data/lib/action_view/helpers/tags/date_select.rb +72 -0
  182. data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
  183. data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
  184. data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
  185. data/lib/action_view/helpers/tags/email_field.rb +8 -0
  186. data/lib/action_view/helpers/tags/file_field.rb +8 -0
  187. data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
  188. data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
  189. data/lib/action_view/helpers/tags/label.rb +65 -0
  190. data/lib/action_view/helpers/tags/month_field.rb +13 -0
  191. data/lib/action_view/helpers/tags/number_field.rb +18 -0
  192. data/lib/action_view/helpers/tags/password_field.rb +12 -0
  193. data/lib/action_view/helpers/tags/radio_button.rb +31 -0
  194. data/lib/action_view/helpers/tags/range_field.rb +8 -0
  195. data/lib/action_view/helpers/tags/search_field.rb +24 -0
  196. data/lib/action_view/helpers/tags/select.rb +41 -0
  197. data/lib/action_view/helpers/tags/tel_field.rb +8 -0
  198. data/lib/action_view/helpers/tags/text_area.rb +18 -0
  199. data/lib/action_view/helpers/tags/text_field.rb +29 -0
  200. data/lib/action_view/helpers/tags/time_field.rb +13 -0
  201. data/lib/action_view/helpers/tags/time_select.rb +8 -0
  202. data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
  203. data/lib/action_view/helpers/tags/url_field.rb +8 -0
  204. data/lib/action_view/helpers/tags/week_field.rb +13 -0
  205. data/lib/action_view/helpers/text_helper.rb +126 -113
  206. data/lib/action_view/helpers/translation_helper.rb +32 -16
  207. data/lib/action_view/helpers/url_helper.rb +200 -271
  208. data/lib/action_view/locale/en.yml +1 -105
  209. data/lib/action_view/log_subscriber.rb +6 -4
  210. data/lib/action_view/lookup_context.rb +15 -39
  211. data/lib/action_view/model_naming.rb +12 -0
  212. data/lib/action_view/path_set.rb +9 -39
  213. data/lib/action_view/railtie.rb +6 -22
  214. data/lib/action_view/record_identifier.rb +84 -0
  215. data/lib/action_view/renderer/abstract_renderer.rb +10 -19
  216. data/lib/action_view/renderer/partial_renderer.rb +144 -81
  217. data/lib/action_view/renderer/renderer.rb +2 -19
  218. data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
  219. data/lib/action_view/renderer/template_renderer.rb +14 -13
  220. data/lib/action_view/routing_url_for.rb +107 -0
  221. data/lib/action_view/template.rb +22 -21
  222. data/lib/action_view/template/error.rb +22 -12
  223. data/lib/action_view/template/handlers.rb +12 -9
  224. data/lib/action_view/template/handlers/builder.rb +1 -1
  225. data/lib/action_view/template/handlers/erb.rb +11 -16
  226. data/lib/action_view/template/handlers/raw.rb +11 -0
  227. data/lib/action_view/template/resolver.rb +111 -83
  228. data/lib/action_view/template/text.rb +12 -8
  229. data/lib/action_view/template/types.rb +57 -0
  230. data/lib/action_view/test_case.rb +66 -43
  231. data/lib/action_view/testing/resolvers.rb +3 -2
  232. data/lib/action_view/vendor/html-scanner.rb +20 -0
  233. data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
  234. data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
  235. data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
  236. data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
  237. data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
  238. data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
  239. metadata +135 -125
  240. data/lib/action_controller/caching/actions.rb +0 -185
  241. data/lib/action_controller/caching/pages.rb +0 -187
  242. data/lib/action_controller/caching/sweeping.rb +0 -97
  243. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  244. data/lib/action_controller/metal/compatibility.rb +0 -65
  245. data/lib/action_controller/metal/session_management.rb +0 -14
  246. data/lib/action_controller/railties/paths.rb +0 -25
  247. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  248. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  249. data/lib/action_dispatch/middleware/head.rb +0 -18
  250. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  251. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  252. data/lib/action_view/asset_paths.rb +0 -142
  253. data/lib/action_view/helpers/asset_paths.rb +0 -7
  254. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  255. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  256. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  257. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  258. data/lib/sprockets/assets.rake +0 -99
  259. data/lib/sprockets/bootstrap.rb +0 -37
  260. data/lib/sprockets/compressors.rb +0 -83
  261. data/lib/sprockets/helpers.rb +0 -6
  262. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  263. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  264. data/lib/sprockets/railtie.rb +0 -62
  265. data/lib/sprockets/static_compiler.rb +0 -56
@@ -8,52 +8,54 @@ module AbstractController
8
8
  include ActiveSupport::Callbacks
9
9
 
10
10
  included do
11
- define_callbacks :process_action, :terminator => "response_body"
11
+ define_callbacks :process_action, :terminator => "response_body", :skip_after_callbacks_if_terminated => true
12
12
  end
13
13
 
14
14
  # Override AbstractController::Base's process_action to run the
15
15
  # process_action callbacks around the normal behavior.
16
16
  def process_action(*args)
17
- run_callbacks(:process_action, action_name) do
17
+ run_callbacks(:process_action) do
18
18
  super
19
19
  end
20
20
  end
21
21
 
22
22
  module ClassMethods
23
23
  # If :only or :except are used, convert the options into the
24
- # primitive form (:per_key) used by ActiveSupport::Callbacks.
24
+ # :unless and :if options of ActiveSupport::Callbacks.
25
25
  # The basic idea is that :only => :index gets converted to
26
- # :if => proc {|c| c.action_name == "index" }, but that the
27
- # proc is only evaluated once per action for the lifetime of
28
- # a Rails process.
26
+ # :if => proc {|c| c.action_name == "index" }.
29
27
  #
30
28
  # ==== Options
31
29
  # * <tt>only</tt> - The callback should be run only for this action
32
30
  # * <tt>except</tt> - The callback should be run for all actions except this action
33
31
  def _normalize_callback_options(options)
34
- if only = options[:only]
35
- only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ")
36
- options[:per_key] = {:if => only}
37
- end
38
- if except = options[:except]
39
- except = Array(except).map {|e| "action_name == '#{e}'"}.join(" || ")
40
- options[:per_key] = {:unless => except}
32
+ _normalize_callback_option(options, :only, :if)
33
+ _normalize_callback_option(options, :except, :unless)
34
+ end
35
+
36
+ def _normalize_callback_option(options, from, to) # :nodoc:
37
+ if from = options[from]
38
+ from = Array(from).map {|o| "action_name == '#{o}'"}.join(" || ")
39
+ options[to] = Array(options[to]) << from
41
40
  end
42
41
  end
43
42
 
44
- # Skip before, after, and around filters matching any of the names
43
+ # Skip before, after, and around action callbacks matching any of the names
44
+ # Aliased as skip_filter.
45
45
  #
46
46
  # ==== Parameters
47
47
  # * <tt>names</tt> - A list of valid names that could be used for
48
48
  # callbacks. Note that skipping uses Ruby equality, so it's
49
49
  # impossible to skip a callback defined using an anonymous proc
50
50
  # using #skip_filter
51
- def skip_filter(*names, &blk)
52
- skip_before_filter(*names)
53
- skip_after_filter(*names)
54
- skip_around_filter(*names)
51
+ def skip_action_callback(*names)
52
+ skip_before_action(*names)
53
+ skip_after_action(*names)
54
+ skip_around_action(*names)
55
55
  end
56
56
 
57
+ alias_method :skip_filter, :skip_action_callback
58
+
57
59
  # Take callback names and an optional callback proc, normalize them,
58
60
  # then call the block with each callback. This allows us to abstract
59
61
  # the normalization across several methods that use it.
@@ -66,7 +68,7 @@ module AbstractController
66
68
  # ==== Block Parameters
67
69
  # * <tt>name</tt> - The callback to be added
68
70
  # * <tt>options</tt> - A hash of options to be used when adding the callback
69
- def _insert_callbacks(callbacks, block)
71
+ def _insert_callbacks(callbacks, block = nil)
70
72
  options = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
71
73
  _normalize_callback_options(options)
72
74
  callbacks.push(block) if block
@@ -76,121 +78,138 @@ module AbstractController
76
78
  end
77
79
 
78
80
  ##
79
- # :method: before_filter
81
+ # :method: before_action
80
82
  #
81
- # :call-seq: before_filter(names, block)
83
+ # :call-seq: before_action(names, block)
82
84
  #
83
- # Append a before filter. See _insert_callbacks for parameter details.
85
+ # Append a callback before actions. See _insert_callbacks for parameter details.
86
+ # Aliased as before_filter.
84
87
 
85
88
  ##
86
- # :method: prepend_before_filter
89
+ # :method: prepend_before_action
87
90
  #
88
- # :call-seq: prepend_before_filter(names, block)
91
+ # :call-seq: prepend_before_action(names, block)
89
92
  #
90
- # Prepend a before filter. See _insert_callbacks for parameter details.
93
+ # Prepend a callback before actions. See _insert_callbacks for parameter details.
94
+ # Aliased as prepend_before_filter.
91
95
 
92
96
  ##
93
- # :method: skip_before_filter
97
+ # :method: skip_before_action
94
98
  #
95
- # :call-seq: skip_before_filter(names, block)
99
+ # :call-seq: skip_before_action(names)
96
100
  #
97
- # Skip a before filter. See _insert_callbacks for parameter details.
101
+ # Skip a callback before actions. See _insert_callbacks for parameter details.
102
+ # Aliased as skip_before_filter.
98
103
 
99
104
  ##
100
- # :method: append_before_filter
105
+ # :method: append_before_action
101
106
  #
102
- # :call-seq: append_before_filter(names, block)
107
+ # :call-seq: append_before_action(names, block)
103
108
  #
104
- # Append a before filter. See _insert_callbacks for parameter details.
109
+ # Append a callback before actions. See _insert_callbacks for parameter details.
110
+ # Aliased as append_before_filter.
105
111
 
106
112
  ##
107
- # :method: after_filter
113
+ # :method: after_action
108
114
  #
109
- # :call-seq: after_filter(names, block)
115
+ # :call-seq: after_action(names, block)
110
116
  #
111
- # Append an after filter. See _insert_callbacks for parameter details.
117
+ # Append a callback after actions. See _insert_callbacks for parameter details.
118
+ # Aliased as after_filter.
112
119
 
113
120
  ##
114
- # :method: prepend_after_filter
121
+ # :method: prepend_after_action
115
122
  #
116
- # :call-seq: prepend_after_filter(names, block)
123
+ # :call-seq: prepend_after_action(names, block)
117
124
  #
118
- # Prepend an after filter. See _insert_callbacks for parameter details.
125
+ # Prepend a callback after actions. See _insert_callbacks for parameter details.
126
+ # Aliased as prepend_after_filter.
119
127
 
120
128
  ##
121
- # :method: skip_after_filter
129
+ # :method: skip_after_action
122
130
  #
123
- # :call-seq: skip_after_filter(names, block)
131
+ # :call-seq: skip_after_action(names)
124
132
  #
125
- # Skip an after filter. See _insert_callbacks for parameter details.
133
+ # Skip a callback after actions. See _insert_callbacks for parameter details.
134
+ # Aliased as skip_after_filter.
126
135
 
127
136
  ##
128
- # :method: append_after_filter
137
+ # :method: append_after_action
129
138
  #
130
- # :call-seq: append_after_filter(names, block)
139
+ # :call-seq: append_after_action(names, block)
131
140
  #
132
- # Append an after filter. See _insert_callbacks for parameter details.
141
+ # Append a callback after actions. See _insert_callbacks for parameter details.
142
+ # Aliased as append_after_filter.
133
143
 
134
144
  ##
135
- # :method: around_filter
145
+ # :method: around_action
136
146
  #
137
- # :call-seq: around_filter(names, block)
147
+ # :call-seq: around_action(names, block)
138
148
  #
139
- # Append an around filter. See _insert_callbacks for parameter details.
149
+ # Append a callback around actions. See _insert_callbacks for parameter details.
150
+ # Aliased as around_filter.
140
151
 
141
152
  ##
142
- # :method: prepend_around_filter
153
+ # :method: prepend_around_action
143
154
  #
144
- # :call-seq: prepend_around_filter(names, block)
155
+ # :call-seq: prepend_around_action(names, block)
145
156
  #
146
- # Prepend an around filter. See _insert_callbacks for parameter details.
157
+ # Prepend a callback around actions. See _insert_callbacks for parameter details.
158
+ # Aliased as prepend_around_filter.
147
159
 
148
160
  ##
149
- # :method: skip_around_filter
161
+ # :method: skip_around_action
150
162
  #
151
- # :call-seq: skip_around_filter(names, block)
163
+ # :call-seq: skip_around_action(names)
152
164
  #
153
- # Skip an around filter. See _insert_callbacks for parameter details.
165
+ # Skip a callback around actions. See _insert_callbacks for parameter details.
166
+ # Aliased as skip_around_filter.
154
167
 
155
168
  ##
156
- # :method: append_around_filter
169
+ # :method: append_around_action
157
170
  #
158
- # :call-seq: append_around_filter(names, block)
171
+ # :call-seq: append_around_action(names, block)
159
172
  #
160
- # Append an around filter. See _insert_callbacks for parameter details.
173
+ # Append a callback around actions. See _insert_callbacks for parameter details.
174
+ # Aliased as append_around_filter.
161
175
 
162
- # set up before_filter, prepend_before_filter, skip_before_filter, etc.
176
+ # set up before_action, prepend_before_action, skip_before_action, etc.
163
177
  # for each of before, after, and around.
164
- [:before, :after, :around].each do |filter|
178
+ [:before, :after, :around].each do |callback|
165
179
  class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
166
- # Append a before, after or around filter. See _insert_callbacks
180
+ # Append a before, after or around callback. See _insert_callbacks
167
181
  # for details on the allowed parameters.
168
- def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
169
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
170
- options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after} # options[:if] = (Array.wrap(options[:if]) << "!halted") if false
171
- set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before, name, options)
172
- end # end
173
- end # end
174
-
175
- # Prepend a before, after or around filter. See _insert_callbacks
182
+ def #{callback}_action(*names, &blk) # def before_action(*names, &blk)
183
+ _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
184
+ set_callback(:process_action, :#{callback}, name, options) # set_callback(:process_action, :before, name, options)
185
+ end # end
186
+ end # end
187
+
188
+ alias_method :#{callback}_filter, :#{callback}_action
189
+
190
+ # Prepend a before, after or around callback. See _insert_callbacks
176
191
  # for details on the allowed parameters.
177
- def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
178
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
179
- options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after} # options[:if] = (Array.wrap(options[:if]) << "!halted") if false
180
- set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
181
- end # end
182
- end # end
183
-
184
- # Skip a before, after or around filter. See _insert_callbacks
192
+ def prepend_#{callback}_action(*names, &blk) # def prepend_before_action(*names, &blk)
193
+ _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
194
+ set_callback(:process_action, :#{callback}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
195
+ end # end
196
+ end # end
197
+
198
+ alias_method :prepend_#{callback}_filter, :prepend_#{callback}_action
199
+
200
+ # Skip a before, after or around callback. See _insert_callbacks
185
201
  # for details on the allowed parameters.
186
- def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
187
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
188
- skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
189
- end # end
190
- end # end
191
-
192
- # *_filter is the same as append_*_filter
193
- alias_method :append_#{filter}_filter, :#{filter}_filter # alias_method :append_before_filter, :before_filter
202
+ def skip_#{callback}_action(*names) # def skip_before_action(*names)
203
+ _insert_callbacks(names) do |name, options| # _insert_callbacks(names) do |name, options|
204
+ skip_callback(:process_action, :#{callback}, name, options) # skip_callback(:process_action, :before, name, options)
205
+ end # end
206
+ end # end
207
+
208
+ alias_method :skip_#{callback}_filter, :skip_#{callback}_action
209
+
210
+ # *_action is the same as append_*_action
211
+ alias_method :append_#{callback}_action, :#{callback}_action # alias_method :append_before_action, :before_action
212
+ alias_method :append_#{callback}_filter, :#{callback}_action # alias_method :append_before_filter, :before_action
194
213
  RUBY_EVAL
195
214
  end
196
215
  end
@@ -4,7 +4,7 @@ module AbstractController
4
4
  module Collector
5
5
  def self.generate_method_for_mime(mime)
6
6
  sym = mime.is_a?(Symbol) ? mime : mime.to_sym
7
- const = sym.to_s.upcase
7
+ const = sym.upcase
8
8
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
9
9
  def #{sym}(*args, &block) # def html(*args, &block)
10
10
  custom(Mime::#{const}, *args, &block) # custom(Mime::HTML, *args, &block)
@@ -16,10 +16,14 @@ module AbstractController
16
16
  generate_method_for_mime(mime)
17
17
  end
18
18
 
19
+ Mime::Type.register_callback do |mime|
20
+ generate_method_for_mime(mime) unless self.instance_methods.include?(mime.to_sym)
21
+ end
22
+
19
23
  protected
20
24
 
21
25
  def method_missing(symbol, &block)
22
- mime_constant = Mime.const_get(symbol.to_s.upcase)
26
+ mime_constant = Mime.const_get(symbol.upcase)
23
27
 
24
28
  if Mime::SET.include?(mime_constant)
25
29
  AbstractController::Collector.generate_method_for_mime(mime_constant)
@@ -29,4 +33,4 @@ module AbstractController
29
33
  end
30
34
  end
31
35
  end
32
- end
36
+ end
@@ -19,7 +19,7 @@ module AbstractController
19
19
  def inherited(klass)
20
20
  helpers = _helpers
21
21
  klass._helpers = Module.new { include helpers }
22
- klass.class_eval { default_helper_module! unless anonymous? }
22
+ klass.class_eval { default_helper_module! } unless klass.anonymous?
23
23
  super
24
24
  end
25
25
 
@@ -32,9 +32,9 @@ module AbstractController
32
32
  # @current_user ||= User.find_by_id(session[:user])
33
33
  # end
34
34
  #
35
- # def logged_in?
36
- # current_user != nil
37
- # end
35
+ # def logged_in?
36
+ # current_user != nil
37
+ # end
38
38
  # end
39
39
  #
40
40
  # In a view:
@@ -49,20 +49,19 @@ module AbstractController
49
49
 
50
50
  meths.each do |meth|
51
51
  _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
52
- def #{meth}(*args, &blk)
53
- controller.send(%(#{meth}), *args, &blk)
54
- end
52
+ def #{meth}(*args, &blk) # def current_user(*args, &blk)
53
+ controller.send(%(#{meth}), *args, &blk) # controller.send(:current_user, *args, &blk)
54
+ end # end
55
55
  ruby_eval
56
56
  end
57
57
  end
58
58
 
59
59
  # The +helper+ class method can take a series of helper module names, a block, or both.
60
60
  #
61
- # ==== Parameters
61
+ # ==== Options
62
62
  # * <tt>*args</tt> - Module, Symbol, String, :all
63
63
  # * <tt>block</tt> - A block defining helper methods
64
64
  #
65
- # ==== Examples
66
65
  # When the argument is a module it will be included directly in the template class.
67
66
  # helper FooHelper # => includes FooHelper
68
67
  #
@@ -114,7 +113,7 @@ module AbstractController
114
113
  # helpers with the following behavior:
115
114
  #
116
115
  # String or Symbol:: :FooBar or "FooBar" becomes "foo_bar_helper",
117
- # and "foo_bar_helper.rb" is loaded using require_dependency.
116
+ # and "foo_bar_helper.rb" is loaded using require_dependency.
118
117
  #
119
118
  # Module:: No further processing
120
119
  #
@@ -132,7 +131,11 @@ module AbstractController
132
131
  case arg
133
132
  when String, Symbol
134
133
  file_name = "#{arg.to_s.underscore}_helper"
135
- require_dependency(file_name, "Missing helper file helpers/%s.rb")
134
+ begin
135
+ require_dependency(file_name)
136
+ rescue LoadError => e
137
+ raise MissingHelperError.new(e, file_name)
138
+ end
136
139
  file_name.camelize.constantize
137
140
  when Module
138
141
  arg
@@ -142,6 +145,15 @@ module AbstractController
142
145
  end
143
146
  end
144
147
 
148
+ class MissingHelperError < LoadError
149
+ def initialize(error, path)
150
+ @error = error
151
+ @path = "helpers/#{path}.rb"
152
+ set_backtrace error.backtrace
153
+ super("Missing helper file helpers/%s.rb" % path)
154
+ end
155
+ end
156
+
145
157
  private
146
158
  # Makes all the (instance) methods in the helper module available to templates
147
159
  # rendered through this controller.
@@ -89,7 +89,7 @@ module AbstractController
89
89
  # class TillController < BankController
90
90
  # layout false
91
91
  #
92
- # In these examples, we have three implicit lookup scenrios:
92
+ # In these examples, we have three implicit lookup scenarios:
93
93
  # * The BankController uses the "bank" layout.
94
94
  # * The ExchangeController uses the "exchange" layout.
95
95
  # * The CurrencyController inherits the layout from BankController.
@@ -120,6 +120,7 @@ module AbstractController
120
120
  # def writers_and_readers
121
121
  # logged_in? ? "writer_layout" : "reader_layout"
122
122
  # end
123
+ # end
123
124
  #
124
125
  # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing
125
126
  # is logged in or not.
@@ -127,7 +128,14 @@ module AbstractController
127
128
  # If you want to use an inline method, such as a proc, do something like this:
128
129
  #
129
130
  # class WeblogController < ActionController::Base
130
- # layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
131
+ # layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
132
+ # end
133
+ #
134
+ # If an argument isn't given to the proc, it's evaluated in the context of
135
+ # the current controller anyway.
136
+ #
137
+ # class WeblogController < ActionController::Base
138
+ # layout proc { logged_in? ? "writer_layout" : "reader_layout" }
131
139
  # end
132
140
  #
133
141
  # Of course, the most common way of specifying a layout is still just as a plain template name:
@@ -136,8 +144,8 @@ module AbstractController
136
144
  # layout "weblog_standard"
137
145
  # end
138
146
  #
139
- # If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
140
- # Otherwise, it will be looked up relative to the template root.
147
+ # The template will be looked always in <tt>app/views/layouts/</tt> folder. But you can point
148
+ # <tt>layouts</tt> folder direct also. <tt>layout "layouts/demo"</tt> is the same as <tt>layout "demo"</tt>.
141
149
  #
142
150
  # Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists.
143
151
  # Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent:
@@ -162,7 +170,7 @@ module AbstractController
162
170
  # <tt>:only</tt> and <tt>:except</tt> options can be passed to the layout call. For example:
163
171
  #
164
172
  # class WeblogController < ActionController::Base
165
- # layout "weblog_standard", :except => :rss
173
+ # layout "weblog_standard", except: :rss
166
174
  #
167
175
  # # ...
168
176
  #
@@ -172,7 +180,7 @@ module AbstractController
172
180
  # be rendered directly, without wrapping a layout around the rendered view.
173
181
  #
174
182
  # Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
175
- # #<tt>:except => [ :rss, :text_only ]</tt> is valid, as is <tt>:except => :rss</tt>.
183
+ # #<tt>except: [ :rss, :text_only ]</tt> is valid, as is <tt>except: :rss</tt>.
176
184
  #
177
185
  # == Using a different layout in the action render call
178
186
  #
@@ -184,7 +192,7 @@ module AbstractController
184
192
  # layout "weblog_standard"
185
193
  #
186
194
  # def help
187
- # render :action => "help", :layout => "help"
195
+ # render action: "help", layout: "help"
188
196
  # end
189
197
  # end
190
198
  #
@@ -195,30 +203,32 @@ module AbstractController
195
203
  include Rendering
196
204
 
197
205
  included do
198
- class_attribute :_layout_conditions
199
- remove_possible_method :_layout_conditions
206
+ class_attribute :_layout, :_layout_conditions, :instance_accessor => false
207
+ self._layout = nil
200
208
  self._layout_conditions = {}
201
209
  _write_layout_method
202
210
  end
203
211
 
204
- delegate :_layout_conditions, :to => "self.class"
212
+ delegate :_layout_conditions, to: :class
205
213
 
206
214
  module ClassMethods
207
- def inherited(klass)
215
+ def inherited(klass) # :nodoc:
208
216
  super
209
217
  klass._write_layout_method
210
218
  end
211
219
 
212
220
  # This module is mixed in if layout conditions are provided. This means
213
221
  # that if no layout conditions are used, this method is not used
214
- module LayoutConditions
215
- # Determines whether the current action has a layout by checking the
216
- # action name against the :only and :except conditions set on the
217
- # layout.
222
+ module LayoutConditions # :nodoc:
223
+ private
224
+
225
+ # Determines whether the current action has a layout definition by
226
+ # checking the action name against the :only and :except conditions
227
+ # set by the <tt>layout</tt> method.
218
228
  #
219
229
  # ==== Returns
220
- # * <tt> Boolean</tt> - True if the action has a layout, false otherwise.
221
- def conditional_layout?
230
+ # * <tt> Boolean</tt> - True if the action has a layout definition, false otherwise.
231
+ def _conditional_layout?
222
232
  return unless super
223
233
 
224
234
  conditions = _layout_conditions
@@ -254,7 +264,7 @@ module AbstractController
254
264
  conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
255
265
  self._layout_conditions = conditions
256
266
 
257
- @_layout = layout
267
+ self._layout = layout
258
268
  _write_layout_method
259
269
  end
260
270
 
@@ -263,7 +273,7 @@ module AbstractController
263
273
  #
264
274
  # ==== Returns
265
275
  # * <tt>String</tt> - A template name
266
- def _implied_layout_name
276
+ def _implied_layout_name # :nodoc:
267
277
  controller_path
268
278
  end
269
279
 
@@ -271,7 +281,7 @@ module AbstractController
271
281
  #
272
282
  # If a layout is not explicitly mentioned then look for a layout with the controller's name.
273
283
  # if nothing is found then try same procedure to find super class's layout.
274
- def _write_layout_method
284
+ def _write_layout_method # :nodoc:
275
285
  remove_possible_method(:_layout)
276
286
 
277
287
  prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
@@ -279,59 +289,38 @@ module AbstractController
279
289
  <<-RUBY
280
290
  lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first || super
281
291
  RUBY
282
- end
283
-
284
- if defined?(@_layout)
285
- layout_definition = case @_layout
286
- when String
287
- @_layout.inspect
288
- when Symbol
289
- <<-RUBY
290
- #{@_layout}.tap do |layout|
291
- unless layout.is_a?(String) || !layout
292
- raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \
293
- "should have returned a String, false, or nil"
294
- end
295
- end
296
- RUBY
297
- when Proc
298
- define_method :_layout_from_proc, &@_layout
299
- "_layout_from_proc(self)"
300
- when false
301
- nil
302
- when true
303
- raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
304
- when nil
305
- name_clause
306
- end
307
292
  else
308
- # Add a deprecation if the parent layout was explicitly set and the child
309
- # still does a dynamic lookup. In next Rails release, we should @_layout
310
- # to be inheritable so we can skip the child lookup if the parent explicitly
311
- # set the layout.
312
- parent = self.superclass.instance_eval { @_layout if defined?(@_layout) }
313
- @_layout = nil
314
- inspect = parent.is_a?(Proc) ? parent.inspect : parent
293
+ <<-RUBY
294
+ super
295
+ RUBY
296
+ end
315
297
 
316
- layout_definition = if parent.nil?
317
- name_clause
318
- elsif name
319
- <<-RUBY
320
- if template = lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first
321
- ActiveSupport::Deprecation.warn 'Layout found at "#{_implied_layout_name}" for #{name} but parent controller ' \
322
- 'set layout to #{inspect.inspect}. Please explicitly set your layout to "#{_implied_layout_name}" ' \
323
- 'or set it to nil to force a dynamic lookup.'
324
- template
325
- else
326
- super
298
+ layout_definition = case _layout
299
+ when String
300
+ _layout.inspect
301
+ when Symbol
302
+ <<-RUBY
303
+ #{_layout}.tap do |layout|
304
+ unless layout.is_a?(String) || !layout
305
+ raise ArgumentError, "Your layout method :#{_layout} returned \#{layout}. It " \
306
+ "should have returned a String, false, or nil"
327
307
  end
328
- RUBY
329
- end
308
+ end
309
+ RUBY
310
+ when Proc
311
+ define_method :_layout_from_proc, &_layout
312
+ _layout.arity == 0 ? "_layout_from_proc" : "_layout_from_proc(self)"
313
+ when false
314
+ nil
315
+ when true
316
+ raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil"
317
+ when nil
318
+ name_clause
330
319
  end
331
320
 
332
321
  self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
333
322
  def _layout
334
- if conditional_layout?
323
+ if _conditional_layout?
335
324
  #{layout_definition}
336
325
  else
337
326
  #{name_clause}
@@ -342,32 +331,38 @@ module AbstractController
342
331
  end
343
332
  end
344
333
 
345
- def _normalize_options(options)
334
+ def _normalize_options(options) # :nodoc:
346
335
  super
347
336
 
348
337
  if _include_layout?(options)
349
- layout = options.key?(:layout) ? options.delete(:layout) : :default
338
+ layout = options.delete(:layout) { :default }
350
339
  options[:layout] = _layout_for_option(layout)
351
340
  end
352
341
  end
353
342
 
354
343
  attr_internal_writer :action_has_layout
355
344
 
356
- def initialize(*)
345
+ def initialize(*) # :nodoc:
357
346
  @_action_has_layout = true
358
347
  super
359
348
  end
360
349
 
350
+ # Controls whether an action should be rendered using a layout.
351
+ # If you want to disable any <tt>layout</tt> settings for the
352
+ # current action so that it is rendered without a layout then
353
+ # either override this method in your controller to return false
354
+ # for that action or set the <tt>action_has_layout</tt> attribute
355
+ # to false before rendering.
361
356
  def action_has_layout?
362
357
  @_action_has_layout
363
358
  end
364
359
 
365
- def conditional_layout?
360
+ private
361
+
362
+ def _conditional_layout?
366
363
  true
367
364
  end
368
365
 
369
- private
370
-
371
366
  # This will be overwritten by _write_layout_method
372
367
  def _layout; end
373
368
 
@@ -384,7 +379,7 @@ module AbstractController
384
379
  when false, nil then nil
385
380
  else
386
381
  raise ArgumentError,
387
- "String, true, or false, expected for `layout'; you passed #{name.inspect}"
382
+ "String, Proc, :default, true, or false, expected for `layout'; you passed #{name.inspect}"
388
383
  end
389
384
  end
390
385