actionpack 3.0.0.beta4 → 3.0.0.rc
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 +36 -0
- data/{README → README.rdoc} +79 -137
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +3 -12
- data/lib/abstract_controller/rendering.rb +2 -2
- data/lib/abstract_controller/view_paths.rb +2 -1
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +3 -9
- data/lib/action_controller/log_subscriber.rb +56 -0
- data/lib/action_controller/metal.rb +10 -3
- data/lib/action_controller/metal/helpers.rb +5 -4
- data/lib/action_controller/metal/hide_actions.rb +3 -3
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/mime_responds.rb +13 -10
- data/lib/action_controller/metal/rack_delegation.rb +0 -4
- data/lib/action_controller/metal/request_forgery_protection.rb +1 -1
- data/lib/action_controller/metal/rescue.rb +9 -0
- data/lib/action_controller/metal/responder.rb +13 -5
- data/lib/action_controller/metal/streaming.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +5 -5
- data/lib/action_controller/railtie.rb +14 -23
- data/lib/action_controller/record_identifier.rb +6 -25
- data/lib/action_controller/test_case.rb +18 -6
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -0
- data/lib/action_dispatch.rb +6 -0
- data/lib/action_dispatch/http/cache.rb +2 -2
- data/lib/action_dispatch/http/filter_parameters.rb +10 -66
- data/lib/action_dispatch/http/mime_type.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +72 -0
- data/lib/action_dispatch/http/parameters.rb +31 -2
- data/lib/action_dispatch/http/request.rb +4 -1
- data/lib/action_dispatch/http/upload.rb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +4 -4
- data/lib/action_dispatch/middleware/cookies.rb +39 -6
- data/lib/action_dispatch/middleware/flash.rb +9 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +121 -36
- data/lib/action_dispatch/middleware/session/cookie_store.rb +26 -19
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/stack.rb +12 -5
- data/lib/action_dispatch/railtie.rb +1 -1
- data/lib/action_dispatch/routing.rb +11 -13
- data/lib/action_dispatch/routing/deprecated_mapper.rb +6 -388
- data/lib/action_dispatch/routing/mapper.rb +364 -234
- data/lib/action_dispatch/routing/polymorphic_routes.rb +186 -0
- data/lib/action_dispatch/routing/route.rb +11 -2
- data/lib/action_dispatch/routing/route_set.rb +62 -28
- data/lib/action_dispatch/routing/url_for.rb +2 -1
- data/lib/action_dispatch/testing/assertions.rb +0 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +0 -1
- data/lib/action_dispatch/testing/assertions/selector.rb +20 -24
- data/lib/action_dispatch/testing/integration.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +1 -0
- data/lib/action_view/base.rb +20 -21
- data/lib/action_view/context.rb +9 -12
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/helpers/active_model_helper.rb +17 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +15 -33
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -3
- data/lib/action_view/helpers/cache_helper.rb +4 -2
- data/lib/action_view/helpers/capture_helper.rb +4 -4
- data/lib/action_view/helpers/csrf_helper.rb +3 -1
- data/lib/action_view/helpers/date_helper.rb +10 -5
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +36 -30
- data/lib/action_view/helpers/form_options_helper.rb +7 -6
- data/lib/action_view/helpers/form_tag_helper.rb +17 -6
- data/lib/action_view/helpers/javascript_helper.rb +1 -0
- data/lib/action_view/helpers/number_helper.rb +16 -45
- data/lib/action_view/helpers/prototype_helper.rb +14 -16
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_tag_helper.rb +5 -0
- data/lib/action_view/helpers/sanitize_helper.rb +26 -20
- data/lib/action_view/helpers/scriptaculous_helper.rb +6 -5
- data/lib/action_view/helpers/tag_helper.rb +2 -1
- data/lib/action_view/helpers/text_helper.rb +24 -111
- data/lib/action_view/helpers/translation_helper.rb +17 -10
- data/lib/action_view/helpers/url_helper.rb +26 -33
- data/lib/action_view/log_subscriber.rb +28 -0
- data/lib/action_view/lookup_context.rb +2 -0
- data/lib/action_view/paths.rb +1 -0
- data/lib/action_view/railtie.rb +15 -3
- data/lib/action_view/render/layouts.rb +2 -1
- data/lib/action_view/render/partials.rb +3 -1
- data/lib/action_view/render/rendering.rb +2 -1
- data/lib/action_view/template.rb +12 -8
- data/lib/action_view/template/error.rb +1 -0
- data/lib/action_view/template/handlers.rb +1 -0
- data/lib/action_view/template/resolver.rb +2 -1
- data/lib/action_view/template/text.rb +1 -0
- data/lib/action_view/test_case.rb +42 -20
- metadata +44 -23
- data/lib/action_controller/polymorphic_routes.rb +0 -182
- data/lib/action_controller/railties/log_subscriber.rb +0 -56
- data/lib/action_controller/railties/url_helpers.rb +0 -14
- data/lib/action_dispatch/testing/assertions/model.rb +0 -19
- data/lib/action_view/helpers/record_identification_helper.rb +0 -20
- data/lib/action_view/railties/log_subscriber.rb +0 -24
@@ -4,7 +4,7 @@ module ActionDispatch
|
|
4
4
|
# read a notice you put there or <tt>flash["notice"] = "hello"</tt>
|
5
5
|
# to put a new one.
|
6
6
|
def flash
|
7
|
-
|
7
|
+
@env['action_dispatch.request.flash_hash'] ||= (session["flash"] || Flash::FlashHash.new)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -176,7 +176,14 @@ module ActionDispatch
|
|
176
176
|
|
177
177
|
@app.call(env)
|
178
178
|
ensure
|
179
|
-
|
179
|
+
session = env['rack.session'] || {}
|
180
|
+
flash_hash = env['action_dispatch.request.flash_hash']
|
181
|
+
|
182
|
+
if flash_hash && (!flash_hash.empty? || session.key?('flash'))
|
183
|
+
session["flash"] = flash_hash
|
184
|
+
end
|
185
|
+
|
186
|
+
if session.key?('flash') && session['flash'].empty?
|
180
187
|
session.delete('flash')
|
181
188
|
end
|
182
189
|
end
|
@@ -12,6 +12,35 @@ module ActionDispatch
|
|
12
12
|
ENV_SESSION_KEY = 'rack.session'.freeze
|
13
13
|
ENV_SESSION_OPTIONS_KEY = 'rack.session.options'.freeze
|
14
14
|
|
15
|
+
# thin wrapper around Hash that allows us to lazily
|
16
|
+
# load session id into session_options
|
17
|
+
class OptionsHash < Hash
|
18
|
+
def initialize(by, env, default_options)
|
19
|
+
@by = by
|
20
|
+
@env = env
|
21
|
+
@session_id_loaded = false
|
22
|
+
merge!(default_options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](key)
|
26
|
+
if key == :id
|
27
|
+
load_session_id! unless key?(:id) || has_session_id?
|
28
|
+
end
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def has_session_id?
|
35
|
+
@session_id_loaded
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_session_id!
|
39
|
+
self[:id] = @by.send(:extract_session_id, @env)
|
40
|
+
@session_id_loaded = true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
15
44
|
class SessionHash < Hash
|
16
45
|
def initialize(by, env)
|
17
46
|
super()
|
@@ -21,66 +50,80 @@ module ActionDispatch
|
|
21
50
|
end
|
22
51
|
|
23
52
|
def [](key)
|
24
|
-
|
53
|
+
load_for_read!
|
54
|
+
super(key.to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_key?(key)
|
58
|
+
load_for_read!
|
25
59
|
super(key.to_s)
|
26
60
|
end
|
27
61
|
|
28
62
|
def []=(key, value)
|
29
|
-
|
63
|
+
load_for_write!
|
30
64
|
super(key.to_s, value)
|
31
65
|
end
|
32
66
|
|
67
|
+
def clear
|
68
|
+
load_for_write!
|
69
|
+
super
|
70
|
+
end
|
71
|
+
|
33
72
|
def to_hash
|
73
|
+
load_for_read!
|
34
74
|
h = {}.replace(self)
|
35
75
|
h.delete_if { |k,v| v.nil? }
|
36
76
|
h
|
37
77
|
end
|
38
78
|
|
39
79
|
def update(hash)
|
40
|
-
|
80
|
+
load_for_write!
|
41
81
|
super(hash.stringify_keys)
|
42
82
|
end
|
43
83
|
|
44
84
|
def delete(key)
|
45
|
-
|
85
|
+
load_for_write!
|
46
86
|
super(key.to_s)
|
47
87
|
end
|
48
88
|
|
49
89
|
def inspect
|
50
|
-
|
90
|
+
load_for_read!
|
51
91
|
super
|
52
92
|
end
|
53
93
|
|
94
|
+
def exists?
|
95
|
+
return @exists if instance_variable_defined?(:@exists)
|
96
|
+
@exists = @by.send(:exists?, @env)
|
97
|
+
end
|
98
|
+
|
54
99
|
def loaded?
|
55
100
|
@loaded
|
56
101
|
end
|
57
102
|
|
103
|
+
def destroy
|
104
|
+
clear
|
105
|
+
@by.send(:destroy, @env) if @by
|
106
|
+
@env[ENV_SESSION_OPTIONS_KEY][:id] = nil if @env && @env[ENV_SESSION_OPTIONS_KEY]
|
107
|
+
@loaded = false
|
108
|
+
end
|
109
|
+
|
58
110
|
private
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
(@env[ENV_SESSION_OPTIONS_KEY] ||= {})[:id] = id
|
63
|
-
replace(session.stringify_keys)
|
64
|
-
@loaded = true
|
65
|
-
end
|
111
|
+
|
112
|
+
def load_for_read!
|
113
|
+
load! if !loaded? && exists?
|
66
114
|
end
|
67
115
|
|
68
|
-
def
|
69
|
-
|
70
|
-
rescue ArgumentError => argument_error
|
71
|
-
if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
|
72
|
-
begin
|
73
|
-
# Note that the regexp does not allow $1 to end with a ':'
|
74
|
-
$1.constantize
|
75
|
-
rescue LoadError, NameError => const_error
|
76
|
-
raise ActionDispatch::Session::SessionRestoreError, "Session contains objects whose class definition isn't available.\nRemember to require the classes for all objects kept in the session.\n(Original exception: #{const_error.message} [#{const_error.class}])\n"
|
77
|
-
end
|
78
|
-
|
79
|
-
retry
|
80
|
-
else
|
81
|
-
raise
|
82
|
-
end
|
116
|
+
def load_for_write!
|
117
|
+
load! unless loaded?
|
83
118
|
end
|
119
|
+
|
120
|
+
def load!
|
121
|
+
id, session = @by.send(:load_session, @env)
|
122
|
+
@env[ENV_SESSION_OPTIONS_KEY][:id] = id
|
123
|
+
replace(session.stringify_keys)
|
124
|
+
@loaded = true
|
125
|
+
end
|
126
|
+
|
84
127
|
end
|
85
128
|
|
86
129
|
DEFAULT_OPTIONS = {
|
@@ -108,8 +151,8 @@ module ActionDispatch
|
|
108
151
|
session_data = env[ENV_SESSION_KEY]
|
109
152
|
options = env[ENV_SESSION_OPTIONS_KEY]
|
110
153
|
|
111
|
-
if !session_data.is_a?(AbstractStore::SessionHash) || session_data.
|
112
|
-
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.
|
154
|
+
if !session_data.is_a?(AbstractStore::SessionHash) || session_data.loaded? || options[:expire_after]
|
155
|
+
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.loaded?
|
113
156
|
|
114
157
|
sid = options[:id] || generate_sid
|
115
158
|
session_data = session_data.to_hash
|
@@ -133,7 +176,7 @@ module ActionDispatch
|
|
133
176
|
|
134
177
|
def prepare!(env)
|
135
178
|
env[ENV_SESSION_KEY] = SessionHash.new(self, env)
|
136
|
-
env[ENV_SESSION_OPTIONS_KEY] = @default_options
|
179
|
+
env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options)
|
137
180
|
end
|
138
181
|
|
139
182
|
def generate_sid
|
@@ -141,15 +184,33 @@ module ActionDispatch
|
|
141
184
|
end
|
142
185
|
|
143
186
|
def set_cookie(request, options)
|
144
|
-
request.cookie_jar[@key]
|
187
|
+
if request.cookie_jar[@key] != options[:value] || !options[:expires].nil?
|
188
|
+
request.cookie_jar[@key] = options
|
189
|
+
end
|
145
190
|
end
|
146
191
|
|
147
192
|
def load_session(env)
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
193
|
+
stale_session_check! do
|
194
|
+
if sid = current_session_id(env)
|
195
|
+
sid, session = get_session(env, sid)
|
196
|
+
else
|
197
|
+
sid, session = generate_sid, {}
|
198
|
+
end
|
199
|
+
[sid, session]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def extract_session_id(env)
|
204
|
+
stale_session_check! do
|
205
|
+
request = ActionDispatch::Request.new(env)
|
206
|
+
sid = request.cookies[@key]
|
207
|
+
sid ||= request.params[@key] unless @cookie_only
|
208
|
+
sid
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def current_session_id(env)
|
213
|
+
env[ENV_SESSION_OPTIONS_KEY][:id]
|
153
214
|
end
|
154
215
|
|
155
216
|
def ensure_session_key!
|
@@ -161,6 +222,26 @@ module ActionDispatch
|
|
161
222
|
end
|
162
223
|
end
|
163
224
|
|
225
|
+
def stale_session_check!
|
226
|
+
yield
|
227
|
+
rescue ArgumentError => argument_error
|
228
|
+
if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
|
229
|
+
begin
|
230
|
+
# Note that the regexp does not allow $1 to end with a ':'
|
231
|
+
$1.constantize
|
232
|
+
rescue LoadError, NameError => const_error
|
233
|
+
raise ActionDispatch::Session::SessionRestoreError, "Session contains objects whose class definition isn't available.\nRemember to require the classes for all objects kept in the session.\n(Original exception: #{const_error.message} [#{const_error.class}])\n"
|
234
|
+
end
|
235
|
+
retry
|
236
|
+
else
|
237
|
+
raise
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def exists?(env)
|
242
|
+
current_session_id(env).present?
|
243
|
+
end
|
244
|
+
|
164
245
|
def get_session(env, sid)
|
165
246
|
raise '#get_session needs to be implemented.'
|
166
247
|
end
|
@@ -169,6 +250,10 @@ module ActionDispatch
|
|
169
250
|
raise '#set_session needs to be implemented and should return ' <<
|
170
251
|
'the value to be stored in the cookie (usually the sid)'
|
171
252
|
end
|
253
|
+
|
254
|
+
def destroy(env)
|
255
|
+
raise '#destroy needs to be implemented.'
|
256
|
+
end
|
172
257
|
end
|
173
258
|
end
|
174
259
|
end
|
@@ -35,20 +35,10 @@ module ActionDispatch
|
|
35
35
|
# such as 'MD5', 'RIPEMD160', 'SHA256', etc.
|
36
36
|
#
|
37
37
|
# To generate a secret key for an existing application, run
|
38
|
-
# "rake secret" and set the key in config/
|
38
|
+
# "rake secret" and set the key in config/initializers/secret_token.rb.
|
39
39
|
#
|
40
40
|
# Note that changing digest or secret invalidates all existing sessions!
|
41
41
|
class CookieStore < AbstractStore
|
42
|
-
class OptionsHash < Hash
|
43
|
-
def initialize(by, env, default_options)
|
44
|
-
@session_data = env[AbstractStore::ENV_SESSION_KEY]
|
45
|
-
merge!(default_options)
|
46
|
-
end
|
47
|
-
|
48
|
-
def [](key)
|
49
|
-
key == :id ? @session_data[:session_id] : super(key)
|
50
|
-
end
|
51
|
-
end
|
52
42
|
|
53
43
|
def initialize(app, options = {})
|
54
44
|
super(app, options.merge!(:cookie_only => true))
|
@@ -57,19 +47,32 @@ module ActionDispatch
|
|
57
47
|
|
58
48
|
private
|
59
49
|
|
60
|
-
def prepare!(env)
|
61
|
-
env[ENV_SESSION_KEY] = SessionHash.new(self, env)
|
62
|
-
env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options)
|
63
|
-
end
|
64
|
-
|
65
50
|
def load_session(env)
|
66
|
-
|
67
|
-
data = request.cookie_jar.signed[@key]
|
51
|
+
data = unpacked_cookie_data(env)
|
68
52
|
data = persistent_session_id!(data)
|
69
|
-
data.stringify_keys!
|
70
53
|
[data["session_id"], data]
|
71
54
|
end
|
72
55
|
|
56
|
+
def extract_session_id(env)
|
57
|
+
if data = unpacked_cookie_data(env)
|
58
|
+
data["session_id"]
|
59
|
+
else
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def unpacked_cookie_data(env)
|
65
|
+
env["action_dispatch.request.unsigned_session_cookie"] ||= begin
|
66
|
+
stale_session_check! do
|
67
|
+
request = ActionDispatch::Request.new(env)
|
68
|
+
if data = request.cookie_jar.signed[@key]
|
69
|
+
data.stringify_keys!
|
70
|
+
end
|
71
|
+
data || {}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
73
76
|
def set_cookie(request, options)
|
74
77
|
request.cookie_jar.signed[@key] = options
|
75
78
|
end
|
@@ -78,6 +81,10 @@ module ActionDispatch
|
|
78
81
|
persistent_session_id!(session_data, sid)
|
79
82
|
end
|
80
83
|
|
84
|
+
def destroy(env)
|
85
|
+
# session data is stored on client; nothing to do here
|
86
|
+
end
|
87
|
+
|
81
88
|
def persistent_session_id!(data, sid=nil)
|
82
89
|
data ||= {}
|
83
90
|
data["session_id"] ||= sid || generate_sid
|
@@ -25,7 +25,6 @@ module ActionDispatch
|
|
25
25
|
|
26
26
|
private
|
27
27
|
def get_session(env, sid)
|
28
|
-
sid ||= generate_sid
|
29
28
|
begin
|
30
29
|
session = @pool.get(sid) || {}
|
31
30
|
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
@@ -42,6 +41,15 @@ module ActionDispatch
|
|
42
41
|
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
43
42
|
false
|
44
43
|
end
|
44
|
+
|
45
|
+
def destroy(env)
|
46
|
+
if sid = current_session_id(env)
|
47
|
+
@pool.delete(sid)
|
48
|
+
end
|
49
|
+
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|
@@ -122,7 +122,7 @@ module ActionDispatch
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def render(status, body)
|
125
|
-
[status, {'Content-Type' => 'text/html', 'Content-Length' => body.
|
125
|
+
[status, {'Content-Type' => 'text/html', 'Content-Length' => body.bytesize.to_s}, [body]]
|
126
126
|
end
|
127
127
|
|
128
128
|
def public_path
|
@@ -135,7 +135,7 @@ module ActionDispatch
|
|
135
135
|
ActiveSupport::Deprecation.silence do
|
136
136
|
message = "\n#{exception.class} (#{exception.message}):\n"
|
137
137
|
message << exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
|
138
|
-
message << exception.
|
138
|
+
message << " " << application_trace(exception).join("\n ")
|
139
139
|
logger.fatal("#{message}\n\n")
|
140
140
|
end
|
141
141
|
end
|
@@ -46,7 +46,7 @@ module ActionDispatch
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def insert(index, *args, &block)
|
49
|
-
index =
|
49
|
+
index = assert_index(index, :before)
|
50
50
|
middleware = self.class::Middleware.new(*args, &block)
|
51
51
|
super(index, middleware)
|
52
52
|
end
|
@@ -54,9 +54,8 @@ module ActionDispatch
|
|
54
54
|
alias_method :insert_before, :insert
|
55
55
|
|
56
56
|
def insert_after(index, *args, &block)
|
57
|
-
|
58
|
-
|
59
|
-
insert(i + 1, *args, &block)
|
57
|
+
index = assert_index(index, :after)
|
58
|
+
insert(index + 1, *args, &block)
|
60
59
|
end
|
61
60
|
|
62
61
|
def swap(target, *args, &block)
|
@@ -70,7 +69,7 @@ module ActionDispatch
|
|
70
69
|
end
|
71
70
|
|
72
71
|
def active
|
73
|
-
ActiveSupport::Deprecation.warn "All middlewares in the
|
72
|
+
ActiveSupport::Deprecation.warn "All middlewares in the chain are active since the laziness " <<
|
74
73
|
"was removed from the middleware stack", caller
|
75
74
|
end
|
76
75
|
|
@@ -79,5 +78,13 @@ module ActionDispatch
|
|
79
78
|
raise "MiddlewareStack#build requires an app" unless app
|
80
79
|
reverse.inject(app) { |a, e| e.build(a) }
|
81
80
|
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def assert_index(index, where)
|
85
|
+
i = index.is_a?(Integer) ? index : self.index(index)
|
86
|
+
raise "No such middleware to insert #{where}: #{index.inspect}" unless i
|
87
|
+
i
|
88
|
+
end
|
82
89
|
end
|
83
90
|
end
|
@@ -10,7 +10,7 @@ module ActionDispatch
|
|
10
10
|
|
11
11
|
# Prepare dispatcher callbacks and run 'prepare' callbacks
|
12
12
|
initializer "action_dispatch.prepare_dispatcher" do |app|
|
13
|
-
ActionDispatch::Callbacks.to_prepare { app.routes_reloader.
|
13
|
+
ActionDispatch::Callbacks.to_prepare { app.routes_reloader.execute_if_updated }
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'active_support/core_ext/object/to_param'
|
2
2
|
require 'active_support/core_ext/regexp'
|
3
|
-
require 'action_controller/polymorphic_routes'
|
4
3
|
|
5
4
|
module ActionDispatch
|
6
|
-
#
|
5
|
+
# = Routing
|
7
6
|
#
|
8
7
|
# The routing module provides URL rewriting in native Ruby. It's a way to
|
9
8
|
# redirect incoming requests to controllers and actions. This replaces
|
@@ -31,7 +30,7 @@ module ActionDispatch
|
|
31
30
|
# Think of creating routes as drawing a map for your requests. The map tells
|
32
31
|
# them where to go based on some predefined pattern:
|
33
32
|
#
|
34
|
-
# AppName::
|
33
|
+
# AppName::Application.routes.draw do
|
35
34
|
# Pattern 1 tells some request to go to one place
|
36
35
|
# Pattern 2 tell them to go to another
|
37
36
|
# ...
|
@@ -62,7 +61,7 @@ module ActionDispatch
|
|
62
61
|
#
|
63
62
|
# redirect_to show_item_path(:id => 25)
|
64
63
|
#
|
65
|
-
# Use <tt>root</tt> as a shorthand to name a route for the root path "".
|
64
|
+
# Use <tt>root</tt> as a shorthand to name a route for the root path "/".
|
66
65
|
#
|
67
66
|
# # In routes.rb
|
68
67
|
# root :to => 'blogs#index'
|
@@ -72,7 +71,7 @@ module ActionDispatch
|
|
72
71
|
#
|
73
72
|
# # and provide these named routes
|
74
73
|
# root_url # => 'http://www.example.com/'
|
75
|
-
# root_path # => ''
|
74
|
+
# root_path # => '/'
|
76
75
|
#
|
77
76
|
# Note: when using +controller+, the route is simply named after the
|
78
77
|
# method you call on the block parameter rather than map.
|
@@ -91,9 +90,7 @@ module ActionDispatch
|
|
91
90
|
#
|
92
91
|
# Routes can generate pretty URLs. For example:
|
93
92
|
#
|
94
|
-
# match '/articles/:year/:month/:day', :constraints => {
|
95
|
-
# :controller => 'articles',
|
96
|
-
# :action => 'find_by_date',
|
93
|
+
# match '/articles/:year/:month/:day' => 'articles#find_by_id', :constraints => {
|
97
94
|
# :year => /\d{4}/,
|
98
95
|
# :month => /\d{1,2}/,
|
99
96
|
# :day => /\d{1,2}/
|
@@ -108,7 +105,7 @@ module ActionDispatch
|
|
108
105
|
# You can specify a regular expression to define a format for a parameter.
|
109
106
|
#
|
110
107
|
# controller 'geocode' do
|
111
|
-
# match 'geocode/:postalcode' => :show
|
108
|
+
# match 'geocode/:postalcode' => :show, :constraints => {
|
112
109
|
# :postalcode => /\d{5}(-\d{4})?/
|
113
110
|
# }
|
114
111
|
#
|
@@ -116,13 +113,13 @@ module ActionDispatch
|
|
116
113
|
# expression modifiers:
|
117
114
|
#
|
118
115
|
# controller 'geocode' do
|
119
|
-
# match 'geocode/:postalcode' => :show
|
116
|
+
# match 'geocode/:postalcode' => :show, :constraints => {
|
120
117
|
# :postalcode => /hx\d\d\s\d[a-z]{2}/i
|
121
118
|
# }
|
122
119
|
# end
|
123
120
|
#
|
124
121
|
# controller 'geocode' do
|
125
|
-
# match 'geocode/:postalcode' => :show
|
122
|
+
# match 'geocode/:postalcode' => :show, :constraints => {
|
126
123
|
# :postalcode => /# Postcode format
|
127
124
|
# \d{5} #Prefix
|
128
125
|
# (-\d{4})? #Suffix
|
@@ -167,7 +164,7 @@ module ActionDispatch
|
|
167
164
|
#
|
168
165
|
# You can reload routes if you feel you must:
|
169
166
|
#
|
170
|
-
# Rails
|
167
|
+
# Rails.application.reload_routes!
|
171
168
|
#
|
172
169
|
# This will clear all named routes and reload routes.rb if the file has been modified from
|
173
170
|
# last load. To absolutely force reloading, use <tt>reload!</tt>.
|
@@ -219,13 +216,14 @@ module ActionDispatch
|
|
219
216
|
autoload :Route, 'action_dispatch/routing/route'
|
220
217
|
autoload :RouteSet, 'action_dispatch/routing/route_set'
|
221
218
|
autoload :UrlFor, 'action_dispatch/routing/url_for'
|
219
|
+
autoload :PolymorphicRoutes, 'action_dispatch/routing/polymorphic_routes'
|
222
220
|
|
223
221
|
SEPARATORS = %w( / . ? ) #:nodoc:
|
224
222
|
HTTP_METHODS = [:get, :head, :post, :put, :delete, :options] #:nodoc:
|
225
223
|
|
226
224
|
# A helper module to hold URL related helpers.
|
227
225
|
module Helpers #:nodoc:
|
228
|
-
include
|
226
|
+
include PolymorphicRoutes
|
229
227
|
end
|
230
228
|
end
|
231
229
|
end
|