actionpack 3.0.20 → 3.1.0.beta1
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 +88 -142
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -6
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +24 -19
- data/lib/abstract_controller/callbacks.rb +19 -19
- data/lib/abstract_controller/helpers.rb +11 -13
- data/lib/abstract_controller/layouts.rb +4 -5
- data/lib/abstract_controller/railties/routes_helpers.rb +18 -0
- data/lib/abstract_controller/rendering.rb +34 -31
- data/lib/abstract_controller/url_for.rb +27 -0
- data/lib/abstract_controller/view_paths.rb +31 -6
- data/lib/action_controller.rb +5 -3
- data/lib/action_controller/base.rb +15 -16
- data/lib/action_controller/caching.rb +2 -2
- data/lib/action_controller/caching/actions.rb +11 -12
- data/lib/action_controller/caching/fragments.rb +41 -19
- data/lib/action_controller/caching/pages.rb +3 -9
- data/lib/action_controller/caching/sweeping.rb +0 -1
- data/lib/action_controller/deprecated.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +1 -1
- data/lib/action_controller/metal.rb +78 -20
- data/lib/action_controller/metal/compatibility.rb +0 -9
- data/lib/action_controller/metal/conditional_get.rb +9 -9
- data/lib/action_controller/metal/data_streaming.rb +145 -0
- data/lib/action_controller/metal/force_ssl.rb +35 -0
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/helpers.rb +37 -44
- data/lib/action_controller/metal/hide_actions.rb +2 -3
- data/lib/action_controller/metal/http_authentication.rb +41 -38
- data/lib/action_controller/metal/implicit_render.rb +13 -13
- data/lib/action_controller/metal/instrumentation.rb +2 -2
- data/lib/action_controller/metal/mime_responds.rb +25 -19
- data/lib/action_controller/metal/params_wrapper.rb +224 -0
- data/lib/action_controller/metal/redirecting.rb +6 -2
- data/lib/action_controller/metal/renderers.rb +50 -36
- data/lib/action_controller/metal/rendering.rb +34 -25
- data/lib/action_controller/metal/request_forgery_protection.rb +18 -36
- data/lib/action_controller/metal/responder.rb +47 -12
- data/lib/action_controller/metal/streaming.rb +244 -138
- data/lib/action_controller/metal/testing.rb +0 -9
- data/lib/action_controller/metal/url_for.rb +12 -14
- data/lib/action_controller/railtie.rb +19 -37
- data/lib/action_controller/railties/paths.rb +24 -0
- data/lib/action_controller/record_identifier.rb +4 -10
- data/lib/action_controller/test_case.rb +36 -19
- data/lib/action_controller/vendor/html-scanner/html/node.rb +5 -5
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +3 -3
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -0
- data/lib/action_dispatch.rb +4 -1
- data/lib/action_dispatch/http/cache.rb +5 -32
- data/lib/action_dispatch/http/filter_parameters.rb +3 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -3
- data/lib/action_dispatch/http/mime_type.rb +45 -5
- data/lib/action_dispatch/http/rack_cache.rb +58 -0
- data/lib/action_dispatch/http/request.rb +27 -41
- data/lib/action_dispatch/http/response.rb +56 -54
- data/lib/action_dispatch/http/upload.rb +1 -11
- data/lib/action_dispatch/http/url.rb +102 -42
- data/lib/action_dispatch/middleware/callbacks.rb +8 -25
- data/lib/action_dispatch/middleware/closed_error.rb +7 -0
- data/lib/action_dispatch/middleware/cookies.rb +37 -15
- data/lib/action_dispatch/middleware/flash.rb +80 -11
- data/lib/action_dispatch/middleware/params_parser.rb +2 -2
- data/lib/action_dispatch/middleware/reloader.rb +76 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +56 -226
- data/lib/action_dispatch/middleware/session/cookie_store.rb +20 -44
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -46
- data/lib/action_dispatch/middleware/show_exceptions.rb +15 -2
- data/lib/action_dispatch/middleware/stack.rb +50 -17
- data/lib/action_dispatch/middleware/static.rb +41 -29
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +2 -6
- data/lib/action_dispatch/railtie.rb +8 -0
- data/lib/action_dispatch/routing.rb +13 -1
- data/lib/action_dispatch/routing/mapper.rb +345 -227
- data/lib/action_dispatch/routing/polymorphic_routes.rb +33 -13
- data/lib/action_dispatch/routing/redirection.rb +110 -0
- data/lib/action_dispatch/routing/route.rb +15 -13
- data/lib/action_dispatch/routing/route_set.rb +116 -90
- data/lib/action_dispatch/routing/routes_proxy.rb +35 -0
- data/lib/action_dispatch/routing/url_for.rb +25 -1
- data/lib/action_dispatch/testing/assertions/response.rb +8 -10
- data/lib/action_dispatch/testing/assertions/routing.rb +15 -15
- data/lib/action_dispatch/testing/assertions/selector.rb +13 -220
- data/lib/action_dispatch/testing/integration.rb +37 -28
- data/lib/action_dispatch/testing/performance_test.rb +1 -3
- data/lib/action_dispatch/testing/test_process.rb +1 -1
- data/lib/action_dispatch/testing/test_request.rb +9 -3
- data/lib/action_dispatch/testing/test_response.rb +4 -111
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +39 -24
- data/lib/action_view/base.rb +61 -86
- data/lib/action_view/buffers.rb +43 -0
- data/lib/action_view/context.rb +21 -24
- data/lib/action_view/flows.rb +79 -0
- data/lib/action_view/helpers.rb +8 -6
- data/lib/action_view/helpers/active_model_helper.rb +0 -23
- data/lib/action_view/helpers/asset_paths.rb +79 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +30 -500
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +147 -0
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +101 -0
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +200 -0
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +152 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +11 -19
- data/lib/action_view/helpers/capture_helper.rb +19 -8
- data/lib/action_view/helpers/controller_helper.rb +21 -0
- data/lib/action_view/helpers/csrf_helper.rb +22 -4
- data/lib/action_view/helpers/date_helper.rb +36 -22
- data/lib/action_view/helpers/form_helper.rb +199 -113
- data/lib/action_view/helpers/form_options_helper.rb +10 -11
- data/lib/action_view/helpers/form_tag_helper.rb +94 -22
- data/lib/action_view/helpers/javascript_helper.rb +24 -107
- data/lib/action_view/helpers/number_helper.rb +36 -33
- data/lib/action_view/helpers/output_safety_helper.rb +38 -0
- data/lib/action_view/helpers/record_tag_helper.rb +6 -6
- data/lib/action_view/helpers/rendering_helper.rb +90 -0
- data/lib/action_view/helpers/sanitize_helper.rb +2 -2
- data/lib/action_view/helpers/sprockets_helper.rb +69 -0
- data/lib/action_view/helpers/tag_helper.rb +34 -12
- data/lib/action_view/helpers/text_helper.rb +30 -145
- data/lib/action_view/helpers/translation_helper.rb +10 -17
- data/lib/action_view/helpers/url_helper.rb +70 -67
- data/lib/action_view/locale/en.yml +1 -1
- data/lib/action_view/lookup_context.rb +36 -14
- data/lib/action_view/{paths.rb → path_set.rb} +9 -8
- data/lib/action_view/railtie.rb +12 -4
- data/lib/action_view/renderer/abstract_renderer.rb +36 -0
- data/lib/action_view/{render/partials.rb → renderer/partial_renderer.rb} +147 -146
- data/lib/action_view/renderer/renderer.rb +54 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +106 -0
- data/lib/action_view/renderer/template_renderer.rb +74 -0
- data/lib/action_view/template.rb +91 -54
- data/lib/action_view/template/error.rb +11 -8
- data/lib/action_view/template/handler.rb +9 -1
- data/lib/action_view/template/handlers.rb +9 -9
- data/lib/action_view/template/handlers/builder.rb +4 -4
- data/lib/action_view/template/handlers/erb.rb +21 -41
- data/lib/action_view/template/resolver.rb +171 -57
- data/lib/action_view/template/text.rb +0 -4
- data/lib/action_view/test_case.rb +32 -16
- data/lib/action_view/testing/resolvers.rb +16 -10
- data/lib/sprockets/railtie.rb +100 -0
- metadata +162 -140
- checksums.yaml +0 -7
- data/lib/action_controller/deprecated/base.rb +0 -143
- data/lib/action_controller/deprecated/dispatcher.rb +0 -28
- data/lib/action_controller/deprecated/url_writer.rb +0 -14
- data/lib/action_dispatch/routing/deprecated_mapper.rb +0 -525
- data/lib/action_view/helpers/prototype_helper.rb +0 -851
- data/lib/action_view/helpers/raw_output_helper.rb +0 -18
- data/lib/action_view/helpers/scriptaculous_helper.rb +0 -263
- data/lib/action_view/render/layouts.rb +0 -83
- data/lib/action_view/render/rendering.rb +0 -67
- data/lib/action_view/template/handlers/rjs.rb +0 -17
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 1233f96f807c0dc8b447b84b7b7d031267147203
|
4
|
-
data.tar.gz: d1a329c22c422cf76385feda31f9200f4afe1b10
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: c9a95139477e0cfa773bb32f27e18588d79580402313f865f5193a308c8d422dced7e957e4e46422501f7020d5a957ec0f5996a910b7f240314353b82fbbc462
|
7
|
-
data.tar.gz: 232a6d69810531cb7496203f04a304f6b9cab4c5180bf2c34ddfc29775d375dae3e5d7da3782497888692aaf007fdf1aac8e0e42885f68cbc875e4d5e615adbf
|
@@ -1,143 +0,0 @@
|
|
1
|
-
module ActionController
|
2
|
-
class Base
|
3
|
-
# Deprecated methods. Wrap them in a module so they can be overwritten by plugins
|
4
|
-
# (like the verify method.)
|
5
|
-
module DeprecatedBehavior #:nodoc:
|
6
|
-
def relative_url_root
|
7
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.relative_url_root is ineffective. " <<
|
8
|
-
"Please stop using it.", caller
|
9
|
-
end
|
10
|
-
|
11
|
-
def relative_url_root=(value)
|
12
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.relative_url_root= is ineffective. " <<
|
13
|
-
"Please stop using it.", caller
|
14
|
-
end
|
15
|
-
|
16
|
-
def consider_all_requests_local
|
17
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " <<
|
18
|
-
"use Rails.application.config.consider_all_requests_local instead", caller
|
19
|
-
Rails.application.config.consider_all_requests_local
|
20
|
-
end
|
21
|
-
|
22
|
-
def consider_all_requests_local=(value)
|
23
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " <<
|
24
|
-
"Please configure it on your application with config.consider_all_requests_local=", caller
|
25
|
-
Rails.application.config.consider_all_requests_local = value
|
26
|
-
end
|
27
|
-
|
28
|
-
def allow_concurrency
|
29
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " <<
|
30
|
-
"use Rails.application.config.allow_concurrency instead", caller
|
31
|
-
Rails.application.config.allow_concurrency
|
32
|
-
end
|
33
|
-
|
34
|
-
def allow_concurrency=(value)
|
35
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " <<
|
36
|
-
"Please configure it on your application with config.allow_concurrency=", caller
|
37
|
-
Rails.application.config.allow_concurrency = value
|
38
|
-
end
|
39
|
-
|
40
|
-
def ip_spoofing_check=(value)
|
41
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " <<
|
42
|
-
"Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller
|
43
|
-
Rails.application.config.action_dispatch.ip_spoofing_check = value
|
44
|
-
end
|
45
|
-
|
46
|
-
def ip_spoofing_check
|
47
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " <<
|
48
|
-
"Configuring ip_spoofing_check on the application configures a middleware.", caller
|
49
|
-
Rails.application.config.action_dispatch.ip_spoofing_check
|
50
|
-
end
|
51
|
-
|
52
|
-
def cookie_verifier_secret=(value)
|
53
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret= is deprecated. " <<
|
54
|
-
"Please configure it on your application with config.secret_token=", caller
|
55
|
-
end
|
56
|
-
|
57
|
-
def cookie_verifier_secret
|
58
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated.", caller
|
59
|
-
end
|
60
|
-
|
61
|
-
def trusted_proxies=(value)
|
62
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " <<
|
63
|
-
"Please configure it on your application with config.action_dispatch.trusted_proxies=", caller
|
64
|
-
Rails.application.config.action_dispatch.ip_spoofing_check = value
|
65
|
-
end
|
66
|
-
|
67
|
-
def trusted_proxies
|
68
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " <<
|
69
|
-
"Configuring trusted_proxies on the application configures a middleware.", caller
|
70
|
-
Rails.application.config.action_dispatch.ip_spoofing_check = value
|
71
|
-
end
|
72
|
-
|
73
|
-
def session(*args)
|
74
|
-
ActiveSupport::Deprecation.warn(
|
75
|
-
"Disabling sessions for a single controller has been deprecated. " +
|
76
|
-
"Sessions are now lazy loaded. So if you don't access them, " +
|
77
|
-
"consider them off. You can still modify the session cookie " +
|
78
|
-
"options with request.session_options.", caller)
|
79
|
-
end
|
80
|
-
|
81
|
-
def session=(value)
|
82
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " <<
|
83
|
-
"Please configure it on your application with config.session_store :cookie_store, :key => '....'", caller
|
84
|
-
|
85
|
-
if secret = value.delete(:secret)
|
86
|
-
Rails.application.config.secret_token = secret
|
87
|
-
end
|
88
|
-
|
89
|
-
if value.delete(:disabled)
|
90
|
-
Rails.application.config.session_store :disabled
|
91
|
-
else
|
92
|
-
store = Rails.application.config.session_store
|
93
|
-
Rails.application.config.session_store store, value
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# Controls the resource action separator
|
98
|
-
def resource_action_separator
|
99
|
-
@resource_action_separator ||= "/"
|
100
|
-
end
|
101
|
-
|
102
|
-
def resource_action_separator=(val)
|
103
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \
|
104
|
-
"works with the deprecated router DSL."
|
105
|
-
@resource_action_separator = val
|
106
|
-
end
|
107
|
-
|
108
|
-
def use_accept_header
|
109
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \
|
110
|
-
"The accept header is always taken into account."
|
111
|
-
end
|
112
|
-
|
113
|
-
def use_accept_header=(val)
|
114
|
-
use_accept_header
|
115
|
-
end
|
116
|
-
|
117
|
-
# This method has been moved to ActionDispatch::Request.filter_parameters
|
118
|
-
def filter_parameter_logging(*args, &block)
|
119
|
-
ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller)
|
120
|
-
filter = Rails.application.config.filter_parameters
|
121
|
-
filter.concat(args)
|
122
|
-
filter << block if block
|
123
|
-
filter
|
124
|
-
end
|
125
|
-
|
126
|
-
# This was moved to a plugin
|
127
|
-
def verify(*args)
|
128
|
-
ActiveSupport::Deprecation.warn "verify was removed from Rails and is now available as a plugin. " \
|
129
|
-
"Please install it with `rails plugin install git://github.com/sikachu/verification.git`.", caller
|
130
|
-
end
|
131
|
-
|
132
|
-
def exempt_from_layout(*)
|
133
|
-
ActiveSupport::Deprecation.warn "exempt_from_layout is no longer needed, because layouts in Rails 3 " \
|
134
|
-
"are restricted to the content-type of the template that was rendered.", caller
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
extend DeprecatedBehavior
|
139
|
-
|
140
|
-
delegate :consider_all_requests_local, :consider_all_requests_local=,
|
141
|
-
:allow_concurrency, :allow_concurrency=, :to => :"self.class"
|
142
|
-
end
|
143
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module ActionController
|
2
|
-
class Dispatcher
|
3
|
-
class << self
|
4
|
-
def before_dispatch(*args, &block)
|
5
|
-
ActiveSupport::Deprecation.warn "ActionController::Dispatcher.before_dispatch is deprecated. " <<
|
6
|
-
"Please use ActionDispatch::Callbacks.before instead.", caller
|
7
|
-
ActionDispatch::Callbacks.before(*args, &block)
|
8
|
-
end
|
9
|
-
|
10
|
-
def after_dispatch(*args, &block)
|
11
|
-
ActiveSupport::Deprecation.warn "ActionController::Dispatcher.after_dispatch is deprecated. " <<
|
12
|
-
"Please use ActionDispatch::Callbacks.after instead.", caller
|
13
|
-
ActionDispatch::Callbacks.after(*args, &block)
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_prepare(*args, &block)
|
17
|
-
ActiveSupport::Deprecation.warn "ActionController::Dispatcher.to_prepare is deprecated. " <<
|
18
|
-
"Please use config.to_prepare instead", caller
|
19
|
-
ActionDispatch::Callbacks.after(*args, &block)
|
20
|
-
end
|
21
|
-
|
22
|
-
def new
|
23
|
-
ActiveSupport::Deprecation.warn "ActionController::Dispatcher.new is deprecated, use Rails.application instead."
|
24
|
-
Rails.application
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module ActionController
|
2
|
-
module UrlWriter
|
3
|
-
def self.included(klass)
|
4
|
-
ActiveSupport::Deprecation.warn "include ActionController::UrlWriter is deprecated. Instead, " \
|
5
|
-
"include Rails.application.routes.url_helpers"
|
6
|
-
klass.class_eval { include Rails.application.routes.url_helpers }
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class UrlRewriter
|
11
|
-
def initialize(*)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,525 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
2
|
-
require 'active_support/core_ext/object/with_options'
|
3
|
-
require 'active_support/core_ext/object/try'
|
4
|
-
|
5
|
-
module ActionDispatch
|
6
|
-
module Routing
|
7
|
-
class RouteSet
|
8
|
-
attr_accessor :controller_namespaces
|
9
|
-
|
10
|
-
CONTROLLER_REGEXP = /[_a-zA-Z0-9]+/
|
11
|
-
|
12
|
-
def controller_constraints
|
13
|
-
@controller_constraints ||= begin
|
14
|
-
namespaces = controller_namespaces + in_memory_controller_namespaces
|
15
|
-
source = namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" }
|
16
|
-
source << CONTROLLER_REGEXP.source
|
17
|
-
Regexp.compile(source.sort.reverse.join('|'))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def in_memory_controller_namespaces
|
22
|
-
namespaces = Set.new
|
23
|
-
ActionController::Base.descendants.each do |klass|
|
24
|
-
next if klass.anonymous?
|
25
|
-
namespaces << klass.name.underscore.split('/')[0...-1].join('/')
|
26
|
-
end
|
27
|
-
namespaces.delete('')
|
28
|
-
namespaces
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class DeprecatedMapper #:nodoc:
|
33
|
-
def initialize(set) #:nodoc:
|
34
|
-
ActiveSupport::Deprecation.warn "You are using the old router DSL which will be removed in Rails 3.1. " <<
|
35
|
-
"Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
|
36
|
-
@set = set
|
37
|
-
end
|
38
|
-
|
39
|
-
def connect(path, options = {})
|
40
|
-
options = options.dup
|
41
|
-
|
42
|
-
if conditions = options.delete(:conditions)
|
43
|
-
conditions = conditions.dup
|
44
|
-
method = [conditions.delete(:method)].flatten.compact
|
45
|
-
method.map! { |m|
|
46
|
-
m = m.to_s.upcase
|
47
|
-
|
48
|
-
if m == "HEAD"
|
49
|
-
raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
|
50
|
-
end
|
51
|
-
|
52
|
-
unless HTTP_METHODS.include?(m.downcase.to_sym)
|
53
|
-
raise ArgumentError, "Invalid HTTP method specified in route conditions"
|
54
|
-
end
|
55
|
-
|
56
|
-
m
|
57
|
-
}
|
58
|
-
|
59
|
-
if method.length > 1
|
60
|
-
method = Regexp.union(*method)
|
61
|
-
elsif method.length == 1
|
62
|
-
method = method.first
|
63
|
-
else
|
64
|
-
method = nil
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
path_prefix = options.delete(:path_prefix)
|
69
|
-
name_prefix = options.delete(:name_prefix)
|
70
|
-
namespace = options.delete(:namespace)
|
71
|
-
|
72
|
-
name = options.delete(:_name)
|
73
|
-
name = "#{name_prefix}#{name}" if name_prefix
|
74
|
-
|
75
|
-
requirements = options.delete(:requirements) || {}
|
76
|
-
defaults = options.delete(:defaults) || {}
|
77
|
-
options.each do |k, v|
|
78
|
-
if v.is_a?(Regexp)
|
79
|
-
if value = options.delete(k)
|
80
|
-
requirements[k.to_sym] = value
|
81
|
-
end
|
82
|
-
else
|
83
|
-
value = options.delete(k)
|
84
|
-
defaults[k.to_sym] = value.is_a?(Symbol) ? value : value.to_param
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
requirements.each do |_, requirement|
|
89
|
-
if requirement.source =~ %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
|
90
|
-
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
|
91
|
-
end
|
92
|
-
if requirement.multiline?
|
93
|
-
raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
requirements[:controller] ||= @set.controller_constraints
|
98
|
-
|
99
|
-
if defaults[:controller]
|
100
|
-
defaults[:action] ||= 'index'
|
101
|
-
defaults[:controller] = defaults[:controller].to_s
|
102
|
-
defaults[:controller] = "#{namespace}#{defaults[:controller]}" if namespace
|
103
|
-
end
|
104
|
-
|
105
|
-
if defaults[:action]
|
106
|
-
defaults[:action] = defaults[:action].to_s
|
107
|
-
end
|
108
|
-
|
109
|
-
if path.is_a?(String)
|
110
|
-
path = "#{path_prefix}/#{path}" if path_prefix
|
111
|
-
path = path.gsub('.:format', '(.:format)')
|
112
|
-
path = optionalize_trailing_dynamic_segments(path, requirements, defaults)
|
113
|
-
glob = $1.to_sym if path =~ /\/\*(\w+)$/
|
114
|
-
path = ::Rack::Mount::Utils.normalize_path(path)
|
115
|
-
|
116
|
-
if glob && !defaults[glob].blank?
|
117
|
-
raise ActionController::RoutingError, "paths cannot have non-empty default values"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
app = Routing::RouteSet::Dispatcher.new(:defaults => defaults, :glob => glob)
|
122
|
-
|
123
|
-
conditions = {}
|
124
|
-
conditions[:request_method] = method if method
|
125
|
-
conditions[:path_info] = path if path
|
126
|
-
|
127
|
-
@set.add_route(app, conditions, requirements, defaults, name)
|
128
|
-
end
|
129
|
-
|
130
|
-
def optionalize_trailing_dynamic_segments(path, requirements, defaults) #:nodoc:
|
131
|
-
path = (path =~ /^\//) ? path.dup : "/#{path}"
|
132
|
-
optional, segments = true, []
|
133
|
-
|
134
|
-
required_segments = requirements.keys
|
135
|
-
required_segments -= defaults.keys.compact
|
136
|
-
|
137
|
-
old_segments = path.split('/')
|
138
|
-
old_segments.shift
|
139
|
-
length = old_segments.length
|
140
|
-
|
141
|
-
old_segments.reverse.each_with_index do |segment, index|
|
142
|
-
required_segments.each do |required|
|
143
|
-
if segment =~ /#{required}/
|
144
|
-
optional = false
|
145
|
-
break
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
if optional
|
150
|
-
if segment == ":id" && segments.include?(":action")
|
151
|
-
optional = false
|
152
|
-
elsif segment == ":controller" || segment == ":action" || segment == ":id"
|
153
|
-
# Ignore
|
154
|
-
elsif !(segment =~ /^:\w+$/) &&
|
155
|
-
!(segment =~ /^:\w+\(\.:format\)$/)
|
156
|
-
optional = false
|
157
|
-
elsif segment =~ /^:(\w+)$/
|
158
|
-
if defaults.has_key?($1.to_sym)
|
159
|
-
defaults.delete($1.to_sym) if defaults[$1.to_sym].nil?
|
160
|
-
else
|
161
|
-
optional = false
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
if optional && index < length - 1
|
167
|
-
segments.unshift('(/', segment)
|
168
|
-
segments.push(')')
|
169
|
-
elsif optional
|
170
|
-
segments.unshift('/(', segment)
|
171
|
-
segments.push(')')
|
172
|
-
else
|
173
|
-
segments.unshift('/', segment)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
segments.join
|
178
|
-
end
|
179
|
-
private :optionalize_trailing_dynamic_segments
|
180
|
-
|
181
|
-
# Creates a named route called "root" for matching the root level request.
|
182
|
-
def root(options = {})
|
183
|
-
if options.is_a?(Symbol)
|
184
|
-
if source_route = @set.named_routes.routes[options]
|
185
|
-
options = source_route.defaults.merge({ :conditions => source_route.conditions })
|
186
|
-
end
|
187
|
-
end
|
188
|
-
named_route("root", '', options)
|
189
|
-
end
|
190
|
-
|
191
|
-
def named_route(name, path, options = {}) #:nodoc:
|
192
|
-
options[:_name] = name
|
193
|
-
connect(path, options)
|
194
|
-
end
|
195
|
-
|
196
|
-
def namespace(name, options = {}, &block)
|
197
|
-
if options[:namespace]
|
198
|
-
with_options({:path_prefix => "#{options.delete(:path_prefix)}/#{name}", :name_prefix => "#{options.delete(:name_prefix)}#{name}_", :namespace => "#{options.delete(:namespace)}#{name}/" }.merge(options), &block)
|
199
|
-
else
|
200
|
-
with_options({:path_prefix => name, :name_prefix => "#{name}_", :namespace => "#{name}/" }.merge(options), &block)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
def method_missing(route_name, *args, &proc) #:nodoc:
|
205
|
-
super unless args.length >= 1 && proc.nil?
|
206
|
-
named_route(route_name, *args)
|
207
|
-
end
|
208
|
-
|
209
|
-
INHERITABLE_OPTIONS = :namespace, :shallow
|
210
|
-
|
211
|
-
class Resource #:nodoc:
|
212
|
-
DEFAULT_ACTIONS = :index, :create, :new, :edit, :show, :update, :destroy
|
213
|
-
|
214
|
-
attr_reader :collection_methods, :member_methods, :new_methods
|
215
|
-
attr_reader :path_prefix, :name_prefix, :path_segment
|
216
|
-
attr_reader :plural, :singular
|
217
|
-
attr_reader :options, :defaults
|
218
|
-
|
219
|
-
def initialize(entities, options, defaults)
|
220
|
-
@plural ||= entities
|
221
|
-
@singular ||= options[:singular] || plural.to_s.singularize
|
222
|
-
@path_segment = options.delete(:as) || @plural
|
223
|
-
|
224
|
-
@options = options
|
225
|
-
@defaults = defaults
|
226
|
-
|
227
|
-
arrange_actions
|
228
|
-
add_default_actions
|
229
|
-
set_allowed_actions
|
230
|
-
set_prefixes
|
231
|
-
end
|
232
|
-
|
233
|
-
def controller
|
234
|
-
@controller ||= "#{options[:namespace]}#{(options[:controller] || plural).to_s}"
|
235
|
-
end
|
236
|
-
|
237
|
-
def requirements(with_id = false)
|
238
|
-
@requirements ||= @options[:requirements] || {}
|
239
|
-
@id_requirement ||= { :id => @requirements.delete(:id) || /[^#{Routing::SEPARATORS.join}]+/ }
|
240
|
-
|
241
|
-
with_id ? @requirements.merge(@id_requirement) : @requirements
|
242
|
-
end
|
243
|
-
|
244
|
-
def conditions
|
245
|
-
@conditions ||= @options[:conditions] || {}
|
246
|
-
end
|
247
|
-
|
248
|
-
def path
|
249
|
-
@path ||= "#{path_prefix}/#{path_segment}"
|
250
|
-
end
|
251
|
-
|
252
|
-
def new_path
|
253
|
-
new_action = self.options[:path_names][:new] if self.options[:path_names]
|
254
|
-
new_action ||= self.defaults[:path_names][:new]
|
255
|
-
@new_path ||= "#{path}/#{new_action}"
|
256
|
-
end
|
257
|
-
|
258
|
-
def shallow_path_prefix
|
259
|
-
@shallow_path_prefix ||= @options[:shallow] ? @options[:namespace].try(:sub, /\/$/, '') : path_prefix
|
260
|
-
end
|
261
|
-
|
262
|
-
def member_path
|
263
|
-
@member_path ||= "#{shallow_path_prefix}/#{path_segment}/:id"
|
264
|
-
end
|
265
|
-
|
266
|
-
def nesting_path_prefix
|
267
|
-
@nesting_path_prefix ||= "#{shallow_path_prefix}/#{path_segment}/:#{singular}_id"
|
268
|
-
end
|
269
|
-
|
270
|
-
def shallow_name_prefix
|
271
|
-
@shallow_name_prefix ||= @options[:shallow] ? @options[:namespace].try(:gsub, /\//, '_') : name_prefix
|
272
|
-
end
|
273
|
-
|
274
|
-
def nesting_name_prefix
|
275
|
-
"#{shallow_name_prefix}#{singular}_"
|
276
|
-
end
|
277
|
-
|
278
|
-
def action_separator
|
279
|
-
@action_separator ||= ActionController::Base.resource_action_separator
|
280
|
-
end
|
281
|
-
|
282
|
-
def uncountable?
|
283
|
-
@singular.to_s == @plural.to_s
|
284
|
-
end
|
285
|
-
|
286
|
-
def has_action?(action)
|
287
|
-
!DEFAULT_ACTIONS.include?(action) || action_allowed?(action)
|
288
|
-
end
|
289
|
-
|
290
|
-
protected
|
291
|
-
def arrange_actions
|
292
|
-
@collection_methods = arrange_actions_by_methods(options.delete(:collection))
|
293
|
-
@member_methods = arrange_actions_by_methods(options.delete(:member))
|
294
|
-
@new_methods = arrange_actions_by_methods(options.delete(:new))
|
295
|
-
end
|
296
|
-
|
297
|
-
def add_default_actions
|
298
|
-
add_default_action(member_methods, :get, :edit)
|
299
|
-
add_default_action(new_methods, :get, :new)
|
300
|
-
end
|
301
|
-
|
302
|
-
def set_allowed_actions
|
303
|
-
only, except = @options.values_at(:only, :except)
|
304
|
-
@allowed_actions ||= {}
|
305
|
-
|
306
|
-
if only == :all || except == :none
|
307
|
-
only = nil
|
308
|
-
except = []
|
309
|
-
elsif only == :none || except == :all
|
310
|
-
only = []
|
311
|
-
except = nil
|
312
|
-
end
|
313
|
-
|
314
|
-
if only
|
315
|
-
@allowed_actions[:only] = Array(only).map {|a| a.to_sym }
|
316
|
-
elsif except
|
317
|
-
@allowed_actions[:except] = Array(except).map {|a| a.to_sym }
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
def action_allowed?(action)
|
322
|
-
only, except = @allowed_actions.values_at(:only, :except)
|
323
|
-
(!only || only.include?(action)) && (!except || !except.include?(action))
|
324
|
-
end
|
325
|
-
|
326
|
-
def set_prefixes
|
327
|
-
@path_prefix = options.delete(:path_prefix)
|
328
|
-
@name_prefix = options.delete(:name_prefix)
|
329
|
-
end
|
330
|
-
|
331
|
-
def arrange_actions_by_methods(actions)
|
332
|
-
(actions || {}).inject({}) do |flipped_hash, (key, value)|
|
333
|
-
(flipped_hash[value] ||= []) << key
|
334
|
-
flipped_hash
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
def add_default_action(collection, method, action)
|
339
|
-
(collection[method] ||= []).unshift(action)
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
class SingletonResource < Resource #:nodoc:
|
344
|
-
def initialize(entity, options, defaults)
|
345
|
-
@singular = @plural = entity
|
346
|
-
options[:controller] ||= @singular.to_s.pluralize
|
347
|
-
super
|
348
|
-
end
|
349
|
-
|
350
|
-
alias_method :shallow_path_prefix, :path_prefix
|
351
|
-
alias_method :shallow_name_prefix, :name_prefix
|
352
|
-
alias_method :member_path, :path
|
353
|
-
alias_method :nesting_path_prefix, :path
|
354
|
-
end
|
355
|
-
|
356
|
-
def resources(*entities, &block)
|
357
|
-
options = entities.extract_options!
|
358
|
-
entities.each { |entity| map_resource(entity, options.dup, &block) }
|
359
|
-
end
|
360
|
-
|
361
|
-
def resource(*entities, &block)
|
362
|
-
options = entities.extract_options!
|
363
|
-
entities.each { |entity| map_singleton_resource(entity, options.dup, &block) }
|
364
|
-
end
|
365
|
-
|
366
|
-
private
|
367
|
-
def map_resource(entities, options = {}, &block)
|
368
|
-
resource = Resource.new(entities, options, :path_names => @set.resources_path_names)
|
369
|
-
|
370
|
-
with_options :controller => resource.controller do |map|
|
371
|
-
map_associations(resource, options)
|
372
|
-
|
373
|
-
if block_given?
|
374
|
-
with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
|
375
|
-
end
|
376
|
-
|
377
|
-
map_collection_actions(map, resource)
|
378
|
-
map_default_collection_actions(map, resource)
|
379
|
-
map_new_actions(map, resource)
|
380
|
-
map_member_actions(map, resource)
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
def map_singleton_resource(entities, options = {}, &block)
|
385
|
-
resource = SingletonResource.new(entities, options, :path_names => @set.resources_path_names)
|
386
|
-
|
387
|
-
with_options :controller => resource.controller do |map|
|
388
|
-
map_associations(resource, options)
|
389
|
-
|
390
|
-
if block_given?
|
391
|
-
with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
|
392
|
-
end
|
393
|
-
|
394
|
-
map_collection_actions(map, resource)
|
395
|
-
map_new_actions(map, resource)
|
396
|
-
map_member_actions(map, resource)
|
397
|
-
map_default_singleton_actions(map, resource)
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
def map_associations(resource, options)
|
402
|
-
map_has_many_associations(resource, options.delete(:has_many), options) if options[:has_many]
|
403
|
-
|
404
|
-
path_prefix = "#{options.delete(:path_prefix)}#{resource.nesting_path_prefix}"
|
405
|
-
name_prefix = "#{options.delete(:name_prefix)}#{resource.nesting_name_prefix}"
|
406
|
-
|
407
|
-
Array(options[:has_one]).each do |association|
|
408
|
-
resource(association, options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => path_prefix, :name_prefix => name_prefix))
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
def map_has_many_associations(resource, associations, options)
|
413
|
-
case associations
|
414
|
-
when Hash
|
415
|
-
associations.each do |association,has_many|
|
416
|
-
map_has_many_associations(resource, association, options.merge(:has_many => has_many))
|
417
|
-
end
|
418
|
-
when Array
|
419
|
-
associations.each do |association|
|
420
|
-
map_has_many_associations(resource, association, options)
|
421
|
-
end
|
422
|
-
when Symbol, String
|
423
|
-
resources(associations, options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :has_many => options[:has_many]))
|
424
|
-
else
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
428
|
-
def map_collection_actions(map, resource)
|
429
|
-
resource.collection_methods.each do |method, actions|
|
430
|
-
actions.each do |action|
|
431
|
-
[method].flatten.each do |m|
|
432
|
-
action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
|
433
|
-
action_path ||= action
|
434
|
-
|
435
|
-
map_resource_routes(map, resource, action, "#{resource.path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.name_prefix}#{resource.plural}", m)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
def map_default_collection_actions(map, resource)
|
442
|
-
index_route_name = "#{resource.name_prefix}#{resource.plural}"
|
443
|
-
|
444
|
-
if resource.uncountable?
|
445
|
-
index_route_name << "_index"
|
446
|
-
end
|
447
|
-
|
448
|
-
map_resource_routes(map, resource, :index, resource.path, index_route_name)
|
449
|
-
map_resource_routes(map, resource, :create, resource.path, index_route_name)
|
450
|
-
end
|
451
|
-
|
452
|
-
def map_default_singleton_actions(map, resource)
|
453
|
-
map_resource_routes(map, resource, :create, resource.path, "#{resource.shallow_name_prefix}#{resource.singular}")
|
454
|
-
end
|
455
|
-
|
456
|
-
def map_new_actions(map, resource)
|
457
|
-
resource.new_methods.each do |method, actions|
|
458
|
-
actions.each do |action|
|
459
|
-
route_path = resource.new_path
|
460
|
-
route_name = "new_#{resource.name_prefix}#{resource.singular}"
|
461
|
-
|
462
|
-
unless action == :new
|
463
|
-
route_path = "#{route_path}#{resource.action_separator}#{action}"
|
464
|
-
route_name = "#{action}_#{route_name}"
|
465
|
-
end
|
466
|
-
|
467
|
-
map_resource_routes(map, resource, action, route_path, route_name, method)
|
468
|
-
end
|
469
|
-
end
|
470
|
-
end
|
471
|
-
|
472
|
-
def map_member_actions(map, resource)
|
473
|
-
resource.member_methods.each do |method, actions|
|
474
|
-
actions.each do |action|
|
475
|
-
[method].flatten.each do |m|
|
476
|
-
action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
|
477
|
-
action_path ||= @set.resources_path_names[action] || action
|
478
|
-
|
479
|
-
map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m, { :force_id => true })
|
480
|
-
end
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
route_path = "#{resource.shallow_name_prefix}#{resource.singular}"
|
485
|
-
map_resource_routes(map, resource, :show, resource.member_path, route_path)
|
486
|
-
map_resource_routes(map, resource, :update, resource.member_path, route_path)
|
487
|
-
map_resource_routes(map, resource, :destroy, resource.member_path, route_path)
|
488
|
-
end
|
489
|
-
|
490
|
-
def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil, resource_options = {} )
|
491
|
-
if resource.has_action?(action)
|
492
|
-
action_options = action_options_for(action, resource, method, resource_options)
|
493
|
-
formatted_route_path = "#{route_path}.:format"
|
494
|
-
|
495
|
-
if route_name && @set.named_routes[route_name.to_sym].nil?
|
496
|
-
map.named_route(route_name, formatted_route_path, action_options)
|
497
|
-
else
|
498
|
-
map.connect(formatted_route_path, action_options)
|
499
|
-
end
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
def add_conditions_for(conditions, method)
|
504
|
-
{:conditions => conditions.dup}.tap do |options|
|
505
|
-
options[:conditions][:method] = method unless method == :any
|
506
|
-
end
|
507
|
-
end
|
508
|
-
|
509
|
-
def action_options_for(action, resource, method = nil, resource_options = {})
|
510
|
-
default_options = { :action => action.to_s }
|
511
|
-
require_id = !resource.kind_of?(SingletonResource)
|
512
|
-
force_id = resource_options[:force_id] && !resource.kind_of?(SingletonResource)
|
513
|
-
|
514
|
-
case default_options[:action]
|
515
|
-
when "index", "new"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements)
|
516
|
-
when "create"; default_options.merge(add_conditions_for(resource.conditions, method || :post)).merge(resource.requirements)
|
517
|
-
when "show", "edit"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements(require_id))
|
518
|
-
when "update"; default_options.merge(add_conditions_for(resource.conditions, method || :put)).merge(resource.requirements(require_id))
|
519
|
-
when "destroy"; default_options.merge(add_conditions_for(resource.conditions, method || :delete)).merge(resource.requirements(require_id))
|
520
|
-
else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements(force_id))
|
521
|
-
end
|
522
|
-
end
|
523
|
-
end
|
524
|
-
end
|
525
|
-
end
|