actionpack 3.0.0.rc → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +11 -16
- data/README.rdoc +3 -3
- data/lib/abstract_controller/base.rb +28 -14
- data/lib/abstract_controller/callbacks.rb +22 -23
- data/lib/abstract_controller/helpers.rb +24 -7
- data/lib/abstract_controller/layouts.rb +12 -10
- data/lib/abstract_controller/view_paths.rb +7 -7
- data/lib/abstract_controller.rb +1 -0
- data/lib/action_controller/base.rb +165 -2
- data/lib/action_controller/deprecated/base.rb +11 -1
- data/lib/action_controller/deprecated/url_writer.rb +14 -0
- data/lib/action_controller/metal/http_authentication.rb +3 -3
- data/lib/action_controller/metal/responder.rb +2 -8
- data/lib/action_controller/middleware.rb +1 -1
- data/lib/action_controller/test_case.rb +2 -1
- data/lib/action_controller/vendor/html-scanner/html/document.rb +2 -2
- data/lib/action_controller/vendor/html-scanner/html/node.rb +29 -29
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +25 -25
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +8 -8
- data/lib/action_controller.rb +2 -1
- data/lib/action_dispatch/http/cache.rb +2 -2
- data/lib/action_dispatch/http/mime_negotiation.rb +1 -1
- data/lib/action_dispatch/http/mime_type.rb +10 -10
- data/lib/action_dispatch/http/parameters.rb +2 -2
- data/lib/action_dispatch/http/request.rb +7 -0
- data/lib/action_dispatch/http/url.rb +12 -2
- data/lib/action_dispatch/middleware/best_standards_support.rb +22 -0
- data/lib/action_dispatch/middleware/cookies.rb +29 -10
- data/lib/action_dispatch/middleware/flash.rb +7 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +1 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +2 -9
- data/lib/action_dispatch/middleware/stack.rb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -1
- data/lib/action_dispatch/routing/deprecated_mapper.rb +1 -0
- data/lib/action_dispatch/routing/mapper.rb +120 -137
- data/lib/action_dispatch/routing/polymorphic_routes.rb +10 -10
- data/lib/action_dispatch/routing/route_set.rb +8 -5
- data/lib/action_dispatch/routing/url_for.rb +1 -1
- data/lib/action_dispatch/routing.rb +4 -4
- data/lib/action_dispatch/testing/assertions/dom.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +5 -5
- data/lib/action_dispatch/testing/assertions/routing.rb +39 -16
- data/lib/action_dispatch/testing/integration.rb +1 -0
- data/lib/action_dispatch.rb +1 -0
- data/lib/action_pack/version.rb +1 -2
- data/lib/action_view/base.rb +1 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +12 -0
- data/lib/action_view/helpers/capture_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +13 -17
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +16 -10
- data/lib/action_view/helpers/form_options_helper.rb +21 -18
- data/lib/action_view/helpers/form_tag_helper.rb +9 -9
- data/lib/action_view/helpers/number_helper.rb +1 -1
- data/lib/action_view/helpers/raw_output_helper.rb +1 -1
- data/lib/action_view/helpers/sanitize_helper.rb +4 -2
- data/lib/action_view/helpers/text_helper.rb +5 -2
- data/lib/action_view/helpers/translation_helper.rb +9 -9
- data/lib/action_view/helpers/url_helper.rb +2 -2
- data/lib/action_view/log_subscriber.rb +1 -1
- data/lib/action_view/render/layouts.rb +8 -4
- data/lib/action_view/render/partials.rb +1 -1
- data/lib/action_view/template/handler.rb +1 -1
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/resolver.rb +15 -0
- data/lib/action_view/template.rb +3 -3
- data/lib/action_view/test_case.rb +1 -1
- data/lib/action_view/testing/resolvers.rb +1 -1
- metadata +20 -23
data/CHANGELOG
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
*Rails 3.0.0
|
|
1
|
+
*Rails 3.0.0 (August 29, 2010)*
|
|
2
|
+
|
|
3
|
+
* Symbols and strings in routes should yield the same behavior. Note this may break existing apps that were using symbols with the new routes API [José Valim]
|
|
4
|
+
|
|
5
|
+
* Add clear_helpers as a way to clean up all helpers added to this controller, maintaing just the helper with the same name as the controller. [José Valim]
|
|
6
|
+
|
|
7
|
+
* Support routing constraints in functional tests. [Andrew White]
|
|
8
|
+
|
|
9
|
+
* Add a header that tells Internet Explorer (all versions) to use the best available standards support. [Yehuda Katz]
|
|
2
10
|
|
|
3
11
|
* Allow stylesheet/javascript extensions to be changed through railties. [Josh Kalderimis]
|
|
4
12
|
|
|
@@ -26,16 +34,13 @@
|
|
|
26
34
|
resources :comments
|
|
27
35
|
end
|
|
28
36
|
end
|
|
29
|
-
|
|
37
|
+
|
|
30
38
|
You can now use comment_path for /comments/1 instead of post_comment_path for /posts/1/comments/1.
|
|
31
39
|
|
|
32
40
|
* Add support for multi-subdomain session by setting cookie host in session cookie so you can share session between www.example.com, example.com and user.example.com. #4818 [Guillermo Álvarez]
|
|
33
41
|
|
|
34
42
|
* Removed textilize, textilize_without_paragraph and markdown helpers. [Santiago Pastorino]
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
*Rails 3.0.0 [beta 4] (June 8th, 2010)*
|
|
38
|
-
|
|
39
44
|
* Remove middleware laziness [José Valim]
|
|
40
45
|
|
|
41
46
|
* Make session stores rely on request.cookie_jar and change set_session semantics to return the cookie value instead of a boolean. [José Valim]
|
|
@@ -52,9 +57,6 @@
|
|
|
52
57
|
|
|
53
58
|
* Changed translate helper so that it doesn’t mark every translation as safe HTML. Only keys with a "_html" suffix and keys named "html" are considered to be safe HTML. All other translations are left untouched. [Craig Davey]
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
*Rails 3.0.0 [beta 3] (April 13th, 2010)*
|
|
57
|
-
|
|
58
60
|
* New option :as added to form_for allows to change the object name. The old <% form_for :client, @post %> becomes <% form_for @post, :as => :client %> [spastorino]
|
|
59
61
|
|
|
60
62
|
* Removed verify method in controllers. [JV]
|
|
@@ -89,9 +91,6 @@
|
|
|
89
91
|
"HEAD" and #request_method returns "GET" in HEAD requests). This
|
|
90
92
|
is for compatibility with Rack::Request [YK]
|
|
91
93
|
|
|
92
|
-
|
|
93
|
-
*Rails 3.0.0 [beta 2] (April 1st, 2010)*
|
|
94
|
-
|
|
95
94
|
* #concat is now deprecated in favor of using <%= %> helpers [YK]
|
|
96
95
|
|
|
97
96
|
* Block helpers now return Strings, so you can use <%= form_for @foo do |f| %>.
|
|
@@ -110,7 +109,7 @@
|
|
|
110
109
|
* ActionDispatch::Request#content_type returns a String to be compatible with
|
|
111
110
|
Rack::Request. Use #content_mime_type for the Mime::Type instance [YK]
|
|
112
111
|
|
|
113
|
-
* Updated Prototype to 1.6.1 and Scriptaculous to 1.8.3 [ML]
|
|
112
|
+
* Updated Prototype to 1.6.1 and Scriptaculous to 1.8.3 [ML]
|
|
114
113
|
|
|
115
114
|
* Change the preferred way that URL helpers are included into a class[YK & CL]
|
|
116
115
|
|
|
@@ -120,9 +119,6 @@
|
|
|
120
119
|
# for just url_for
|
|
121
120
|
include Rails.application.router.url_for
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
*Rails 3.0.0 [beta 1] (February 4, 2010)*
|
|
125
|
-
|
|
126
122
|
* Fixed that PrototypeHelper#update_page should return html_safe [DHH]
|
|
127
123
|
|
|
128
124
|
* Fixed that much of DateHelper wouldn't return html_safe? strings [DHH]
|
|
@@ -144,7 +140,6 @@
|
|
|
144
140
|
|
|
145
141
|
* Added ActionController::Base#notice/= and ActionController::Base#alert/= as a convenience accessors in both the controller and the view for flash[:notice]/= and flash[:alert]/= [DHH]
|
|
146
142
|
|
|
147
|
-
|
|
148
143
|
* Introduce grouped_collection_select helper. #1249 [Dan Codeape, Erik Ostrom]
|
|
149
144
|
|
|
150
145
|
* Make sure javascript_include_tag/stylesheet_link_tag does not append ".js" or ".css" onto external urls. #1664 [Matthew Rudy Jacobs]
|
data/README.rdoc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
= Action Pack -- From request to response
|
|
2
2
|
|
|
3
|
-
Action Pack is a framework for handling and responding to web requests. It
|
|
3
|
+
Action Pack is a framework for handling and responding to web requests. It
|
|
4
4
|
provides mechanisms for *routing* (mapping request URLs to actions), defining
|
|
5
5
|
*controllers* that implement actions, and generating responses by rendering
|
|
6
6
|
*views*, which are templates of various formats. In short, Action Pack
|
|
@@ -102,10 +102,10 @@ A short rundown of some of the major features:
|
|
|
102
102
|
class WeblogController < ActionController::Base
|
|
103
103
|
# filters as methods
|
|
104
104
|
before_filter :authenticate, :cache, :audit
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
# filter as a proc
|
|
107
107
|
after_filter { |c| c.response.body = Gzip::compress(c.response.body) }
|
|
108
|
-
|
|
108
|
+
|
|
109
109
|
# class filter
|
|
110
110
|
after_filter LocalizeFilter
|
|
111
111
|
|
|
@@ -6,6 +6,10 @@ module AbstractController
|
|
|
6
6
|
class Error < StandardError; end
|
|
7
7
|
class ActionNotFound < StandardError; end
|
|
8
8
|
|
|
9
|
+
# <tt>AbstractController::Base</tt> is a low-level API. Nobody should be
|
|
10
|
+
# using it directly, and subclasses (like ActionController::Base) are
|
|
11
|
+
# expected to provide their own +render+ method, since rendering means
|
|
12
|
+
# different things depending on the context.
|
|
9
13
|
class Base
|
|
10
14
|
attr_internal :response_body
|
|
11
15
|
attr_internal :action_name
|
|
@@ -36,13 +40,12 @@ module AbstractController
|
|
|
36
40
|
controller.public_instance_methods(true)
|
|
37
41
|
end
|
|
38
42
|
|
|
39
|
-
# The list of hidden actions to an empty
|
|
40
|
-
# empty
|
|
43
|
+
# The list of hidden actions to an empty array. Defaults to an
|
|
44
|
+
# empty array. This can be modified by other modules or subclasses
|
|
41
45
|
# to specify particular actions as hidden.
|
|
42
46
|
#
|
|
43
47
|
# ==== Returns
|
|
44
|
-
#
|
|
45
|
-
# considered actions.
|
|
48
|
+
# * <tt>array</tt> - An array of method names that should not be considered actions.
|
|
46
49
|
def hidden_actions
|
|
47
50
|
[]
|
|
48
51
|
end
|
|
@@ -54,8 +57,7 @@ module AbstractController
|
|
|
54
57
|
# itself. Finally, #hidden_actions are removed.
|
|
55
58
|
#
|
|
56
59
|
# ==== Returns
|
|
57
|
-
#
|
|
58
|
-
# actions.
|
|
60
|
+
# * <tt>array</tt> - A list of all methods that should be considered actions.
|
|
59
61
|
def action_methods
|
|
60
62
|
@action_methods ||= begin
|
|
61
63
|
# All public instance methods of this class, including ancestors
|
|
@@ -72,15 +74,27 @@ module AbstractController
|
|
|
72
74
|
end
|
|
73
75
|
end
|
|
74
76
|
|
|
77
|
+
# action_methods are cached and there is sometimes need to refresh
|
|
78
|
+
# them. clear_action_methods! allows you to do that, so next time
|
|
79
|
+
# you run action_methods, they will be recalculated
|
|
80
|
+
def clear_action_methods!
|
|
81
|
+
@action_methods = nil
|
|
82
|
+
end
|
|
83
|
+
|
|
75
84
|
# Returns the full controller name, underscored, without the ending Controller.
|
|
76
85
|
# For instance, MyApp::MyPostsController would return "my_app/my_posts" for
|
|
77
86
|
# controller_name.
|
|
78
87
|
#
|
|
79
88
|
# ==== Returns
|
|
80
|
-
#
|
|
89
|
+
# * <tt>string</tt>
|
|
81
90
|
def controller_path
|
|
82
91
|
@controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
|
|
83
92
|
end
|
|
93
|
+
|
|
94
|
+
def method_added(name)
|
|
95
|
+
super
|
|
96
|
+
clear_action_methods!
|
|
97
|
+
end
|
|
84
98
|
end
|
|
85
99
|
|
|
86
100
|
abstract!
|
|
@@ -92,12 +106,12 @@ module AbstractController
|
|
|
92
106
|
# ActionNotFound error is raised.
|
|
93
107
|
#
|
|
94
108
|
# ==== Returns
|
|
95
|
-
# self
|
|
109
|
+
# * <tt>self</tt>
|
|
96
110
|
def process(action, *args)
|
|
97
111
|
@_action_name = action_name = action.to_s
|
|
98
112
|
|
|
99
113
|
unless action_name = method_for_action(action_name)
|
|
100
|
-
raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
|
|
114
|
+
raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
|
|
101
115
|
end
|
|
102
116
|
|
|
103
117
|
@_response_body = nil
|
|
@@ -121,10 +135,10 @@ module AbstractController
|
|
|
121
135
|
# can be considered an action.
|
|
122
136
|
#
|
|
123
137
|
# ==== Parameters
|
|
124
|
-
# name
|
|
138
|
+
# * <tt>name</tt> - The name of an action to be tested
|
|
125
139
|
#
|
|
126
140
|
# ==== Returns
|
|
127
|
-
# TrueClass
|
|
141
|
+
# * <tt>TrueClass</tt>, <tt>FalseClass</tt>
|
|
128
142
|
def action_method?(name)
|
|
129
143
|
self.class.action_methods.include?(name)
|
|
130
144
|
end
|
|
@@ -168,11 +182,11 @@ module AbstractController
|
|
|
168
182
|
# returns nil, an ActionNotFound exception will be raised.
|
|
169
183
|
#
|
|
170
184
|
# ==== Parameters
|
|
171
|
-
# action_name
|
|
185
|
+
# * <tt>action_name</tt> - An action name to find a method name for
|
|
172
186
|
#
|
|
173
187
|
# ==== Returns
|
|
174
|
-
#
|
|
175
|
-
# nil
|
|
188
|
+
# * <tt>string</tt> - The name of the method that handles the action
|
|
189
|
+
# * <tt>nil</tt> - No method name could be found. Raise ActionNotFound.
|
|
176
190
|
def method_for_action(action_name)
|
|
177
191
|
if action_method?(action_name) then action_name
|
|
178
192
|
elsif respond_to?(:action_missing, true) then "_handle_action_missing"
|
|
@@ -28,9 +28,8 @@ module AbstractController
|
|
|
28
28
|
# a Rails process.
|
|
29
29
|
#
|
|
30
30
|
# ==== Options
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
# except this action
|
|
31
|
+
# * <tt>only</tt> - The callback should be run only for this action
|
|
32
|
+
# * <tt>except<tt> - The callback should be run for all actions except this action
|
|
34
33
|
def _normalize_callback_options(options)
|
|
35
34
|
if only = options[:only]
|
|
36
35
|
only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ")
|
|
@@ -45,7 +44,7 @@ module AbstractController
|
|
|
45
44
|
# Skip before, after, and around filters matching any of the names
|
|
46
45
|
#
|
|
47
46
|
# ==== Parameters
|
|
48
|
-
# *names
|
|
47
|
+
# * <tt>names</tt> - A list of valid names that could be used for
|
|
49
48
|
# callbacks. Note that skipping uses Ruby equality, so it's
|
|
50
49
|
# impossible to skip a callback defined using an anonymous proc
|
|
51
50
|
# using #skip_filter
|
|
@@ -60,13 +59,13 @@ module AbstractController
|
|
|
60
59
|
# the normalization across several methods that use it.
|
|
61
60
|
#
|
|
62
61
|
# ==== Parameters
|
|
63
|
-
#
|
|
62
|
+
# * <tt>callbacks</tt> - An array of callbacks, with an optional
|
|
64
63
|
# options hash as the last parameter.
|
|
65
|
-
# block
|
|
64
|
+
# * <tt>block</tt> - A proc that should be added to the callbacks.
|
|
66
65
|
#
|
|
67
66
|
# ==== Block Parameters
|
|
68
|
-
# name
|
|
69
|
-
# options
|
|
67
|
+
# * <tt>name</tt> - The callback to be added
|
|
68
|
+
# * <tt>options</tt> - A hash of options to be used when adding the callback
|
|
70
69
|
def _insert_callbacks(callbacks, block)
|
|
71
70
|
options = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
|
|
72
71
|
_normalize_callback_options(options)
|
|
@@ -82,27 +81,27 @@ module AbstractController
|
|
|
82
81
|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
|
83
82
|
# Append a before, after or around filter. See _insert_callbacks
|
|
84
83
|
# for details on the allowed parameters.
|
|
85
|
-
def #{filter}_filter(*names, &blk)
|
|
86
|
-
_insert_callbacks(names, blk) do |name, options|
|
|
87
|
-
set_callback(:process_action, :#{filter}, name, options)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
84
|
+
def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
|
|
85
|
+
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options}
|
|
86
|
+
set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before_filter, name, options)
|
|
87
|
+
end # end
|
|
88
|
+
end # end
|
|
90
89
|
|
|
91
90
|
# Prepend a before, after or around filter. See _insert_callbacks
|
|
92
91
|
# for details on the allowed parameters.
|
|
93
|
-
def prepend_#{filter}_filter(*names, &blk)
|
|
94
|
-
_insert_callbacks(names, blk) do |name, options|
|
|
95
|
-
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true))
|
|
96
|
-
end
|
|
97
|
-
end
|
|
92
|
+
def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
|
|
93
|
+
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
|
94
|
+
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
|
|
95
|
+
end # end
|
|
96
|
+
end # end
|
|
98
97
|
|
|
99
98
|
# Skip a before, after or around filter. See _insert_callbacks
|
|
100
99
|
# for details on the allowed parameters.
|
|
101
|
-
def skip_#{filter}_filter(*names, &blk)
|
|
102
|
-
_insert_callbacks(names, blk) do |name, options|
|
|
103
|
-
skip_callback(:process_action, :#{filter}, name, options)
|
|
104
|
-
end
|
|
105
|
-
end
|
|
100
|
+
def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
|
|
101
|
+
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
|
|
102
|
+
skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
|
|
103
|
+
end # end
|
|
104
|
+
end # end
|
|
106
105
|
|
|
107
106
|
# *_filter is the same as append_*_filter
|
|
108
107
|
alias_method :append_#{filter}_filter, :#{filter}_filter
|
|
@@ -9,6 +9,9 @@ module AbstractController
|
|
|
9
9
|
included do
|
|
10
10
|
class_attribute :_helpers
|
|
11
11
|
self._helpers = Module.new
|
|
12
|
+
|
|
13
|
+
class_attribute :_helper_methods
|
|
14
|
+
self._helper_methods = Array.new
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
module ClassMethods
|
|
@@ -40,10 +43,13 @@ module AbstractController
|
|
|
40
43
|
# <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
|
|
41
44
|
#
|
|
42
45
|
# ==== Parameters
|
|
43
|
-
#
|
|
46
|
+
# * <tt>method[, method]</tt> - A name or names of a method on the controller
|
|
44
47
|
# to be made available on the view.
|
|
45
48
|
def helper_method(*meths)
|
|
46
|
-
meths.flatten
|
|
49
|
+
meths.flatten!
|
|
50
|
+
self._helper_methods += meths
|
|
51
|
+
|
|
52
|
+
meths.each do |meth|
|
|
47
53
|
_helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
|
|
48
54
|
def #{meth}(*args, &blk)
|
|
49
55
|
controller.send(%(#{meth}), *args, &blk)
|
|
@@ -55,8 +61,8 @@ module AbstractController
|
|
|
55
61
|
# The +helper+ class method can take a series of helper module names, a block, or both.
|
|
56
62
|
#
|
|
57
63
|
# ==== Parameters
|
|
58
|
-
# *args
|
|
59
|
-
# block
|
|
64
|
+
# * <tt>*args</tt> - Module, Symbol, String, :all
|
|
65
|
+
# * <tt>block</tt> - A block defining helper methods
|
|
60
66
|
#
|
|
61
67
|
# ==== Examples
|
|
62
68
|
# When the argument is a module it will be included directly in the template class.
|
|
@@ -95,12 +101,23 @@ module AbstractController
|
|
|
95
101
|
_helpers.module_eval(&block) if block_given?
|
|
96
102
|
end
|
|
97
103
|
|
|
104
|
+
# Clears up all existing helpers in this class, only keeping the helper
|
|
105
|
+
# with the same name as this class.
|
|
106
|
+
def clear_helpers
|
|
107
|
+
inherited_helper_methods = _helper_methods
|
|
108
|
+
self._helpers = Module.new
|
|
109
|
+
self._helper_methods = Array.new
|
|
110
|
+
|
|
111
|
+
inherited_helper_methods.each { |meth| helper_method meth }
|
|
112
|
+
default_helper_module! unless anonymous?
|
|
113
|
+
end
|
|
114
|
+
|
|
98
115
|
private
|
|
99
116
|
# Makes all the (instance) methods in the helper module available to templates
|
|
100
117
|
# rendered through this controller.
|
|
101
118
|
#
|
|
102
119
|
# ==== Parameters
|
|
103
|
-
#
|
|
120
|
+
# * <tt>module</tt> - The module to include into the current helper module
|
|
104
121
|
# for the class
|
|
105
122
|
def add_template_helper(mod)
|
|
106
123
|
_helpers.module_eval { include mod }
|
|
@@ -118,10 +135,10 @@ module AbstractController
|
|
|
118
135
|
# are returned.
|
|
119
136
|
#
|
|
120
137
|
# ==== Parameters
|
|
121
|
-
# args
|
|
138
|
+
# * <tt>args</tt> - An array of helpers
|
|
122
139
|
#
|
|
123
140
|
# ==== Returns
|
|
124
|
-
# Array
|
|
141
|
+
# * <tt>Array</tt> - A normalized list of modules for the list of
|
|
125
142
|
# helpers provided.
|
|
126
143
|
def modules_for_helpers(args)
|
|
127
144
|
args.flatten.map! do |arg|
|
|
@@ -114,11 +114,13 @@ module AbstractController
|
|
|
114
114
|
#
|
|
115
115
|
# class WeblogController < ActionController::Base
|
|
116
116
|
# layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
|
|
117
|
+
# end
|
|
117
118
|
#
|
|
118
119
|
# Of course, the most common way of specifying a layout is still just as a plain template name:
|
|
119
120
|
#
|
|
120
121
|
# class WeblogController < ActionController::Base
|
|
121
122
|
# layout "weblog_standard"
|
|
123
|
+
# end
|
|
122
124
|
#
|
|
123
125
|
# If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
|
|
124
126
|
# Otherwise, it will be looked up relative to the template root.
|
|
@@ -183,7 +185,7 @@ module AbstractController
|
|
|
183
185
|
# layout.
|
|
184
186
|
#
|
|
185
187
|
# ==== Returns
|
|
186
|
-
# Boolean
|
|
188
|
+
# * <tt> Boolean</tt> - True if the action has a layout, false otherwise.
|
|
187
189
|
def action_has_layout?
|
|
188
190
|
return unless super
|
|
189
191
|
|
|
@@ -209,11 +211,11 @@ module AbstractController
|
|
|
209
211
|
# true:: raise an ArgumentError
|
|
210
212
|
#
|
|
211
213
|
# ==== Parameters
|
|
212
|
-
#
|
|
214
|
+
# * <tt>String, Symbol, false</tt> - The layout to use.
|
|
213
215
|
#
|
|
214
216
|
# ==== Options (conditions)
|
|
215
|
-
# :only
|
|
216
|
-
# :except
|
|
217
|
+
# * :only - A list of actions to apply this layout to.
|
|
218
|
+
# * :except - Apply this layout to all actions but this one.
|
|
217
219
|
def layout(layout, conditions = {})
|
|
218
220
|
include LayoutConditions unless conditions.empty?
|
|
219
221
|
|
|
@@ -228,7 +230,7 @@ module AbstractController
|
|
|
228
230
|
# value of this method.
|
|
229
231
|
#
|
|
230
232
|
# ==== Returns
|
|
231
|
-
# String
|
|
233
|
+
# * <tt>String</tt> - A template name
|
|
232
234
|
def _implied_layout_name
|
|
233
235
|
controller_path
|
|
234
236
|
end
|
|
@@ -313,8 +315,8 @@ module AbstractController
|
|
|
313
315
|
# the name type.
|
|
314
316
|
#
|
|
315
317
|
# ==== Parameters
|
|
316
|
-
# name
|
|
317
|
-
# details
|
|
318
|
+
# * <tt>name</tt> - The name of the template
|
|
319
|
+
# * <tt>details</tt> - A list of details to restrict
|
|
318
320
|
# the lookup to. By default, layout lookup is limited to the
|
|
319
321
|
# formats specified for the current request.
|
|
320
322
|
def _layout_for_option(name)
|
|
@@ -333,14 +335,14 @@ module AbstractController
|
|
|
333
335
|
# Optionally raises an exception if the layout could not be found.
|
|
334
336
|
#
|
|
335
337
|
# ==== Parameters
|
|
336
|
-
# details
|
|
338
|
+
# * <tt>details</tt> - A list of details to restrict the search by. This
|
|
337
339
|
# might include details like the format or locale of the template.
|
|
338
|
-
#
|
|
340
|
+
# * <tt>require_logout</tt> - If this is true, raise an ArgumentError
|
|
339
341
|
# with details about the fact that the exception could not be
|
|
340
342
|
# found (defaults to false)
|
|
341
343
|
#
|
|
342
344
|
# ==== Returns
|
|
343
|
-
#
|
|
345
|
+
# * <tt>template</tt> - The template object for the default layout (or nil)
|
|
344
346
|
def _default_layout(require_layout = false)
|
|
345
347
|
begin
|
|
346
348
|
layout_name = _layout if action_has_layout?
|
|
@@ -34,9 +34,9 @@ module AbstractController
|
|
|
34
34
|
# Append a path to the list of view paths for this controller.
|
|
35
35
|
#
|
|
36
36
|
# ==== Parameters
|
|
37
|
-
# path
|
|
38
|
-
#
|
|
39
|
-
#
|
|
37
|
+
# * <tt>path</tt> - If a String is provided, it gets converted into
|
|
38
|
+
# the default view path. You may also provide a custom view path
|
|
39
|
+
# (see ActionView::ViewPathSet for more information)
|
|
40
40
|
def append_view_path(path)
|
|
41
41
|
self.view_paths = view_paths.dup + Array(path)
|
|
42
42
|
end
|
|
@@ -44,9 +44,9 @@ module AbstractController
|
|
|
44
44
|
# Prepend a path to the list of view paths for this controller.
|
|
45
45
|
#
|
|
46
46
|
# ==== Parameters
|
|
47
|
-
# path
|
|
48
|
-
#
|
|
49
|
-
#
|
|
47
|
+
# * <tt>path</tt> - If a String is provided, it gets converted into
|
|
48
|
+
# the default view path. You may also provide a custom view path
|
|
49
|
+
# (see ActionView::ViewPathSet for more information)
|
|
50
50
|
def prepend_view_path(path)
|
|
51
51
|
self.view_paths = Array(path) + view_paths.dup
|
|
52
52
|
end
|
|
@@ -59,7 +59,7 @@ module AbstractController
|
|
|
59
59
|
# Set the view paths.
|
|
60
60
|
#
|
|
61
61
|
# ==== Parameters
|
|
62
|
-
# paths
|
|
62
|
+
# * <tt>paths</tt> - If a ViewPathSet is provided, use that;
|
|
63
63
|
# otherwise, process the parameter into a ViewPathSet.
|
|
64
64
|
def view_paths=(paths)
|
|
65
65
|
self._view_paths = ActionView::Base.process_view_paths(paths)
|
data/lib/abstract_controller.rb
CHANGED
|
@@ -2,6 +2,7 @@ activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
|
|
|
2
2
|
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
|
|
3
3
|
|
|
4
4
|
require 'action_pack'
|
|
5
|
+
require 'active_support/concern'
|
|
5
6
|
require 'active_support/ruby/shim'
|
|
6
7
|
require 'active_support/dependencies/autoload'
|
|
7
8
|
require 'active_support/core_ext/class/attribute'
|
|
@@ -1,6 +1,169 @@
|
|
|
1
1
|
require "action_controller/log_subscriber"
|
|
2
2
|
|
|
3
3
|
module ActionController
|
|
4
|
+
# Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
|
|
5
|
+
# on request and then either render a template or redirect to another action. An action is defined as a public method
|
|
6
|
+
# on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
|
|
7
|
+
#
|
|
8
|
+
# By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other
|
|
9
|
+
# controllers in turn inherit from ApplicationController. This gives you one class to configure things such as
|
|
10
|
+
# request forgery protection and filtering of sensitive request parameters.
|
|
11
|
+
#
|
|
12
|
+
# A sample controller could look like this:
|
|
13
|
+
#
|
|
14
|
+
# class PostsController < ApplicationController
|
|
15
|
+
# def index
|
|
16
|
+
# @posts = Post.all
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# def create
|
|
20
|
+
# @post = Post.create params[:post]
|
|
21
|
+
# redirect_to posts_path
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# Actions, by default, render a template in the <tt>app/views</tt> directory corresponding to the name of the controller and action
|
|
26
|
+
# after executing code in the action. For example, the +index+ action of the PostsController would render the
|
|
27
|
+
# template <tt>app/views/posts/index.erb</tt> by default after populating the <tt>@posts</tt> instance variable.
|
|
28
|
+
#
|
|
29
|
+
# Unlike index, the create action will not render a template. After performing its main purpose (creating a
|
|
30
|
+
# new post), it initiates a redirect instead. This redirect works by returning an external
|
|
31
|
+
# "302 Moved" HTTP response that takes the user to the index action.
|
|
32
|
+
#
|
|
33
|
+
# These two methods represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect.
|
|
34
|
+
# Most actions are variations of these themes.
|
|
35
|
+
#
|
|
36
|
+
# == Requests
|
|
37
|
+
#
|
|
38
|
+
# For every request, the router determines the value of the +controller+ and +action+ keys. These determine which controller
|
|
39
|
+
# and action are called. The remaining request parameters, the session (if one is available), and the full request with
|
|
40
|
+
# all the HTTP headers are made available to the action through accessor methods. Then the action is performed.
|
|
41
|
+
#
|
|
42
|
+
# The full request object is available via the request accessor and is primarily used to query for HTTP headers:
|
|
43
|
+
#
|
|
44
|
+
# def server_ip
|
|
45
|
+
# location = request.env["SERVER_ADDR"]
|
|
46
|
+
# render :text => "This server hosted at #{location}"
|
|
47
|
+
# end
|
|
48
|
+
#
|
|
49
|
+
# == Parameters
|
|
50
|
+
#
|
|
51
|
+
# All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method
|
|
52
|
+
# which returns a hash. For example, an action that was performed through <tt>/posts?category=All&limit=5</tt> will include
|
|
53
|
+
# <tt>{ "category" => "All", "limit" => 5 }</tt> in params.
|
|
54
|
+
#
|
|
55
|
+
# It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
|
|
56
|
+
#
|
|
57
|
+
# <input type="text" name="post[name]" value="david">
|
|
58
|
+
# <input type="text" name="post[address]" value="hyacintvej">
|
|
59
|
+
#
|
|
60
|
+
# A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
|
|
61
|
+
# If the address input had been named "post[address][street]", the params would have included
|
|
62
|
+
# <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
|
|
63
|
+
#
|
|
64
|
+
# == Sessions
|
|
65
|
+
#
|
|
66
|
+
# Sessions allows you to store objects in between requests. This is useful for objects that are not yet ready to be persisted,
|
|
67
|
+
# such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such
|
|
68
|
+
# as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely
|
|
69
|
+
# they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at.
|
|
70
|
+
#
|
|
71
|
+
# You can place objects in the session by using the <tt>session</tt> method, which accesses a hash:
|
|
72
|
+
#
|
|
73
|
+
# session[:person] = Person.authenticate(user_name, password)
|
|
74
|
+
#
|
|
75
|
+
# And retrieved again through the same hash:
|
|
76
|
+
#
|
|
77
|
+
# Hello #{session[:person]}
|
|
78
|
+
#
|
|
79
|
+
# For removing objects from the session, you can either assign a single key to +nil+:
|
|
80
|
+
#
|
|
81
|
+
# # removes :person from session
|
|
82
|
+
# session[:person] = nil
|
|
83
|
+
#
|
|
84
|
+
# or you can remove the entire session with +reset_session+.
|
|
85
|
+
#
|
|
86
|
+
# Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted.
|
|
87
|
+
# This prevents the user from tampering with the session but also allows him to see its contents.
|
|
88
|
+
#
|
|
89
|
+
# Do not put secret information in cookie-based sessions!
|
|
90
|
+
#
|
|
91
|
+
# Other options for session storage:
|
|
92
|
+
#
|
|
93
|
+
# * ActiveRecord::SessionStore - Sessions are stored in your database, which works better than PStore with multiple app servers and,
|
|
94
|
+
# unlike CookieStore, hides your session contents from the user. To use ActiveRecord::SessionStore, set
|
|
95
|
+
#
|
|
96
|
+
# config.action_controller.session_store = :active_record_store
|
|
97
|
+
#
|
|
98
|
+
# in your <tt>config/environment.rb</tt> and run <tt>rake db:sessions:create</tt>.
|
|
99
|
+
#
|
|
100
|
+
# == Responses
|
|
101
|
+
#
|
|
102
|
+
# Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
|
|
103
|
+
# object is generated automatically through the use of renders and redirects and requires no user intervention.
|
|
104
|
+
#
|
|
105
|
+
# == Renders
|
|
106
|
+
#
|
|
107
|
+
# Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering
|
|
108
|
+
# of a template. Included in the Action Pack is the Action View, which enables rendering of ERb templates. It's automatically configured.
|
|
109
|
+
# The controller passes objects to the view by assigning instance variables:
|
|
110
|
+
#
|
|
111
|
+
# def show
|
|
112
|
+
# @post = Post.find(params[:id])
|
|
113
|
+
# end
|
|
114
|
+
#
|
|
115
|
+
# Which are then automatically available to the view:
|
|
116
|
+
#
|
|
117
|
+
# Title: <%= @post.title %>
|
|
118
|
+
#
|
|
119
|
+
# You don't have to rely on the automated rendering. Especially actions that could result in the rendering of different templates will use
|
|
120
|
+
# the manual rendering methods:
|
|
121
|
+
#
|
|
122
|
+
# def search
|
|
123
|
+
# @results = Search.find(params[:query])
|
|
124
|
+
# case @results
|
|
125
|
+
# when 0 then render :action => "no_results"
|
|
126
|
+
# when 1 then render :action => "show"
|
|
127
|
+
# when 2..10 then render :action => "show_many"
|
|
128
|
+
# end
|
|
129
|
+
# end
|
|
130
|
+
#
|
|
131
|
+
# Read more about writing ERb and Builder templates in ActionView::Base.
|
|
132
|
+
#
|
|
133
|
+
# == Redirects
|
|
134
|
+
#
|
|
135
|
+
# Redirects are used to move from one action to another. For example, after a <tt>create</tt> action, which stores a blog entry to a database,
|
|
136
|
+
# we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're going to reuse (and redirect to)
|
|
137
|
+
# a <tt>show</tt> action that we'll assume has already been created. The code might look like this:
|
|
138
|
+
#
|
|
139
|
+
# def create
|
|
140
|
+
# @entry = Entry.new(params[:entry])
|
|
141
|
+
# if @entry.save
|
|
142
|
+
# # The entry was saved correctly, redirect to show
|
|
143
|
+
# redirect_to :action => 'show', :id => @entry.id
|
|
144
|
+
# else
|
|
145
|
+
# # things didn't go so well, do something else
|
|
146
|
+
# end
|
|
147
|
+
# end
|
|
148
|
+
#
|
|
149
|
+
# In this case, after saving our new entry to the database, the user is redirected to the <tt>show</tt> method which is then executed.
|
|
150
|
+
#
|
|
151
|
+
# == Calling multiple redirects or renders
|
|
152
|
+
#
|
|
153
|
+
# An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
|
|
154
|
+
#
|
|
155
|
+
# def do_something
|
|
156
|
+
# redirect_to :action => "elsewhere"
|
|
157
|
+
# render :action => "overthere" # raises DoubleRenderError
|
|
158
|
+
# end
|
|
159
|
+
#
|
|
160
|
+
# If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.
|
|
161
|
+
#
|
|
162
|
+
# def do_something
|
|
163
|
+
# redirect_to(:action => "elsewhere") and return if monkeys.nil?
|
|
164
|
+
# render :action => "overthere" # won't be called if monkeys is nil
|
|
165
|
+
# end
|
|
166
|
+
#
|
|
4
167
|
class Base < Metal
|
|
5
168
|
abstract!
|
|
6
169
|
|
|
@@ -60,11 +223,11 @@ module ActionController
|
|
|
60
223
|
|
|
61
224
|
def self.inherited(klass)
|
|
62
225
|
super
|
|
63
|
-
klass.helper :all
|
|
226
|
+
klass.helper :all if klass.superclass == ActionController::Base
|
|
64
227
|
end
|
|
65
228
|
|
|
229
|
+
require "action_controller/deprecated/base"
|
|
66
230
|
ActiveSupport.run_load_hooks(:action_controller, self)
|
|
67
231
|
end
|
|
68
232
|
end
|
|
69
233
|
|
|
70
|
-
require "action_controller/deprecated/base"
|