actionpack 1.11.2 → 1.12.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 +392 -5
- data/lib/action_controller.rb +8 -4
- data/lib/action_controller/assertions.rb +9 -10
- data/lib/action_controller/base.rb +177 -88
- data/lib/action_controller/benchmarking.rb +5 -5
- data/lib/action_controller/caching.rb +44 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +71 -6
- data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +1 -1
- data/lib/action_controller/cgi_process.rb +36 -24
- data/lib/action_controller/components.rb +152 -52
- data/lib/action_controller/dependencies.rb +1 -1
- data/lib/action_controller/deprecated_redirects.rb +2 -2
- data/lib/action_controller/deprecated_request_methods.rb +34 -0
- data/lib/action_controller/filters.rb +59 -19
- data/lib/action_controller/flash.rb +53 -47
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/integration.rb +524 -0
- data/lib/action_controller/layout.rb +58 -23
- data/lib/action_controller/mime_responds.rb +163 -0
- data/lib/action_controller/mime_type.rb +142 -0
- data/lib/action_controller/pagination.rb +13 -7
- data/lib/action_controller/request.rb +59 -56
- data/lib/action_controller/rescue.rb +1 -1
- data/lib/action_controller/routing.rb +29 -10
- data/lib/action_controller/scaffolding.rb +8 -0
- data/lib/action_controller/session/active_record_store.rb +21 -10
- data/lib/action_controller/session/mem_cache_store.rb +18 -12
- data/lib/action_controller/session_management.rb +30 -11
- data/lib/action_controller/templates/rescues/_trace.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/layout.rhtml +4 -4
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +189 -118
- data/lib/action_controller/vendor/html-scanner/html/node.rb +20 -1
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +3 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +1 -1
- data/lib/action_controller/vendor/xml_node.rb +97 -0
- data/lib/action_controller/verification.rb +2 -0
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +0 -2
- data/lib/action_view/base.rb +109 -36
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +4 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +6 -7
- data/lib/action_view/helpers/capture_helper.rb +49 -12
- data/lib/action_view/helpers/date_helper.rb +14 -4
- data/lib/action_view/helpers/form_helper.rb +136 -20
- data/lib/action_view/helpers/form_options_helper.rb +29 -7
- data/lib/action_view/helpers/form_tag_helper.rb +22 -20
- data/lib/action_view/helpers/java_script_macros_helper.rb +29 -9
- data/lib/action_view/helpers/javascript_helper.rb +50 -446
- data/lib/action_view/helpers/javascripts/controls.js +95 -30
- data/lib/action_view/helpers/javascripts/dragdrop.js +161 -21
- data/lib/action_view/helpers/javascripts/effects.js +310 -211
- data/lib/action_view/helpers/javascripts/prototype.js +228 -28
- data/lib/action_view/helpers/number_helper.rb +9 -9
- data/lib/action_view/helpers/pagination_helper.rb +1 -1
- data/lib/action_view/helpers/prototype_helper.rb +900 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +135 -0
- data/lib/action_view/helpers/text_helper.rb +7 -6
- data/lib/action_view/helpers/url_helper.rb +23 -14
- data/lib/action_view/partials.rb +12 -4
- data/rakefile +13 -5
- data/test/abstract_unit.rb +4 -3
- data/test/active_record_unit.rb +88 -0
- data/test/{controller → activerecord}/active_record_assertions_test.rb +7 -50
- data/test/{controller → activerecord}/active_record_store_test.rb +27 -4
- data/test/activerecord/pagination_test.rb +161 -0
- data/test/controller/action_pack_assertions_test.rb +18 -15
- data/test/controller/base_test.rb +31 -42
- data/test/controller/benchmark_test.rb +8 -11
- data/test/controller/capture_test.rb +33 -1
- data/test/controller/cgi_test.rb +33 -0
- data/test/controller/custom_handler_test.rb +8 -0
- data/test/controller/fake_controllers.rb +9 -17
- data/test/controller/filters_test.rb +32 -3
- data/test/controller/flash_test.rb +26 -41
- data/test/controller/fragment_store_setting_test.rb +1 -1
- data/test/controller/layout_test.rb +73 -0
- data/test/controller/mime_responds_test.rb +257 -0
- data/test/controller/mime_type_test.rb +24 -0
- data/test/controller/new_render_test.rb +157 -1
- data/test/controller/redirect_test.rb +23 -0
- data/test/controller/render_test.rb +54 -56
- data/test/controller/request_test.rb +25 -0
- data/test/controller/routing_test.rb +74 -66
- data/test/controller/test_test.rb +66 -1
- data/test/controller/verification_test.rb +3 -1
- data/test/controller/webservice_test.rb +255 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +9 -0
- data/test/fixtures/db_definitions/sqlite.sql +42 -0
- data/test/fixtures/developer.rb +7 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/replies.yml +13 -0
- data/test/fixtures/reply.rb +5 -0
- data/test/fixtures/respond_to/all_types_with_layout.rhtml +1 -0
- data/test/fixtures/respond_to/all_types_with_layout.rjs +1 -0
- data/test/fixtures/respond_to/layouts/standard.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.rxml +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rxml +1 -0
- data/test/fixtures/test/block_content_for.rhtml +2 -0
- data/test/fixtures/test/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.rhtml +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.rhtml +2 -0
- data/test/fixtures/test/hello_world.rxml +3 -0
- data/test/fixtures/test/hello_world_with_layout_false.rhtml +1 -0
- data/test/fixtures/test/non_erb_block_content_for.rxml +4 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/template/active_record_helper_test.rb +4 -0
- data/test/template/asset_tag_helper_test.rb +7 -2
- data/test/template/date_helper_test.rb +39 -2
- data/test/template/form_helper_test.rb +238 -5
- data/test/template/form_options_helper_test.rb +78 -0
- data/test/template/form_tag_helper_test.rb +11 -0
- data/test/template/java_script_macros_helper_test.rb +51 -6
- data/test/template/javascript_helper_test.rb +7 -153
- data/test/template/number_helper_test.rb +14 -13
- data/test/template/prototype_helper_test.rb +423 -0
- data/test/template/scriptaculous_helper_test.rb +90 -0
- data/test/template/text_helper_test.rb +12 -9
- data/test/template/url_helper_test.rb +31 -15
- metadata +291 -246
- data/lib/action_controller/cgi_ext/multipart_progress.rb +0 -169
- data/lib/action_controller/upload_progress.rb +0 -473
- data/lib/action_controller/vendor/html-scanner/html/node.rb.rej +0 -17
- data/lib/action_view/helpers/upload_progress_helper.rb +0 -433
- data/lib/action_view/vendor/builder.rb +0 -13
- data/lib/action_view/vendor/builder/blankslate.rb +0 -53
- data/lib/action_view/vendor/builder/xmlbase.rb +0 -143
- data/lib/action_view/vendor/builder/xmlevents.rb +0 -63
- data/lib/action_view/vendor/builder/xmlmarkup.rb +0 -308
- data/test/controller/multipart_progress_testx.rb +0 -365
- data/test/controller/upload_progress_testx.rb +0 -89
- data/test/template/upload_progress_helper_testx.rb +0 -136
@@ -1,18 +1,18 @@
|
|
1
1
|
module ActionController #:nodoc:
|
2
|
-
# Components
|
2
|
+
# Components allow you to call other actions for their rendered response while executing another action. You can either delegate
|
3
3
|
# the entire response rendering or you can mix a partial response in with your other content.
|
4
4
|
#
|
5
5
|
# class WeblogController < ActionController::Base
|
6
6
|
# # Performs a method and then lets hello_world output its render
|
7
7
|
# def delegate_action
|
8
8
|
# do_other_stuff_before_hello_world
|
9
|
-
# render_component :controller => "greeter", :action => "hello_world", :params => {
|
9
|
+
# render_component :controller => "greeter", :action => "hello_world", :params => { :person => "david" }
|
10
10
|
# end
|
11
11
|
# end
|
12
12
|
#
|
13
13
|
# class GreeterController < ActionController::Base
|
14
14
|
# def hello_world
|
15
|
-
#
|
15
|
+
# render :text => "#{params[:person]} says, Hello World!"
|
16
16
|
# end
|
17
17
|
# end
|
18
18
|
#
|
@@ -20,67 +20,167 @@ module ActionController #:nodoc:
|
|
20
20
|
#
|
21
21
|
# Let's see a greeting:
|
22
22
|
# <%= render_component :controller => "greeter", :action => "hello_world" %>
|
23
|
+
#
|
24
|
+
# It is also possible to specify the controller as a class constant, bypassing the inflector
|
25
|
+
# code to compute the controller class at runtime:
|
26
|
+
#
|
27
|
+
# <%= render_component :controller => GreeterController, :action => "hello_world" %>
|
28
|
+
#
|
29
|
+
# == When to use components
|
30
|
+
#
|
31
|
+
# Components should be used with care. They're significantly slower than simply splitting reusable parts into partials and
|
32
|
+
# conceptually more complicated. Don't use components as a way of separating concerns inside a single application. Instead,
|
33
|
+
# reserve components to those rare cases where you truly have reusable view and controller elements that can be employed
|
34
|
+
# across many applications at once.
|
35
|
+
#
|
36
|
+
# So to repeat: Components are a special-purpose approach that can often be replaced with better use of partials and filters.
|
23
37
|
module Components
|
24
|
-
def self.
|
25
|
-
|
38
|
+
def self.included(base) #:nodoc:
|
39
|
+
base.send :include, InstanceMethods
|
40
|
+
base.extend(ClassMethods)
|
41
|
+
|
26
42
|
base.helper do
|
27
43
|
def render_component(options)
|
28
44
|
@controller.send(:render_component_as_string, options)
|
29
45
|
end
|
30
46
|
end
|
31
|
-
|
47
|
+
|
48
|
+
# If this controller was instantiated to process a component request,
|
49
|
+
# +parent_controller+ points to the instantiator of this controller.
|
50
|
+
base.send :attr_accessor, :parent_controller
|
51
|
+
|
52
|
+
base.class_eval do
|
53
|
+
alias_method :process_cleanup_without_components, :process_cleanup
|
54
|
+
alias_method :process_cleanup, :process_cleanup_with_components
|
55
|
+
|
56
|
+
alias_method :set_session_options_without_components, :set_session_options
|
57
|
+
alias_method :set_session_options, :set_session_options_with_components
|
58
|
+
|
59
|
+
alias_method :flash_without_components, :flash
|
60
|
+
alias_method :flash, :flash_with_components
|
32
61
|
|
33
|
-
|
34
|
-
# Renders the component specified as the response for the current method
|
35
|
-
def render_component(options = {}) #:doc:
|
36
|
-
component_logging(options) { render_text(component_response(options).body, response.headers["Status"]) }
|
62
|
+
alias_method :component_request?, :parent_controller
|
37
63
|
end
|
64
|
+
end
|
38
65
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
else
|
46
|
-
response.body
|
47
|
-
end
|
48
|
-
end
|
66
|
+
module ClassMethods
|
67
|
+
# Track parent controller to identify component requests
|
68
|
+
def process_with_components(request, response, parent_controller = nil) #:nodoc:
|
69
|
+
controller = new
|
70
|
+
controller.parent_controller = parent_controller
|
71
|
+
controller.process(request, response)
|
49
72
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
def request_for_component(options)
|
67
|
-
request_for_component = @request.dup
|
68
|
-
request_for_component.send(
|
69
|
-
:instance_variable_set, :@parameters,
|
70
|
-
(options[:params] || {}).merge({ "controller" => options[:controller], "action" => options[:action], "id" => options[:id] }).with_indifferent_access
|
71
|
-
)
|
72
|
-
return request_for_component
|
73
|
+
|
74
|
+
# Set the template root to be one directory behind the root dir of the controller. Examples:
|
75
|
+
# /code/weblog/components/admin/users_controller.rb with Admin::UsersController
|
76
|
+
# will use /code/weblog/components as template root
|
77
|
+
# and find templates in /code/weblog/components/admin/users/
|
78
|
+
#
|
79
|
+
# /code/weblog/components/admin/parties/users_controller.rb with Admin::Parties::UsersController
|
80
|
+
# will also use /code/weblog/components as template root
|
81
|
+
# and find templates in /code/weblog/components/admin/parties/users/
|
82
|
+
def uses_component_template_root
|
83
|
+
path_of_calling_controller = File.dirname(caller[0].split(/:\d+:/).first)
|
84
|
+
path_of_controller_root = path_of_calling_controller.sub(/#{controller_path.split("/")[0..-2]}$/, "") # " (for ruby-mode)
|
85
|
+
|
86
|
+
self.template_root = path_of_controller_root
|
73
87
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
88
|
+
end
|
89
|
+
|
90
|
+
module InstanceMethods
|
91
|
+
# Extracts the action_name from the request parameters and performs that action.
|
92
|
+
def process_with_components(request, response, method = :perform_action, *arguments) #:nodoc:
|
93
|
+
flash.discard if component_request?
|
94
|
+
process_without_components(request, response, method, *arguments)
|
77
95
|
end
|
78
96
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
97
|
+
protected
|
98
|
+
# Renders the component specified as the response for the current method
|
99
|
+
def render_component(options) #:doc:
|
100
|
+
component_logging(options) do
|
101
|
+
render_text(component_response(options, true).body, response.headers["Status"])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the component response as a string
|
106
|
+
def render_component_as_string(options) #:doc:
|
107
|
+
component_logging(options) do
|
108
|
+
response = component_response(options, false)
|
109
|
+
|
110
|
+
if redirected = response.redirected_to
|
111
|
+
render_component_as_string(redirected)
|
112
|
+
else
|
113
|
+
response.body
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def flash_with_components(refresh = false) #:nodoc:
|
119
|
+
if @flash.nil? || refresh
|
120
|
+
@flash =
|
121
|
+
if @parent_controller
|
122
|
+
@parent_controller.flash
|
123
|
+
else
|
124
|
+
flash_without_components
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
@flash
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
def component_response(options, reuse_response)
|
133
|
+
klass = component_class(options)
|
134
|
+
request = request_for_component(klass.controller_name, options)
|
135
|
+
response = reuse_response ? @response : @response.dup
|
136
|
+
|
137
|
+
klass.process_with_components(request, response, self)
|
138
|
+
end
|
139
|
+
|
140
|
+
# determine the controller class for the component request
|
141
|
+
def component_class(options)
|
142
|
+
if controller = options[:controller]
|
143
|
+
controller.is_a?(Class) ? controller : "#{controller.camelize}Controller".constantize
|
144
|
+
else
|
145
|
+
self.class
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Create a new request object based on the current request.
|
150
|
+
# The new request inherits the session from the current request,
|
151
|
+
# bypassing any session options set for the component controller's class
|
152
|
+
def request_for_component(controller_name, options)
|
153
|
+
request = @request.dup
|
154
|
+
request.session = @request.session
|
155
|
+
|
156
|
+
request.instance_variable_set(
|
157
|
+
:@parameters,
|
158
|
+
(options[:params] || {}).with_indifferent_access.update(
|
159
|
+
"controller" => controller_name, "action" => options[:action], "id" => options[:id]
|
160
|
+
)
|
161
|
+
)
|
162
|
+
|
163
|
+
request
|
164
|
+
end
|
165
|
+
|
166
|
+
def component_logging(options)
|
167
|
+
if logger
|
168
|
+
logger.info "Start rendering component (#{options.inspect}): "
|
169
|
+
result = yield
|
170
|
+
logger.info "\n\nEnd of component rendering"
|
171
|
+
result
|
172
|
+
else
|
173
|
+
yield
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def set_session_options_with_components(request)
|
178
|
+
set_session_options_without_components(request) unless component_request?
|
179
|
+
end
|
180
|
+
|
181
|
+
def process_cleanup_with_components
|
182
|
+
process_cleanup_without_components unless component_request?
|
183
|
+
end
|
184
|
+
end
|
85
185
|
end
|
86
186
|
end
|
@@ -28,7 +28,7 @@ module ActionController #:nodoc:
|
|
28
28
|
#
|
29
29
|
# Also note, that if the models follow the pattern of just 1 class per file in the form of MyClass => my_class.rb, then these
|
30
30
|
# classes don't have to be required as Active Support will auto-require them.
|
31
|
-
module ClassMethods
|
31
|
+
module ClassMethods #:nodoc:
|
32
32
|
# Specifies a variable number of models that this controller depends on. Models are normally Active Record classes or a similar
|
33
33
|
# backend for modelling entity classes.
|
34
34
|
def model(*models)
|
@@ -2,14 +2,14 @@ module ActionController
|
|
2
2
|
class Base
|
3
3
|
protected
|
4
4
|
# Deprecated in favor of calling redirect_to directly with the path.
|
5
|
-
def redirect_to_path(path)
|
5
|
+
def redirect_to_path(path) #:nodoc:
|
6
6
|
redirect_to(path)
|
7
7
|
end
|
8
8
|
|
9
9
|
# Deprecated in favor of calling redirect_to directly with the url. If the resource has moved permanently, it's possible to pass
|
10
10
|
# true as the second parameter and the browser will get "301 Moved Permanently" instead of "302 Found". This can also be done through
|
11
11
|
# just setting the headers["Status"] to "301 Moved Permanently" before using the redirect_to.
|
12
|
-
def redirect_to_url(url, permanently = false)
|
12
|
+
def redirect_to_url(url, permanently = false) #:nodoc:
|
13
13
|
headers["Status"] = "301 Moved Permanently" if permanently
|
14
14
|
redirect_to(url)
|
15
15
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActionController
|
2
|
+
class AbstractRequest
|
3
|
+
# Determine whether the body of a HTTP call is URL-encoded (default)
|
4
|
+
# or matches one of the registered param_parsers.
|
5
|
+
#
|
6
|
+
# For backward compatibility, the post format is extracted from the
|
7
|
+
# X-Post-Data-Format HTTP header if present.
|
8
|
+
def post_format
|
9
|
+
case content_type.to_s
|
10
|
+
when 'application/xml'
|
11
|
+
:xml
|
12
|
+
when 'application/x-yaml'
|
13
|
+
:yaml
|
14
|
+
else
|
15
|
+
:url_encoded
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Is this a POST request formatted as XML or YAML?
|
20
|
+
def formatted_post?
|
21
|
+
post? && (post_format == :yaml || post_format == :xml)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Is this a POST request formatted as XML?
|
25
|
+
def xml_post?
|
26
|
+
post? && post_format == :xml
|
27
|
+
end
|
28
|
+
|
29
|
+
# Is this a POST request formatted as YAML?
|
30
|
+
def yaml_post?
|
31
|
+
post? && post_format == :yaml
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ActionController #:nodoc:
|
2
2
|
module Filters #:nodoc:
|
3
|
-
def self.
|
4
|
-
super
|
3
|
+
def self.included(base)
|
5
4
|
base.extend(ClassMethods)
|
6
5
|
base.send(:include, ActionController::Filters::InstanceMethods)
|
7
6
|
end
|
@@ -141,7 +140,7 @@ module ActionController #:nodoc:
|
|
141
140
|
# # will run the :authenticate filter
|
142
141
|
# end
|
143
142
|
#
|
144
|
-
# class SignupController <
|
143
|
+
# class SignupController < ApplicationController
|
145
144
|
# # will not run the :authenticate filter
|
146
145
|
# skip_before_filter :authenticate
|
147
146
|
# end
|
@@ -251,39 +250,55 @@ module ActionController #:nodoc:
|
|
251
250
|
# Removes the specified filters from the +before+ filter chain. Note that this only works for skipping method-reference
|
252
251
|
# filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out
|
253
252
|
# of many sub-controllers need a different hierarchy.
|
253
|
+
#
|
254
|
+
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
255
|
+
# just like when you apply the filters.
|
254
256
|
def skip_before_filter(*filters)
|
255
|
-
|
256
|
-
|
257
|
+
if conditions = extract_conditions!(filters)
|
258
|
+
conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
|
259
|
+
add_action_conditions(filters, conditions)
|
260
|
+
else
|
261
|
+
for filter in filters.flatten
|
262
|
+
write_inheritable_attribute("before_filters", read_inheritable_attribute("before_filters") - [ filter ])
|
263
|
+
end
|
257
264
|
end
|
258
265
|
end
|
259
266
|
|
260
267
|
# Removes the specified filters from the +after+ filter chain. Note that this only works for skipping method-reference
|
261
268
|
# filters, not procs. This is especially useful for managing the chain in inheritance hierarchies where only one out
|
262
269
|
# of many sub-controllers need a different hierarchy.
|
270
|
+
#
|
271
|
+
# You can control the actions to skip the filter for with the <tt>:only</tt> and <tt>:except</tt> options,
|
272
|
+
# just like when you apply the filters.
|
263
273
|
def skip_after_filter(*filters)
|
264
|
-
|
265
|
-
|
274
|
+
if conditions = extract_conditions!(filters)
|
275
|
+
conditions[:only], conditions[:except] = conditions[:except], conditions[:only]
|
276
|
+
add_action_conditions(filters, conditions)
|
277
|
+
else
|
278
|
+
for filter in filters.flatten
|
279
|
+
write_inheritable_attribute("after_filters", read_inheritable_attribute("after_filters") - [ filter ])
|
280
|
+
end
|
266
281
|
end
|
267
282
|
end
|
268
283
|
|
269
284
|
# Returns all the before filters for this class and all its ancestors.
|
270
285
|
def before_filters #:nodoc:
|
271
|
-
read_inheritable_attribute("before_filters")
|
286
|
+
@before_filters ||= read_inheritable_attribute("before_filters") || []
|
272
287
|
end
|
273
288
|
|
274
289
|
# Returns all the after filters for this class and all its ancestors.
|
275
290
|
def after_filters #:nodoc:
|
276
|
-
read_inheritable_attribute("after_filters")
|
291
|
+
@after_filters ||= read_inheritable_attribute("after_filters") || []
|
277
292
|
end
|
278
293
|
|
279
294
|
# Returns a mapping between filters and the actions that may run them.
|
280
295
|
def included_actions #:nodoc:
|
281
|
-
read_inheritable_attribute("included_actions") || {}
|
296
|
+
@included_actions ||= read_inheritable_attribute("included_actions") || {}
|
282
297
|
end
|
283
298
|
|
284
299
|
# Returns a mapping between filters and actions that may not run them.
|
285
300
|
def excluded_actions #:nodoc:
|
286
|
-
read_inheritable_attribute("excluded_actions") || {}
|
301
|
+
@excluded_actions ||= read_inheritable_attribute("excluded_actions") || {}
|
287
302
|
end
|
288
303
|
|
289
304
|
private
|
@@ -292,7 +307,8 @@ module ActionController #:nodoc:
|
|
292
307
|
end
|
293
308
|
|
294
309
|
def prepend_filter_to_chain(condition, filters)
|
295
|
-
|
310
|
+
old_filters = read_inheritable_attribute("#{condition}_filters") || []
|
311
|
+
write_inheritable_attribute("#{condition}_filters", filters + old_filters)
|
296
312
|
end
|
297
313
|
|
298
314
|
def ensure_filter_responds_to_before_and_after(filter)
|
@@ -319,18 +335,33 @@ module ActionController #:nodoc:
|
|
319
335
|
end
|
320
336
|
|
321
337
|
module InstanceMethods # :nodoc:
|
322
|
-
def self.
|
323
|
-
|
324
|
-
base.class_eval {
|
338
|
+
def self.included(base)
|
339
|
+
base.class_eval do
|
325
340
|
alias_method :perform_action_without_filters, :perform_action
|
326
341
|
alias_method :perform_action, :perform_action_with_filters
|
327
|
-
|
342
|
+
|
343
|
+
alias_method :process_without_filters, :process
|
344
|
+
alias_method :process, :process_with_filters
|
345
|
+
|
346
|
+
alias_method :process_cleanup_without_filters, :process_cleanup
|
347
|
+
alias_method :process_cleanup, :process_cleanup_with_filters
|
348
|
+
end
|
328
349
|
end
|
329
350
|
|
330
351
|
def perform_action_with_filters
|
331
|
-
|
332
|
-
|
333
|
-
|
352
|
+
before_action_result = before_action
|
353
|
+
|
354
|
+
unless before_action_result == false || performed?
|
355
|
+
perform_action_without_filters
|
356
|
+
after_action
|
357
|
+
end
|
358
|
+
|
359
|
+
@before_filter_chain_aborted = (before_action_result == false)
|
360
|
+
end
|
361
|
+
|
362
|
+
def process_with_filters(request, response, method = :perform_action, *arguments) #:nodoc:
|
363
|
+
@before_filter_chain_aborted = false
|
364
|
+
process_without_filters(request, response, method, *arguments)
|
334
365
|
end
|
335
366
|
|
336
367
|
# Calls all the defined before-filter filters, which are added by using "before_filter :method".
|
@@ -349,6 +380,7 @@ module ActionController #:nodoc:
|
|
349
380
|
def call_filters(filters)
|
350
381
|
filters.each do |filter|
|
351
382
|
next if action_exempted?(filter)
|
383
|
+
|
352
384
|
filter_result = case
|
353
385
|
when filter.is_a?(Symbol)
|
354
386
|
self.send(filter)
|
@@ -386,6 +418,14 @@ module ActionController #:nodoc:
|
|
386
418
|
ea.include?(action_name)
|
387
419
|
end
|
388
420
|
end
|
421
|
+
|
422
|
+
def process_cleanup_with_filters
|
423
|
+
if @before_filter_chain_aborted
|
424
|
+
close_session
|
425
|
+
else
|
426
|
+
process_cleanup_without_filters
|
427
|
+
end
|
428
|
+
end
|
389
429
|
end
|
390
430
|
end
|
391
431
|
end
|