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
@@ -71,6 +71,7 @@ module ActionController
|
|
71
71
|
:order => nil,
|
72
72
|
:join => nil,
|
73
73
|
:joins => nil,
|
74
|
+
:count => nil,
|
74
75
|
:include => nil,
|
75
76
|
:select => nil,
|
76
77
|
:parameter => 'page'
|
@@ -119,6 +120,10 @@ module ActionController
|
|
119
120
|
# and Model.count
|
120
121
|
# <tt>:include</tt>:: optional eager loading parameter passed to Model.find(:all, *params)
|
121
122
|
# and Model.count
|
123
|
+
# <tt>:select</tt>:: :select parameter passed to Model.find(:all, *params)
|
124
|
+
#
|
125
|
+
# <tt>:count</tt>:: parameter passed as :select option to Model.count(*params)
|
126
|
+
#
|
122
127
|
def paginate(collection_id, options={})
|
123
128
|
Pagination.validate_options!(collection_id, options, true)
|
124
129
|
paginator_and_collection_for(collection_id, options)
|
@@ -163,10 +168,13 @@ module ActionController
|
|
163
168
|
# Returns the total number of items in the collection to be paginated for
|
164
169
|
# the +model+ and given +conditions+. Override this method to implement a
|
165
170
|
# custom counter.
|
166
|
-
def count_collection_for_pagination(model,
|
167
|
-
model.count(conditions,
|
171
|
+
def count_collection_for_pagination(model, options)
|
172
|
+
model.count(:conditions => options[:conditions],
|
173
|
+
:joins => options[:join] || options[:joins],
|
174
|
+
:include => options[:include],
|
175
|
+
:select => options[:count])
|
168
176
|
end
|
169
|
-
|
177
|
+
|
170
178
|
# Returns a collection of items for the given +model+ and +options[conditions]+,
|
171
179
|
# ordered by +options[order]+, for the current page in the given +paginator+.
|
172
180
|
# Override this method to implement a custom finder.
|
@@ -185,12 +193,10 @@ module ActionController
|
|
185
193
|
def paginator_and_collection_for(collection_id, options) #:nodoc:
|
186
194
|
klass = options[:class_name].constantize
|
187
195
|
page = @params[options[:parameter]]
|
188
|
-
count = count_collection_for_pagination(klass, options
|
189
|
-
options[:join] || options[:joins])
|
190
|
-
|
196
|
+
count = count_collection_for_pagination(klass, options)
|
191
197
|
paginator = Paginator.new(self, count, options[:per_page], page)
|
192
198
|
collection = find_collection_for_pagination(klass, options, paginator)
|
193
|
-
|
199
|
+
|
194
200
|
return paginator, collection
|
195
201
|
end
|
196
202
|
|
@@ -3,14 +3,18 @@ module ActionController
|
|
3
3
|
class AbstractRequest
|
4
4
|
cattr_accessor :relative_url_root
|
5
5
|
|
6
|
+
# Returns the hash of environment variables for this request,
|
7
|
+
# such as { 'RAILS_ENV' => 'production' }.
|
8
|
+
attr_reader :env
|
9
|
+
|
6
10
|
# Returns both GET and POST parameters in a single hash.
|
7
11
|
def parameters
|
8
|
-
@parameters ||= request_parameters.
|
12
|
+
@parameters ||= request_parameters.update(query_parameters).update(path_parameters).with_indifferent_access
|
9
13
|
end
|
10
14
|
|
11
15
|
# Returns the HTTP request method as a lowercase symbol (:get, for example)
|
12
16
|
def method
|
13
|
-
env['REQUEST_METHOD'].downcase.to_sym
|
17
|
+
@request_method ||= @env['REQUEST_METHOD'].downcase.to_sym
|
14
18
|
end
|
15
19
|
|
16
20
|
# Is this a GET request? Equivalent to request.method == :get
|
@@ -38,51 +42,43 @@ module ActionController
|
|
38
42
|
method == :head
|
39
43
|
end
|
40
44
|
|
41
|
-
# Determine whether the body of a
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# Content-Type Post Format
|
45
|
-
# application/xml :xml
|
46
|
-
# text/xml :xml
|
47
|
-
# application/x-yaml :yaml
|
48
|
-
# text/x-yaml :yaml
|
49
|
-
# * :url_encoded
|
45
|
+
# Determine whether the body of a HTTP call is URL-encoded (default)
|
46
|
+
# or matches one of the registered param_parsers.
|
50
47
|
#
|
51
48
|
# For backward compatibility, the post format is extracted from the
|
52
49
|
# X-Post-Data-Format HTTP header if present.
|
53
|
-
def
|
54
|
-
@
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
# Is this a POST request formatted as XML?
|
72
|
-
def xml_post?
|
73
|
-
post? && post_format == :xml
|
50
|
+
def content_type
|
51
|
+
@content_type ||=
|
52
|
+
begin
|
53
|
+
content_type = @env['CONTENT_TYPE'].to_s.downcase
|
54
|
+
|
55
|
+
if x_post_format = @env['HTTP_X_POST_DATA_FORMAT']
|
56
|
+
case x_post_format.to_s.downcase
|
57
|
+
when 'yaml'
|
58
|
+
content_type = 'application/x-yaml'
|
59
|
+
when 'xml'
|
60
|
+
content_type = 'application/xml'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
Mime::Type.lookup(content_type)
|
65
|
+
end
|
74
66
|
end
|
75
67
|
|
76
|
-
|
77
|
-
|
78
|
-
|
68
|
+
def accepts
|
69
|
+
@accepts ||=
|
70
|
+
if @env['HTTP_ACCEPT'].to_s.strip.empty?
|
71
|
+
[ content_type, Mime::ALL ]
|
72
|
+
else
|
73
|
+
Mime::Type.parse(@env['HTTP_ACCEPT'])
|
74
|
+
end
|
79
75
|
end
|
80
76
|
|
81
77
|
# Returns true if the request's "X-Requested-With" header contains
|
82
78
|
# "XMLHttpRequest". (The Prototype Javascript library sends this header with
|
83
79
|
# every Ajax request.)
|
84
80
|
def xml_http_request?
|
85
|
-
not /XMLHttpRequest/i.match(env['HTTP_X_REQUESTED_WITH']).nil?
|
81
|
+
not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil?
|
86
82
|
end
|
87
83
|
alias xhr? :xml_http_request?
|
88
84
|
|
@@ -93,17 +89,17 @@ module ActionController
|
|
93
89
|
# delimited list in the case of multiple chained proxies; the first is
|
94
90
|
# the originating IP.
|
95
91
|
def remote_ip
|
96
|
-
return env['HTTP_CLIENT_IP'] if env.include? 'HTTP_CLIENT_IP'
|
92
|
+
return @env['HTTP_CLIENT_IP'] if @env.include? 'HTTP_CLIENT_IP'
|
97
93
|
|
98
|
-
if env.include? 'HTTP_X_FORWARDED_FOR' then
|
99
|
-
remote_ips = env['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip|
|
94
|
+
if @env.include? 'HTTP_X_FORWARDED_FOR' then
|
95
|
+
remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip|
|
100
96
|
ip =~ /^unknown$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i
|
101
97
|
end
|
102
98
|
|
103
99
|
return remote_ips.first.strip unless remote_ips.empty?
|
104
100
|
end
|
105
101
|
|
106
|
-
env['REMOTE_ADDR']
|
102
|
+
@env['REMOTE_ADDR']
|
107
103
|
end
|
108
104
|
|
109
105
|
# Returns the domain part of a host, such as rubyonrails.org in "www.rubyonrails.org". You can specify
|
@@ -127,19 +123,19 @@ module ActionController
|
|
127
123
|
# This is useful for services such as REST, XMLRPC and SOAP
|
128
124
|
# which communicate over HTTP POST but don't use the traditional parameter format.
|
129
125
|
def raw_post
|
130
|
-
env['RAW_POST_DATA']
|
126
|
+
@env['RAW_POST_DATA']
|
131
127
|
end
|
132
128
|
|
133
129
|
# Returns the request URI correctly, taking into account the idiosyncracies
|
134
130
|
# of the various servers.
|
135
131
|
def request_uri
|
136
|
-
if uri = env['REQUEST_URI']
|
132
|
+
if uri = @env['REQUEST_URI']
|
137
133
|
(%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri # Remove domain, which webrick puts into the request_uri.
|
138
134
|
else # REQUEST_URI is blank under IIS - get this from PATH_INFO and SCRIPT_NAME
|
139
|
-
script_filename = env['SCRIPT_NAME'].to_s.match(%r{[^/]+$})
|
140
|
-
uri = env['PATH_INFO']
|
135
|
+
script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$})
|
136
|
+
uri = @env['PATH_INFO']
|
141
137
|
uri = uri.sub(/#{script_filename}\//, '') unless script_filename.nil?
|
142
|
-
unless (env_qs = env['QUERY_STRING']).nil? || env_qs.empty?
|
138
|
+
unless (env_qs = @env['QUERY_STRING']).nil? || env_qs.empty?
|
143
139
|
uri << '?' << env_qs
|
144
140
|
end
|
145
141
|
uri
|
@@ -153,7 +149,7 @@ module ActionController
|
|
153
149
|
|
154
150
|
# Is this an SSL request?
|
155
151
|
def ssl?
|
156
|
-
env['HTTPS'] == 'on'
|
152
|
+
@env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
|
157
153
|
end
|
158
154
|
|
159
155
|
# Returns the interpreted path to requested resource after all the installation directory of this application was taken into account
|
@@ -167,15 +163,23 @@ module ActionController
|
|
167
163
|
end
|
168
164
|
|
169
165
|
# Returns the path minus the web server relative installation directory.
|
170
|
-
# This
|
166
|
+
# This can be set with the environment variable RAILS_RELATIVE_URL_ROOT.
|
167
|
+
# It can be automatically extracted for Apache setups. If the server is not
|
168
|
+
# Apache, this method returns an empty string.
|
171
169
|
def relative_url_root
|
172
|
-
@@relative_url_root ||=
|
173
|
-
|
170
|
+
@@relative_url_root ||= case
|
171
|
+
when @env["RAILS_RELATIVE_URL_ROOT"]
|
172
|
+
@env["RAILS_RELATIVE_URL_ROOT"]
|
173
|
+
when server_software == 'apache'
|
174
|
+
@env["SCRIPT_NAME"].to_s.sub(/\/dispatch\.(fcgi|rb|cgi)$/, '')
|
175
|
+
else
|
176
|
+
''
|
177
|
+
end
|
174
178
|
end
|
175
179
|
|
176
180
|
# Returns the port number of this request as an integer.
|
177
181
|
def port
|
178
|
-
@port_as_int ||= env['SERVER_PORT'].to_i
|
182
|
+
@port_as_int ||= @env['SERVER_PORT'].to_i
|
179
183
|
end
|
180
184
|
|
181
185
|
# Returns the standard port number for this request's protocol
|
@@ -213,7 +217,7 @@ module ActionController
|
|
213
217
|
|
214
218
|
# Returns the lowercase name of the HTTP server software.
|
215
219
|
def server_software
|
216
|
-
(env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ env['SERVER_SOFTWARE']) ? $1.downcase : nil
|
220
|
+
(@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil
|
217
221
|
end
|
218
222
|
|
219
223
|
#--
|
@@ -225,11 +229,6 @@ module ActionController
|
|
225
229
|
def request_parameters #:nodoc:
|
226
230
|
end
|
227
231
|
|
228
|
-
# Returns the hash of environment variables for this request,
|
229
|
-
# such as { 'RAILS_ENV' => 'production' }.
|
230
|
-
def env
|
231
|
-
end
|
232
|
-
|
233
232
|
# Returns the host for this request, such as example.com.
|
234
233
|
def host
|
235
234
|
end
|
@@ -240,6 +239,10 @@ module ActionController
|
|
240
239
|
def session #:nodoc:
|
241
240
|
end
|
242
241
|
|
242
|
+
def session=(session) #:nodoc:
|
243
|
+
@session = session
|
244
|
+
end
|
245
|
+
|
243
246
|
def reset_session #:nodoc:
|
244
247
|
end
|
245
248
|
end
|
@@ -60,7 +60,7 @@ module ActionController #:nodoc:
|
|
60
60
|
# the remote IP being 127.0.0.1. For example, this could include the IP of the developer machine when debugging
|
61
61
|
# remotely.
|
62
62
|
def local_request? #:doc:
|
63
|
-
@request.remote_addr == "127.0.0.1"
|
63
|
+
[@request.remote_addr, @request.remote_ip] == ["127.0.0.1"] * 2
|
64
64
|
end
|
65
65
|
|
66
66
|
# Renders a detailed diagnostics screen on action exceptions.
|
@@ -100,6 +100,7 @@ module ActionController
|
|
100
100
|
|
101
101
|
def initialize(key, options = {})
|
102
102
|
@key = key.to_sym
|
103
|
+
@optional = false
|
103
104
|
default, @condition = options[:default], options[:condition]
|
104
105
|
self.default = default if options.key?(:default)
|
105
106
|
end
|
@@ -214,26 +215,45 @@ module ActionController
|
|
214
215
|
|
215
216
|
class << self
|
216
217
|
def assign_controller(g, controller)
|
217
|
-
expr = "
|
218
|
+
expr = "::#{controller.split('/').collect {|c| c.camelize}.join('::')}Controller"
|
218
219
|
g.result :controller, expr, true
|
219
220
|
end
|
220
221
|
|
221
222
|
def traverse_to_controller(segments, start_at = 0)
|
222
|
-
mod = ::
|
223
|
+
mod = ::Object
|
223
224
|
length = segments.length
|
224
225
|
index = start_at
|
225
226
|
mod_name = controller_name = segment = nil
|
226
|
-
|
227
|
+
|
227
228
|
while index < length
|
228
229
|
return nil unless /^[A-Za-z][A-Za-z\d_]*$/ =~ (segment = segments[index])
|
229
230
|
index += 1
|
230
|
-
|
231
|
+
|
231
232
|
mod_name = segment.camelize
|
232
233
|
controller_name = "#{mod_name}Controller"
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
234
|
+
|
235
|
+
begin
|
236
|
+
# We use eval instead of const_get to avoid obtaining values from parent modules.
|
237
|
+
controller = eval("mod::#{controller_name}", nil, __FILE__, __LINE__)
|
238
|
+
expected_name = "#{mod.name}::#{controller_name}"
|
239
|
+
|
240
|
+
# Detect the case when const_get returns an object from a parent namespace.
|
241
|
+
if controller.is_a?(Class) && controller.ancestors.include?(ActionController::Base) && (mod == Object || controller.name == expected_name)
|
242
|
+
return controller, (index - start_at)
|
243
|
+
end
|
244
|
+
rescue NameError => e
|
245
|
+
raise unless /^uninitialized constant .*#{controller_name}$/ =~ e.message
|
246
|
+
end
|
247
|
+
|
248
|
+
begin
|
249
|
+
next_mod = eval("mod::#{mod_name}", nil, __FILE__, __LINE__)
|
250
|
+
# Check that we didn't get a module from a parent namespace
|
251
|
+
mod = (mod == Object || next_mod.name == "#{mod.name}::#{mod_name}") ? next_mod : nil
|
252
|
+
rescue NameError => e
|
253
|
+
raise unless /^uninitialized constant .*#{mod_name}$/ =~ e.message
|
254
|
+
end
|
255
|
+
|
256
|
+
return nil unless mod
|
237
257
|
end
|
238
258
|
end
|
239
259
|
end
|
@@ -442,7 +462,6 @@ module ActionController
|
|
442
462
|
@generation_methods[controller.to_sym] = method_name
|
443
463
|
end
|
444
464
|
|
445
|
-
|
446
465
|
code = generation_code_for('routes', 'generate_default_path').to_s
|
447
466
|
eval(code, nil, 'generated_code/routing/generation.rb')
|
448
467
|
|
@@ -479,7 +498,7 @@ module ActionController
|
|
479
498
|
route.write_recognition(g)
|
480
499
|
end
|
481
500
|
end
|
482
|
-
|
501
|
+
|
483
502
|
eval g.to_s, nil, 'generated/routing/recognition.rb'
|
484
503
|
return g.to_s
|
485
504
|
end
|
@@ -17,6 +17,9 @@ module ActionController
|
|
17
17
|
# This tiny piece of code will add all of the following methods to the controller:
|
18
18
|
#
|
19
19
|
# class WeblogController < ActionController::Base
|
20
|
+
# verify :method => :post, :only => [ :destroy, :create, :update ],
|
21
|
+
# :redirect_to => { :action => :list }
|
22
|
+
#
|
20
23
|
# def index
|
21
24
|
# list
|
22
25
|
# end
|
@@ -98,6 +101,11 @@ module ActionController
|
|
98
101
|
end
|
99
102
|
|
100
103
|
module_eval <<-"end_eval", __FILE__, __LINE__
|
104
|
+
|
105
|
+
verify :method => :post, :only => [ :destroy#{suffix}, :create#{suffix}, :update#{suffix} ],
|
106
|
+
:redirect_to => { :action => :list#{suffix} }
|
107
|
+
|
108
|
+
|
101
109
|
def list#{suffix}
|
102
110
|
@#{singular_name}_pages, @#{plural_name} = paginate :#{plural_name}, :per_page => 10
|
103
111
|
render#{suffix}_scaffold "list#{suffix}"
|
@@ -59,10 +59,8 @@ class CGI
|
|
59
59
|
cattr_accessor :data_column_name
|
60
60
|
self.data_column_name = 'data'
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
before_save :marshal_data!
|
65
|
-
before_save :raise_on_session_data_overflow!
|
62
|
+
before_save :marshal_data!
|
63
|
+
before_save :raise_on_session_data_overflow!
|
66
64
|
|
67
65
|
class << self
|
68
66
|
# Don't try to reload ARStore::Session in dev mode.
|
@@ -122,22 +120,24 @@ class CGI
|
|
122
120
|
@data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {}
|
123
121
|
end
|
124
122
|
|
123
|
+
# Has the session been loaded yet?
|
124
|
+
def loaded?
|
125
|
+
!! @data
|
126
|
+
end
|
127
|
+
|
125
128
|
private
|
126
129
|
attr_writer :data
|
127
130
|
|
128
131
|
def marshal_data!
|
132
|
+
return false if !loaded?
|
129
133
|
write_attribute(@@data_column_name, self.class.marshal(self.data))
|
130
134
|
end
|
131
135
|
|
132
|
-
# Has the session been loaded yet?
|
133
|
-
def loaded?
|
134
|
-
!! @data
|
135
|
-
end
|
136
|
-
|
137
136
|
# Ensures that the data about to be stored in the database is not
|
138
137
|
# larger than the data storage column. Raises
|
139
138
|
# ActionController::SessionOverflowError.
|
140
139
|
def raise_on_session_data_overflow!
|
140
|
+
return false if !loaded?
|
141
141
|
limit = self.class.data_column_size_limit
|
142
142
|
if loaded? and limit and read_attribute(@@data_column_name).size > limit
|
143
143
|
raise ActionController::SessionOverflowError
|
@@ -232,7 +232,12 @@ class CGI
|
|
232
232
|
@data
|
233
233
|
end
|
234
234
|
|
235
|
+
def loaded?
|
236
|
+
!! @data
|
237
|
+
end
|
238
|
+
|
235
239
|
def save
|
240
|
+
return false if !loaded?
|
236
241
|
marshaled_data = self.class.marshal(data)
|
237
242
|
|
238
243
|
if @new_record
|
@@ -278,7 +283,9 @@ class CGI
|
|
278
283
|
raise CGI::Session::NoSession, 'uninitialized session'
|
279
284
|
end
|
280
285
|
@session = @@session_class.new(:session_id => session_id, :data => {})
|
281
|
-
|
286
|
+
# session saving can be lazy again, because of improved component implementation
|
287
|
+
# therefore next line gets commented out:
|
288
|
+
# @session.save
|
282
289
|
end
|
283
290
|
end
|
284
291
|
|
@@ -317,6 +324,10 @@ class CGI
|
|
317
324
|
end
|
318
325
|
end
|
319
326
|
|
327
|
+
protected
|
328
|
+
def logger
|
329
|
+
ActionController::Base.logger rescue nil
|
330
|
+
end
|
320
331
|
end
|
321
332
|
end
|
322
333
|
end
|
@@ -25,30 +25,38 @@ begin
|
|
25
25
|
|
26
26
|
# Create a new CGI::Session::MemCache instance
|
27
27
|
#
|
28
|
-
# This constructor is used internally by CGI::Session.
|
28
|
+
# This constructor is used internally by CGI::Session. The
|
29
29
|
# user does not generally need to call it directly.
|
30
30
|
#
|
31
31
|
# +session+ is the session for which this instance is being
|
32
|
-
# created.
|
32
|
+
# created. The session id must only contain alphanumeric
|
33
33
|
# characters; automatically generated session ids observe
|
34
34
|
# this requirement.
|
35
35
|
#
|
36
|
-
# +
|
36
|
+
# +options+ is a hash of options for the initializer. The
|
37
37
|
# following options are recognized:
|
38
38
|
#
|
39
39
|
# cache:: an instance of a MemCache client to use as the
|
40
40
|
# session cache.
|
41
41
|
#
|
42
|
+
# expires:: an expiry time value to use for session entries in
|
43
|
+
# the session cache. +expires+ is interpreted in seconds
|
44
|
+
# relative to the current time if it�s less than 60*60*24*30
|
45
|
+
# (30 days), or as an absolute Unix time (e.g., Time#to_i) if
|
46
|
+
# greater. If +expires+ is +0+, or not passed on +options+,
|
47
|
+
# the entry will never expire.
|
48
|
+
#
|
42
49
|
# This session's memcache entry will be created if it does
|
43
50
|
# not exist, or retrieved if it does.
|
44
51
|
def initialize(session, options = {})
|
45
52
|
id = session.session_id
|
46
53
|
unless check_id(id)
|
47
54
|
raise ArgumentError, "session_id '%s' is invalid" % id
|
48
|
-
|
55
|
+
end
|
49
56
|
@cache = options['cache'] || MemCache.new('localhost')
|
50
|
-
|
51
|
-
|
57
|
+
@expires = options['expires'] || 0
|
58
|
+
@session_key = "session:#{id}"
|
59
|
+
@session_data = {}
|
52
60
|
end
|
53
61
|
|
54
62
|
# Restore session state from the session's memcache entry.
|
@@ -56,18 +64,16 @@ begin
|
|
56
64
|
# Returns the session state as a hash.
|
57
65
|
def restore
|
58
66
|
begin
|
59
|
-
@
|
67
|
+
@session_data = @cache[@session_key] || {}
|
60
68
|
rescue
|
61
|
-
|
69
|
+
@session_data = {}
|
62
70
|
end
|
63
|
-
@hash = {} unless @hash
|
64
|
-
@hash
|
65
71
|
end
|
66
72
|
|
67
73
|
# Save session state to the session's memcache entry.
|
68
74
|
def update
|
69
75
|
begin
|
70
|
-
@cache
|
76
|
+
@cache.set(@session_key, @session_data, @expires)
|
71
77
|
rescue
|
72
78
|
# Ignore session update failures.
|
73
79
|
end
|
@@ -85,7 +91,7 @@ begin
|
|
85
91
|
rescue
|
86
92
|
# Ignore session delete failures.
|
87
93
|
end
|
88
|
-
|
94
|
+
@session_data = {}
|
89
95
|
end
|
90
96
|
end
|
91
97
|
end
|