actionpack 1.12.5 → 1.13.0
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.
- data/CHANGELOG +517 -15
- data/MIT-LICENSE +1 -1
- data/README +18 -20
- data/Rakefile +7 -4
- data/examples/address_book_controller.rb +3 -3
- data/examples/blog_controller.cgi +3 -3
- data/examples/debate_controller.cgi +5 -5
- data/lib/action_controller.rb +2 -2
- data/lib/action_controller/assertions.rb +73 -311
- data/lib/action_controller/{deprecated_assertions.rb → assertions/deprecated_assertions.rb} +32 -8
- data/lib/action_controller/assertions/dom_assertions.rb +25 -0
- data/lib/action_controller/assertions/model_assertions.rb +12 -0
- data/lib/action_controller/assertions/response_assertions.rb +140 -0
- data/lib/action_controller/assertions/routing_assertions.rb +82 -0
- data/lib/action_controller/assertions/selector_assertions.rb +571 -0
- data/lib/action_controller/assertions/tag_assertions.rb +117 -0
- data/lib/action_controller/base.rb +334 -163
- data/lib/action_controller/benchmarking.rb +3 -6
- data/lib/action_controller/caching.rb +83 -22
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -7
- data/lib/action_controller/cgi_ext/cgi_methods.rb +167 -173
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +43 -22
- data/lib/action_controller/cgi_process.rb +50 -27
- data/lib/action_controller/components.rb +21 -25
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/{dependencies.rb → deprecated_dependencies.rb} +9 -27
- data/lib/action_controller/filters.rb +448 -225
- data/lib/action_controller/flash.rb +24 -20
- data/lib/action_controller/helpers.rb +2 -5
- data/lib/action_controller/integration.rb +40 -16
- data/lib/action_controller/layout.rb +11 -8
- data/lib/action_controller/macros/auto_complete.rb +3 -2
- data/lib/action_controller/macros/in_place_editing.rb +3 -2
- data/lib/action_controller/mime_responds.rb +41 -29
- data/lib/action_controller/mime_type.rb +68 -10
- data/lib/action_controller/pagination.rb +4 -3
- data/lib/action_controller/request.rb +22 -14
- data/lib/action_controller/rescue.rb +25 -22
- data/lib/action_controller/resources.rb +302 -0
- data/lib/action_controller/response.rb +20 -2
- data/lib/action_controller/response.rb.rej +17 -0
- data/lib/action_controller/routing.rb +1165 -567
- data/lib/action_controller/scaffolding.rb +30 -31
- data/lib/action_controller/session/active_record_store.rb +2 -0
- data/lib/action_controller/session/drb_store.rb +4 -0
- data/lib/action_controller/session/mem_cache_store.rb +4 -0
- data/lib/action_controller/session_management.rb +6 -9
- data/lib/action_controller/status_codes.rb +89 -0
- data/lib/action_controller/streaming.rb +6 -15
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +5 -5
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -2
- data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -4
- data/lib/action_controller/templates/rescues/template_error.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +52 -30
- data/lib/action_controller/url_rewriter.rb +63 -29
- data/lib/action_controller/vendor/html-scanner/html/document.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +3 -4
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +822 -0
- data/lib/action_controller/verification.rb +22 -11
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +46 -43
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +54 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +97 -46
- data/lib/action_view/helpers/capture_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +258 -136
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/deprecated_helper.rb +34 -0
- data/lib/action_view/helpers/form_helper.rb +75 -35
- data/lib/action_view/helpers/form_options_helper.rb +7 -5
- data/lib/action_view/helpers/form_tag_helper.rb +44 -6
- data/lib/action_view/helpers/java_script_macros_helper.rb +59 -46
- data/lib/action_view/helpers/javascript_helper.rb +71 -10
- data/lib/action_view/helpers/javascripts/controls.js +41 -23
- data/lib/action_view/helpers/javascripts/dragdrop.js +105 -76
- data/lib/action_view/helpers/javascripts/effects.js +293 -163
- data/lib/action_view/helpers/javascripts/prototype.js +897 -389
- data/lib/action_view/helpers/javascripts/prototype.js.rej +561 -0
- data/lib/action_view/helpers/number_helper.rb +111 -65
- data/lib/action_view/helpers/prototype_helper.rb +84 -109
- data/lib/action_view/helpers/scriptaculous_helper.rb +5 -0
- data/lib/action_view/helpers/tag_helper.rb +69 -16
- data/lib/action_view/helpers/text_helper.rb +149 -112
- data/lib/action_view/helpers/url_helper.rb +200 -107
- data/lib/action_view/template_error.rb +66 -42
- data/test/abstract_unit.rb +4 -2
- data/test/active_record_unit.rb +84 -56
- data/test/activerecord/active_record_assertions_test.rb +26 -18
- data/test/activerecord/active_record_store_test.rb +4 -36
- data/test/activerecord/pagination_test.rb +1 -6
- data/test/controller/action_pack_assertions_test.rb +230 -113
- data/test/controller/addresses_render_test.rb +2 -6
- data/test/controller/assert_select_test.rb +576 -0
- data/test/controller/base_test.rb +73 -3
- data/test/controller/caching_test.rb +228 -0
- data/test/controller/capture_test.rb +12 -10
- data/test/controller/cgi_test.rb +89 -12
- data/test/controller/components_test.rb +24 -2
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +33 -25
- data/test/controller/deprecated_instance_variables_test.rb +48 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +60 -0
- data/test/controller/fake_controllers.rb +0 -1
- data/test/controller/filters_test.rb +301 -16
- data/test/controller/flash_test.rb +19 -2
- data/test/controller/helper_test.rb +2 -2
- data/test/controller/integration_test.rb +154 -0
- data/test/controller/layout_test.rb +115 -1
- data/test/controller/mime_responds_test.rb +94 -0
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/new_render_test.rb +161 -11
- data/test/controller/raw_post_test.rb +52 -15
- data/test/controller/redirect_test.rb +27 -14
- data/test/controller/render_test.rb +76 -29
- data/test/controller/request_test.rb +55 -4
- data/test/controller/resources_test.rb +274 -0
- data/test/controller/routing_test.rb +1533 -824
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +9 -1
- data/test/controller/session_management_test.rb +51 -0
- data/test/controller/test_test.rb +113 -29
- data/test/controller/url_rewriter_test.rb +86 -17
- data/test/controller/verification_test.rb +19 -17
- data/test/controller/webservice_test.rb +0 -7
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/test/_hello.rxml +1 -0
- data/test/fixtures/test/hello_world_container.rxml +3 -0
- data/test/fixtures/topic.rb +2 -2
- data/test/template/active_record_helper_test.rb +83 -12
- data/test/template/asset_tag_helper_test.rb +75 -95
- data/test/template/compiled_templates_test.rb +1 -0
- data/test/template/date_helper_test.rb +873 -181
- data/test/template/deprecated_helper_test.rb +36 -0
- data/test/template/deprecated_instance_variables_test.rb +43 -0
- data/test/template/form_helper_test.rb +77 -1
- data/test/template/form_options_helper_test.rb +4 -0
- data/test/template/form_tag_helper_test.rb +66 -2
- data/test/template/java_script_macros_helper_test.rb +4 -1
- data/test/template/javascript_helper_test.rb +29 -0
- data/test/template/number_helper_test.rb +63 -27
- data/test/template/prototype_helper_test.rb +77 -34
- data/test/template/tag_helper_test.rb +34 -6
- data/test/template/text_helper_test.rb +69 -34
- data/test/template/url_helper_test.rb +168 -16
- data/test/testing_sandbox.rb +7 -22
- metadata +66 -20
- data/filler.txt +0 -50
- data/lib/action_controller/code_generation.rb +0 -235
- data/lib/action_controller/vendor/xml_simple.rb +0 -1019
- data/test/controller/caching_filestore.rb +0 -74
- data/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb +0 -7
- data/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb +0 -3
- data/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb +0 -7
- data/test/fixtures/dont_load.rb +0 -3
@@ -5,19 +5,14 @@ module ActionController #:nodoc:
|
|
5
5
|
base.send(:include, ActionController::Filters::InstanceMethods)
|
6
6
|
end
|
7
7
|
|
8
|
-
# Filters enable controllers to run shared pre and post processing code for its actions. These filters can be used to do
|
9
|
-
# authentication, caching, or auditing before the intended action is performed. Or to do localization or output
|
10
|
-
# compression after the action has been performed.
|
11
|
-
#
|
12
|
-
# Filters have access to the request, response, and all the instance variables set by other filters in the chain
|
13
|
-
# or by the action (in the case of after filters). Additionally, it's possible for a pre-processing <tt>before_filter</tt>
|
14
|
-
# to halt the processing before the intended action is processed by returning false or performing a redirect or render.
|
15
|
-
# This is especially useful for filters like authentication where you're not interested in allowing the action to be
|
16
|
-
# performed if the proper credentials are not in order.
|
8
|
+
# Filters enable controllers to run shared pre and post processing code for its actions. These filters can be used to do
|
9
|
+
# authentication, caching, or auditing before the intended action is performed. Or to do localization or output
|
10
|
+
# compression after the action has been performed. Filters have access to the request, response, and all the instance
|
11
|
+
# variables set by other filters in the chain or by the action (in the case of after filters).
|
17
12
|
#
|
18
13
|
# == Filter inheritance
|
19
14
|
#
|
20
|
-
# Controller inheritance hierarchies share filters downwards, but subclasses can also add
|
15
|
+
# Controller inheritance hierarchies share filters downwards, but subclasses can also add or skip filters without
|
21
16
|
# affecting the superclass. For example:
|
22
17
|
#
|
23
18
|
# class BankController < ActionController::Base
|
@@ -39,7 +34,7 @@ module ActionController #:nodoc:
|
|
39
34
|
# end
|
40
35
|
#
|
41
36
|
# Now any actions performed on the BankController will have the audit method called before. On the VaultController,
|
42
|
-
# first the audit method is called, then the verify_credentials method. If the audit method returns false, then
|
37
|
+
# first the audit method is called, then the verify_credentials method. If the audit method returns false, then
|
43
38
|
# verify_credentials and the intended action are never called.
|
44
39
|
#
|
45
40
|
# == Filter types
|
@@ -64,7 +59,7 @@ module ActionController #:nodoc:
|
|
64
59
|
# The filter method is passed the controller instance and is hence granted access to all aspects of the controller and can
|
65
60
|
# manipulate them as it sees fit.
|
66
61
|
#
|
67
|
-
# The inline method (using a proc) can be used to quickly do something small that doesn't require a lot of explanation.
|
62
|
+
# The inline method (using a proc) can be used to quickly do something small that doesn't require a lot of explanation.
|
68
63
|
# Or just as a quick test. It works like this:
|
69
64
|
#
|
70
65
|
# class WeblogController < ActionController::Base
|
@@ -76,6 +71,9 @@ module ActionController #:nodoc:
|
|
76
71
|
# session, template, and assigns. Note: The inline method doesn't strictly have to be a block; any object that responds to call
|
77
72
|
# and returns 1 or -1 on arity will do (such as a Proc or an Method object).
|
78
73
|
#
|
74
|
+
# Please note that around_filters function a little differently than the normal before and after filters with regard to filter
|
75
|
+
# types. Please see the section dedicated to around_filters below.
|
76
|
+
#
|
79
77
|
# == Filter chain ordering
|
80
78
|
#
|
81
79
|
# Using <tt>before_filter</tt> and <tt>after_filter</tt> appends the specified filters to the existing chain. That's usually
|
@@ -83,14 +81,14 @@ module ActionController #:nodoc:
|
|
83
81
|
# can use <tt>prepend_before_filter</tt> and <tt>prepend_after_filter</tt>. Filters added by these methods will be put at the
|
84
82
|
# beginning of their respective chain and executed before the rest. For example:
|
85
83
|
#
|
86
|
-
# class ShoppingController
|
84
|
+
# class ShoppingController < ActionController::Base
|
87
85
|
# before_filter :verify_open_shop
|
88
86
|
#
|
89
|
-
# class CheckoutController
|
87
|
+
# class CheckoutController < ShoppingController
|
90
88
|
# prepend_before_filter :ensure_items_in_cart, :ensure_items_in_stock
|
91
89
|
#
|
92
90
|
# The filter chain for the CheckoutController is now <tt>:ensure_items_in_cart, :ensure_items_in_stock,</tt>
|
93
|
-
# <tt>:verify_open_shop</tt>. So if either of the ensure filters return false, we'll never get around to see if the shop
|
91
|
+
# <tt>:verify_open_shop</tt>. So if either of the ensure filters return false, we'll never get around to see if the shop
|
94
92
|
# is open or not.
|
95
93
|
#
|
96
94
|
# You may pass multiple filter arguments of each type as well as a filter block.
|
@@ -98,250 +96,511 @@ module ActionController #:nodoc:
|
|
98
96
|
#
|
99
97
|
# == Around filters
|
100
98
|
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
99
|
+
# Around filters wrap an action, executing code both before and after.
|
100
|
+
# They may be declared as method references, blocks, or objects responding
|
101
|
+
# to #filter or to both #before and #after.
|
102
|
+
#
|
103
|
+
# To use a method as an around_filter, pass a symbol naming the Ruby method.
|
104
|
+
# Yield (or block.call) within the method to run the action.
|
105
|
+
#
|
106
|
+
# around_filter :catch_exceptions
|
107
|
+
#
|
108
|
+
# private
|
109
|
+
# def catch_exceptions
|
110
|
+
# yield
|
111
|
+
# rescue => exception
|
112
|
+
# logger.debug "Caught exception! #{exception}"
|
113
|
+
# raise
|
110
114
|
# end
|
111
|
-
#
|
115
|
+
#
|
116
|
+
# To use a block as an around_filter, pass a block taking as args both
|
117
|
+
# the controller and the action block. You can't call yield directly from
|
118
|
+
# an around_filter block; explicitly call the action block instead:
|
119
|
+
#
|
120
|
+
# around_filter do |controller, action|
|
121
|
+
# logger.debug "before #{controller.action_name}"
|
122
|
+
# action.call
|
123
|
+
# logger.debug "after #{controller.action_name}"
|
112
124
|
# end
|
113
125
|
#
|
126
|
+
# To use a filter object with around_filter, pass an object responding
|
127
|
+
# to :filter or both :before and :after. With a filter method, yield to
|
128
|
+
# the block as above:
|
129
|
+
#
|
130
|
+
# around_filter BenchmarkingFilter
|
131
|
+
#
|
114
132
|
# class BenchmarkingFilter
|
115
|
-
# def
|
116
|
-
#
|
133
|
+
# def self.filter(controller, &block)
|
134
|
+
# Benchmark.measure(&block)
|
117
135
|
# end
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# With before and after methods:
|
139
|
+
#
|
140
|
+
# around_filter Authorizer.new
|
141
|
+
#
|
142
|
+
# class Authorizer
|
143
|
+
# # This will run before the action. Returning false aborts the action.
|
144
|
+
# def before(controller)
|
145
|
+
# if user.authorized?
|
146
|
+
# return true
|
147
|
+
# else
|
148
|
+
# redirect_to login_url
|
149
|
+
# return false
|
150
|
+
# end
|
121
151
|
# end
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
# report_result
|
152
|
+
#
|
153
|
+
# # This will run after the action if and only if before returned true.
|
154
|
+
# def after(controller)
|
126
155
|
# end
|
127
156
|
# end
|
128
157
|
#
|
158
|
+
# If the filter has before and after methods, the before method will be
|
159
|
+
# called before the action. If before returns false, the filter chain is
|
160
|
+
# halted and after will not be run. See Filter Chain Halting below for
|
161
|
+
# an example.
|
162
|
+
#
|
129
163
|
# == Filter chain skipping
|
130
164
|
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# they would like to be relieved of. Examples
|
165
|
+
# Declaring a filter on a base class conveniently applies to its subclasses,
|
166
|
+
# but sometimes a subclass should skip some of its superclass' filters:
|
134
167
|
#
|
135
168
|
# class ApplicationController < ActionController::Base
|
136
169
|
# before_filter :authenticate
|
170
|
+
# around_filter :catch_exceptions
|
137
171
|
# end
|
138
172
|
#
|
139
173
|
# class WeblogController < ApplicationController
|
140
|
-
# #
|
174
|
+
# # Will run the :authenticate and :catch_exceptions filters.
|
141
175
|
# end
|
142
176
|
#
|
143
177
|
# class SignupController < ApplicationController
|
144
|
-
# #
|
178
|
+
# # Skip :authenticate, run :catch_exceptions.
|
145
179
|
# skip_before_filter :authenticate
|
146
180
|
# end
|
147
181
|
#
|
182
|
+
# class ProjectsController < ApplicationController
|
183
|
+
# # Skip :catch_exceptions, run :authenticate.
|
184
|
+
# skip_filter :catch_exceptions
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
# class ClientsController < ApplicationController
|
188
|
+
# # Skip :catch_exceptions and :authenticate unless action is index.
|
189
|
+
# skip_filter :catch_exceptions, :authenticate, :except => :index
|
190
|
+
# end
|
191
|
+
#
|
148
192
|
# == Filter conditions
|
149
193
|
#
|
150
|
-
# Filters
|
151
|
-
#
|
152
|
-
#
|
194
|
+
# Filters may be limited to specific actions by declaring the actions to
|
195
|
+
# include or exclude. Both options accept single actions (:only => :index)
|
196
|
+
# or arrays of actions (:except => [:foo, :bar]).
|
153
197
|
#
|
154
198
|
# class Journal < ActionController::Base
|
155
|
-
# #
|
156
|
-
# before_filter :authorize, :only => [
|
157
|
-
#
|
199
|
+
# # Require authentication for edit and delete.
|
200
|
+
# before_filter :authorize, :only => [:edit, :delete]
|
201
|
+
#
|
202
|
+
# # Passing options to a filter with a block.
|
203
|
+
# around_filter(:except => :index) do |controller, action_block|
|
204
|
+
# results = Profiler.run(&action_block)
|
205
|
+
# controller.response.sub! "</body>", "#{results}</body>"
|
206
|
+
# end
|
207
|
+
#
|
158
208
|
# private
|
159
209
|
# def authorize
|
160
|
-
# #
|
210
|
+
# # Redirect to login unless authenticated.
|
161
211
|
# end
|
162
212
|
# end
|
163
|
-
#
|
164
|
-
# When setting conditions on inline method (proc) filters the condition must come first and be placed in parentheses.
|
165
|
-
#
|
166
|
-
# class UserPreferences < ActionController::Base
|
167
|
-
# before_filter(:except => :new) { # some proc ... }
|
168
|
-
# # ...
|
169
|
-
# end
|
170
213
|
#
|
214
|
+
# == Filter Chain Halting
|
215
|
+
#
|
216
|
+
# <tt>before_filter</tt> and <tt>around_filter</tt> may halt the request
|
217
|
+
# before controller action is run. This is useful, for example, to deny
|
218
|
+
# access to unauthenticated users or to redirect from http to https.
|
219
|
+
# Simply return false from the filter or call render or redirect.
|
220
|
+
#
|
221
|
+
# Around filters halt the request unless the action block is called.
|
222
|
+
# Given these filters
|
223
|
+
# after_filter :after
|
224
|
+
# around_filter :around
|
225
|
+
# before_filter :before
|
226
|
+
#
|
227
|
+
# The filter chain will look like:
|
228
|
+
#
|
229
|
+
# ...
|
230
|
+
# . \
|
231
|
+
# . #around (code before yield)
|
232
|
+
# . . \
|
233
|
+
# . . #before (actual filter code is run)
|
234
|
+
# . . . \
|
235
|
+
# . . . execute controller action
|
236
|
+
# . . . /
|
237
|
+
# . . ...
|
238
|
+
# . . /
|
239
|
+
# . #around (code after yield)
|
240
|
+
# . /
|
241
|
+
# #after (actual filter code is run)
|
242
|
+
#
|
243
|
+
# If #around returns before yielding, only #after will be run. The #before
|
244
|
+
# filter and controller action will not be run. If #before returns false,
|
245
|
+
# the second half of #around and all of #after will still run but the
|
246
|
+
# action will not.
|
171
247
|
module ClassMethods
|
172
|
-
# The passed <tt>filters</tt> will be appended to the
|
173
|
-
# on this controller
|
248
|
+
# The passed <tt>filters</tt> will be appended to the filter_chain and
|
249
|
+
# will execute before the action on this controller is performed.
|
174
250
|
def append_before_filter(*filters, &block)
|
175
|
-
|
176
|
-
filters << block if block_given?
|
177
|
-
add_action_conditions(filters, conditions)
|
178
|
-
append_filter_to_chain('before', filters)
|
251
|
+
append_filter_to_chain(filters, :before, &block)
|
179
252
|
end
|
180
253
|
|
181
|
-
# The passed <tt>filters</tt> will be prepended to the
|
182
|
-
# on this controller
|
254
|
+
# The passed <tt>filters</tt> will be prepended to the filter_chain and
|
255
|
+
# will execute before the action on this controller is performed.
|
183
256
|
def prepend_before_filter(*filters, &block)
|
184
|
-
|
185
|
-
filters << block if block_given?
|
186
|
-
add_action_conditions(filters, conditions)
|
187
|
-
prepend_filter_to_chain('before', filters)
|
257
|
+
prepend_filter_to_chain(filters, :before, &block)
|
188
258
|
end
|
189
259
|
|
190
|
-
#
|
260
|
+
# Shorthand for append_before_filter since it's the most common.
|
191
261
|
alias :before_filter :append_before_filter
|
192
|
-
|
193
|
-
# The passed <tt>filters</tt> will be appended to the array of filters
|
194
|
-
# on this controller are performed.
|
262
|
+
|
263
|
+
# The passed <tt>filters</tt> will be appended to the array of filters
|
264
|
+
# that run _after_ actions on this controller are performed.
|
195
265
|
def append_after_filter(*filters, &block)
|
196
|
-
|
197
|
-
filters << block if block_given?
|
198
|
-
add_action_conditions(filters, conditions)
|
199
|
-
append_filter_to_chain('after', filters)
|
266
|
+
prepend_filter_to_chain(filters, :after, &block)
|
200
267
|
end
|
201
268
|
|
202
|
-
# The passed <tt>filters</tt> will be prepended to the array of filters
|
203
|
-
# on this controller are performed.
|
269
|
+
# The passed <tt>filters</tt> will be prepended to the array of filters
|
270
|
+
# that run _after_ actions on this controller are performed.
|
204
271
|
def prepend_after_filter(*filters, &block)
|
205
|
-
|
206
|
-
filters << block if block_given?
|
207
|
-
add_action_conditions(filters, conditions)
|
208
|
-
prepend_filter_to_chain("after", filters)
|
272
|
+
append_filter_to_chain(filters, :after, &block)
|
209
273
|
end
|
210
274
|
|
211
|
-
#
|
275
|
+
# Shorthand for append_after_filter since it's the most common.
|
212
276
|
alias :after_filter :append_after_filter
|
213
|
-
|
214
|
-
|
215
|
-
#
|
216
|
-
# respond to both +before+ and +after+. So if you do append_around_filter A.new, B.new, the callstack will look like:
|
277
|
+
|
278
|
+
|
279
|
+
# If you append_around_filter A.new, B.new, the filter chain looks like
|
217
280
|
#
|
218
281
|
# B#before
|
219
282
|
# A#before
|
283
|
+
# # run the action
|
220
284
|
# A#after
|
221
285
|
# B#after
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
#
|
233
|
-
# respond to both +before+ and +after+. So if you do prepend_around_filter A.new, B.new, the callstack will look like:
|
286
|
+
#
|
287
|
+
# With around filters which yield to the action block, #before and #after
|
288
|
+
# are the code before and after the yield.
|
289
|
+
def append_around_filter(*filters, &block)
|
290
|
+
filters, conditions = extract_conditions(filters, &block)
|
291
|
+
filters.map { |f| proxy_before_and_after_filter(f) }.each do |filter|
|
292
|
+
append_filter_to_chain([filter, conditions])
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# If you prepend_around_filter A.new, B.new, the filter chain looks like:
|
234
297
|
#
|
235
298
|
# A#before
|
236
299
|
# B#before
|
300
|
+
# # run the action
|
237
301
|
# B#after
|
238
302
|
# A#after
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
303
|
+
#
|
304
|
+
# With around filters which yield to the action block, #before and #after
|
305
|
+
# are the code before and after the yield.
|
306
|
+
def prepend_around_filter(*filters, &block)
|
307
|
+
filters, conditions = extract_conditions(filters, &block)
|
308
|
+
filters.map { |f| proxy_before_and_after_filter(f) }.each do |filter|
|
309
|
+
prepend_filter_to_chain([filter, conditions])
|
244
310
|
end
|
245
|
-
end
|
311
|
+
end
|
246
312
|
|
247
|
-
#
|
313
|
+
# Shorthand for append_around_filter since it's the most common.
|
248
314
|
alias :around_filter :append_around_filter
|
249
|
-
|
250
|
-
# Removes the specified filters from the +before+ filter chain. Note that this only works for skipping method-reference
|
315
|
+
|
316
|
+
# Removes the specified filters from the +before+ filter chain. Note that this only works for skipping method-reference
|
251
317
|
# filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out
|
252
318
|
# of many sub-controllers need a different hierarchy.
|
253
319
|
#
|
254
|
-
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
320
|
+
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
255
321
|
# just like when you apply the filters.
|
256
322
|
def skip_before_filter(*filters)
|
257
|
-
|
258
|
-
remove_contradicting_conditions!(filters, conditions)
|
259
|
-
conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
|
260
|
-
add_action_conditions(filters, conditions)
|
261
|
-
else
|
262
|
-
for filter in filters.flatten
|
263
|
-
write_inheritable_attribute("before_filters", read_inheritable_attribute("before_filters") - [ filter ])
|
264
|
-
end
|
265
|
-
end
|
323
|
+
skip_filter_in_chain(*filters, &:before?)
|
266
324
|
end
|
267
325
|
|
268
|
-
# Removes the specified filters from the +after+ filter chain. Note that this only works for skipping method-reference
|
326
|
+
# Removes the specified filters from the +after+ filter chain. Note that this only works for skipping method-reference
|
269
327
|
# filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out
|
270
328
|
# of many sub-controllers need a different hierarchy.
|
271
329
|
#
|
272
|
-
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
330
|
+
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
273
331
|
# just like when you apply the filters.
|
274
332
|
def skip_after_filter(*filters)
|
275
|
-
|
276
|
-
remove_contradicting_conditions!(filters, conditions)
|
277
|
-
conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
|
278
|
-
add_action_conditions(filters, conditions)
|
279
|
-
else
|
280
|
-
for filter in filters.flatten
|
281
|
-
write_inheritable_attribute("after_filters", read_inheritable_attribute("after_filters") - [ filter ])
|
282
|
-
end
|
283
|
-
end
|
333
|
+
skip_filter_in_chain(*filters, &:after?)
|
284
334
|
end
|
285
|
-
|
335
|
+
|
336
|
+
# Removes the specified filters from the filter chain. This only works for method reference (symbol)
|
337
|
+
# filters, not procs. This method is different from skip_after_filter and skip_before_filter in that
|
338
|
+
# it will match any before, after or yielding around filter.
|
339
|
+
#
|
340
|
+
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
341
|
+
# just like when you apply the filters.
|
342
|
+
def skip_filter(*filters)
|
343
|
+
skip_filter_in_chain(*filters)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Returns an array of Filter objects for this controller.
|
347
|
+
def filter_chain
|
348
|
+
read_inheritable_attribute("filter_chain") || []
|
349
|
+
end
|
350
|
+
|
286
351
|
# Returns all the before filters for this class and all its ancestors.
|
352
|
+
# This method returns the actual filter that was assigned in the controller to maintain existing functionality.
|
287
353
|
def before_filters #:nodoc:
|
288
|
-
|
354
|
+
filter_chain.select(&:before?).map(&:filter)
|
289
355
|
end
|
290
|
-
|
356
|
+
|
291
357
|
# Returns all the after filters for this class and all its ancestors.
|
358
|
+
# This method returns the actual filter that was assigned in the controller to maintain existing functionality.
|
292
359
|
def after_filters #:nodoc:
|
293
|
-
|
360
|
+
filter_chain.select(&:after?).map(&:filter)
|
294
361
|
end
|
295
|
-
|
362
|
+
|
296
363
|
# Returns a mapping between filters and the actions that may run them.
|
297
364
|
def included_actions #:nodoc:
|
298
|
-
|
365
|
+
read_inheritable_attribute("included_actions") || {}
|
299
366
|
end
|
300
|
-
|
367
|
+
|
301
368
|
# Returns a mapping between filters and actions that may not run them.
|
302
369
|
def excluded_actions #:nodoc:
|
303
|
-
|
370
|
+
read_inheritable_attribute("excluded_actions") || {}
|
304
371
|
end
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
372
|
+
|
373
|
+
# Find a filter in the filter_chain where the filter method matches the _filter_ param
|
374
|
+
# and (optionally) the passed block evaluates to true (mostly used for testing before?
|
375
|
+
# and after? on the filter). Useful for symbol filters.
|
376
|
+
#
|
377
|
+
# The object of type Filter is passed to the block when yielded, not the filter itself.
|
378
|
+
def find_filter(filter, &block) #:nodoc:
|
379
|
+
filter_chain.select { |f| f.filter == filter && (!block_given? || yield(f)) }.first
|
380
|
+
end
|
381
|
+
|
382
|
+
# Returns true if the filter is excluded from the given action
|
383
|
+
def filter_excluded_from_action?(filter,action) #:nodoc:
|
384
|
+
if (ia = included_actions[filter]) && !ia.empty?
|
385
|
+
!ia.include?(action)
|
386
|
+
else
|
387
|
+
(excluded_actions[filter] || []).include?(action)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
# Filter class is an abstract base class for all filters. Handles all of the included/excluded actions but
|
392
|
+
# contains no logic for calling the actual filters.
|
393
|
+
class Filter #:nodoc:
|
394
|
+
attr_reader :filter, :included_actions, :excluded_actions
|
395
|
+
|
396
|
+
def initialize(filter)
|
397
|
+
@filter = filter
|
398
|
+
end
|
399
|
+
|
400
|
+
def before?
|
401
|
+
false
|
402
|
+
end
|
403
|
+
|
404
|
+
def after?
|
405
|
+
false
|
406
|
+
end
|
407
|
+
|
408
|
+
def around?
|
409
|
+
true
|
309
410
|
end
|
310
411
|
|
311
|
-
def
|
312
|
-
|
313
|
-
write_inheritable_attribute("#{condition}_filters", filters + old_filters)
|
412
|
+
def call(controller, &block)
|
413
|
+
raise(ActionControllerError, 'No filter type: Nothing to do here.')
|
314
414
|
end
|
415
|
+
end
|
416
|
+
|
417
|
+
# Abstract base class for filter proxies. FilterProxy objects are meant to mimic the behaviour of the old
|
418
|
+
# before_filter and after_filter by moving the logic into the filter itself.
|
419
|
+
class FilterProxy < Filter #:nodoc:
|
420
|
+
def filter
|
421
|
+
@filter.filter
|
422
|
+
end
|
423
|
+
|
424
|
+
def around?
|
425
|
+
false
|
426
|
+
end
|
427
|
+
end
|
315
428
|
|
316
|
-
|
317
|
-
|
318
|
-
|
429
|
+
class BeforeFilterProxy < FilterProxy #:nodoc:
|
430
|
+
def before?
|
431
|
+
true
|
432
|
+
end
|
433
|
+
|
434
|
+
def call(controller, &block)
|
435
|
+
if false == @filter.call(controller) # must only stop if equal to false. only filters returning false are halted.
|
436
|
+
controller.halt_filter_chain(@filter, :returned_false)
|
437
|
+
else
|
438
|
+
yield
|
319
439
|
end
|
320
440
|
end
|
441
|
+
end
|
442
|
+
|
443
|
+
class AfterFilterProxy < FilterProxy #:nodoc:
|
444
|
+
def after?
|
445
|
+
true
|
446
|
+
end
|
321
447
|
|
322
|
-
def
|
323
|
-
|
324
|
-
|
448
|
+
def call(controller, &block)
|
449
|
+
yield
|
450
|
+
@filter.call(controller)
|
325
451
|
end
|
452
|
+
end
|
453
|
+
|
454
|
+
class SymbolFilter < Filter #:nodoc:
|
455
|
+
def call(controller, &block)
|
456
|
+
controller.send(@filter, &block)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
class ProcFilter < Filter #:nodoc:
|
461
|
+
def call(controller)
|
462
|
+
@filter.call(controller)
|
463
|
+
rescue LocalJumpError # a yield from a proc... no no bad dog.
|
464
|
+
raise(ActionControllerError, 'Cannot yield from a Proc type filter. The Proc must take two arguments and execute #call on the second argument.')
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
class ProcWithCallFilter < Filter #:nodoc:
|
469
|
+
def call(controller, &block)
|
470
|
+
@filter.call(controller, block)
|
471
|
+
rescue LocalJumpError # a yield from a proc... no no bad dog.
|
472
|
+
raise(ActionControllerError, 'Cannot yield from a Proc type filter. The Proc must take two arguments and execute #call on the second argument.')
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
class MethodFilter < Filter #:nodoc:
|
477
|
+
def call(controller, &block)
|
478
|
+
@filter.call(controller, &block)
|
479
|
+
end
|
480
|
+
end
|
326
481
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
482
|
+
class ClassFilter < Filter #:nodoc:
|
483
|
+
def call(controller, &block)
|
484
|
+
@filter.filter(controller, &block)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
protected
|
489
|
+
def append_filter_to_chain(filters, position = :around, &block)
|
490
|
+
write_inheritable_array('filter_chain', create_filters(filters, position, &block) )
|
491
|
+
end
|
492
|
+
|
493
|
+
def prepend_filter_to_chain(filters, position = :around, &block)
|
494
|
+
write_inheritable_attribute('filter_chain', create_filters(filters, position, &block) + filter_chain)
|
495
|
+
end
|
496
|
+
|
497
|
+
def create_filters(filters, position, &block) #:nodoc:
|
498
|
+
filters, conditions = extract_conditions(filters, &block)
|
499
|
+
filters.map! { |filter| find_or_create_filter(filter,position) }
|
500
|
+
update_conditions(filters, conditions)
|
501
|
+
filters
|
502
|
+
end
|
503
|
+
|
504
|
+
def find_or_create_filter(filter,position)
|
505
|
+
if found_filter = find_filter(filter) { |f| f.send("#{position}?") }
|
506
|
+
found_filter
|
507
|
+
else
|
508
|
+
f = class_for_filter(filter).new(filter)
|
509
|
+
# apply proxy to filter if necessary
|
510
|
+
case position
|
511
|
+
when :before
|
512
|
+
BeforeFilterProxy.new(f)
|
513
|
+
when :after
|
514
|
+
AfterFilterProxy.new(f)
|
515
|
+
else
|
516
|
+
f
|
517
|
+
end
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
# The determination of the filter type was once done at run time.
|
522
|
+
# This method is here to extract as much logic from the filter run time as possible
|
523
|
+
def class_for_filter(filter) #:nodoc:
|
524
|
+
case
|
525
|
+
when filter.is_a?(Symbol)
|
526
|
+
SymbolFilter
|
527
|
+
when filter.respond_to?(:call)
|
528
|
+
if filter.is_a?(Method)
|
529
|
+
MethodFilter
|
530
|
+
elsif filter.arity == 1
|
531
|
+
ProcFilter
|
532
|
+
else
|
533
|
+
ProcWithCallFilter
|
534
|
+
end
|
535
|
+
when filter.respond_to?(:filter)
|
536
|
+
ClassFilter
|
537
|
+
else
|
538
|
+
raise(ActionControllerError, 'A filters must be a Symbol, Proc, Method, or object responding to filter.')
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
def extract_conditions(*filters, &block) #:nodoc:
|
543
|
+
filters.flatten!
|
544
|
+
conditions = filters.last.is_a?(Hash) ? filters.pop : {}
|
545
|
+
filters << block if block_given?
|
546
|
+
return filters, conditions
|
547
|
+
end
|
548
|
+
|
549
|
+
def update_conditions(filters, conditions)
|
550
|
+
return if conditions.empty?
|
551
|
+
if conditions[:only]
|
552
|
+
write_inheritable_hash('included_actions', condition_hash(filters, conditions[:only]))
|
553
|
+
else
|
554
|
+
write_inheritable_hash('excluded_actions', condition_hash(filters, conditions[:except])) if conditions[:except]
|
555
|
+
end
|
332
556
|
end
|
333
557
|
|
334
558
|
def condition_hash(filters, *actions)
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
filters
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
559
|
+
actions = actions.flatten.map(&:to_s)
|
560
|
+
filters.inject({}) { |h,f| h.update( f => (actions.blank? ? nil : actions)) }
|
561
|
+
end
|
562
|
+
|
563
|
+
def skip_filter_in_chain(*filters, &test) #:nodoc:
|
564
|
+
filters, conditions = extract_conditions(filters)
|
565
|
+
filters.map! { |f| block_given? ? find_filter(f, &test) : find_filter(f) }
|
566
|
+
filters.compact!
|
567
|
+
|
568
|
+
if conditions.empty?
|
569
|
+
delete_filters_in_chain(filters)
|
570
|
+
else
|
571
|
+
remove_actions_from_included_actions!(filters,conditions[:only] || [])
|
572
|
+
conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
|
573
|
+
update_conditions(filters,conditions)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
def remove_actions_from_included_actions!(filters,*actions)
|
578
|
+
actions = actions.flatten.map(&:to_s)
|
579
|
+
updated_hash = filters.inject(included_actions) do |hash,filter|
|
580
|
+
ia = (hash[filter] || []) - actions
|
581
|
+
ia.blank? ? hash.delete(filter) : hash[filter] = ia
|
582
|
+
hash
|
583
|
+
end
|
584
|
+
write_inheritable_attribute('included_actions', updated_hash)
|
585
|
+
end
|
586
|
+
|
587
|
+
def delete_filters_in_chain(filters) #:nodoc:
|
588
|
+
write_inheritable_attribute('filter_chain', filter_chain.reject { |f| filters.include?(f) })
|
589
|
+
end
|
590
|
+
|
591
|
+
def filter_responds_to_before_and_after(filter) #:nodoc:
|
592
|
+
filter.respond_to?(:before) && filter.respond_to?(:after)
|
593
|
+
end
|
594
|
+
|
595
|
+
def proxy_before_and_after_filter(filter) #:nodoc:
|
596
|
+
return filter unless filter_responds_to_before_and_after(filter)
|
597
|
+
Proc.new do |controller, action|
|
598
|
+
unless filter.before(controller) == false
|
599
|
+
begin
|
600
|
+
action.call
|
601
|
+
ensure
|
602
|
+
filter.after(controller)
|
603
|
+
end
|
345
604
|
end
|
346
605
|
end
|
347
606
|
end
|
@@ -350,26 +609,14 @@ module ActionController #:nodoc:
|
|
350
609
|
module InstanceMethods # :nodoc:
|
351
610
|
def self.included(base)
|
352
611
|
base.class_eval do
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
alias_method :process_without_filters, :process
|
357
|
-
alias_method :process, :process_with_filters
|
358
|
-
|
359
|
-
alias_method :process_cleanup_without_filters, :process_cleanup
|
360
|
-
alias_method :process_cleanup, :process_cleanup_with_filters
|
612
|
+
alias_method_chain :perform_action, :filters
|
613
|
+
alias_method_chain :process, :filters
|
614
|
+
alias_method_chain :process_cleanup, :filters
|
361
615
|
end
|
362
616
|
end
|
363
617
|
|
364
618
|
def perform_action_with_filters
|
365
|
-
|
366
|
-
|
367
|
-
unless before_action_result == false || performed?
|
368
|
-
perform_action_without_filters
|
369
|
-
after_action
|
370
|
-
end
|
371
|
-
|
372
|
-
@before_filter_chain_aborted = (before_action_result == false)
|
619
|
+
call_filter(self.class.filter_chain, 0)
|
373
620
|
end
|
374
621
|
|
375
622
|
def process_with_filters(request, response, method = :perform_action, *arguments) #:nodoc:
|
@@ -377,61 +624,37 @@ module ActionController #:nodoc:
|
|
377
624
|
process_without_filters(request, response, method, *arguments)
|
378
625
|
end
|
379
626
|
|
380
|
-
|
381
|
-
|
382
|
-
def before_action #:doc:
|
383
|
-
call_filters(self.class.before_filters)
|
627
|
+
def filter_chain
|
628
|
+
self.class.filter_chain
|
384
629
|
end
|
385
630
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
end
|
391
|
-
|
392
|
-
private
|
393
|
-
def call_filters(filters)
|
394
|
-
filters.each do |filter|
|
395
|
-
next if action_exempted?(filter)
|
396
|
-
|
397
|
-
filter_result = case
|
398
|
-
when filter.is_a?(Symbol)
|
399
|
-
self.send(filter)
|
400
|
-
when filter_block?(filter)
|
401
|
-
filter.call(self)
|
402
|
-
when filter_class?(filter)
|
403
|
-
filter.filter(self)
|
404
|
-
else
|
405
|
-
raise(
|
406
|
-
ActionControllerError,
|
407
|
-
'Filters need to be either a symbol, proc/method, or class implementing a static filter method'
|
408
|
-
)
|
409
|
-
end
|
631
|
+
def call_filter(chain, index)
|
632
|
+
return (performed? || perform_action_without_filters) if index >= chain.size
|
633
|
+
filter = chain[index]
|
634
|
+
return call_filter(chain, index.next) if self.class.filter_excluded_from_action?(filter,action_name)
|
410
635
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
def filter_block?(filter)
|
419
|
-
filter.respond_to?('call') && (filter.arity == 1 || filter.arity == -1)
|
420
|
-
end
|
421
|
-
|
422
|
-
def filter_class?(filter)
|
423
|
-
filter.respond_to?('filter')
|
636
|
+
halted = false
|
637
|
+
filter.call(self) do
|
638
|
+
halted = call_filter(chain, index.next)
|
424
639
|
end
|
640
|
+
halt_filter_chain(filter.filter, :no_yield) if halted == false unless @before_filter_chain_aborted
|
641
|
+
halted
|
642
|
+
end
|
425
643
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
644
|
+
def halt_filter_chain(filter, reason)
|
645
|
+
if logger
|
646
|
+
case reason
|
647
|
+
when :no_yield
|
648
|
+
logger.info "Filter chain halted as [#{filter.inspect}] did not yield."
|
649
|
+
when :returned_false
|
650
|
+
logger.info "Filter chain halted as [#{filter.inspect}] returned false."
|
432
651
|
end
|
433
652
|
end
|
653
|
+
@before_filter_chain_aborted = true
|
654
|
+
return false
|
655
|
+
end
|
434
656
|
|
657
|
+
private
|
435
658
|
def process_cleanup_with_filters
|
436
659
|
if @before_filter_chain_aborted
|
437
660
|
close_session
|