actionpack 4.2.10 → 7.2.0.rc1
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +86 -600
- data/MIT-LICENSE +1 -1
- data/README.rdoc +13 -14
- data/lib/abstract_controller/asset_paths.rb +5 -1
- data/lib/abstract_controller/base.rb +166 -136
- data/lib/abstract_controller/caching/fragments.rb +149 -0
- data/lib/abstract_controller/caching.rb +68 -0
- data/lib/abstract_controller/callbacks.rb +126 -57
- data/lib/abstract_controller/collector.rb +13 -15
- data/lib/abstract_controller/deprecator.rb +9 -0
- data/lib/abstract_controller/error.rb +8 -0
- data/lib/abstract_controller/helpers.rb +181 -132
- data/lib/abstract_controller/logger.rb +5 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +10 -3
- data/lib/abstract_controller/rendering.rb +56 -56
- data/lib/abstract_controller/translation.rb +29 -15
- data/lib/abstract_controller/url_for.rb +15 -11
- data/lib/abstract_controller.rb +21 -5
- data/lib/action_controller/api/api_rendering.rb +18 -0
- data/lib/action_controller/api.rb +154 -0
- data/lib/action_controller/base.rb +219 -155
- data/lib/action_controller/caching.rb +28 -68
- data/lib/action_controller/deprecator.rb +9 -0
- data/lib/action_controller/form_builder.rb +55 -0
- data/lib/action_controller/log_subscriber.rb +35 -22
- data/lib/action_controller/metal/allow_browser.rb +119 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
- data/lib/action_controller/metal/conditional_get.rb +259 -122
- data/lib/action_controller/metal/content_security_policy.rb +86 -0
- data/lib/action_controller/metal/cookies.rb +9 -5
- data/lib/action_controller/metal/data_streaming.rb +87 -104
- data/lib/action_controller/metal/default_headers.rb +21 -0
- data/lib/action_controller/metal/etag_with_flash.rb +22 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +35 -26
- data/lib/action_controller/metal/exceptions.rb +71 -24
- data/lib/action_controller/metal/flash.rb +26 -19
- data/lib/action_controller/metal/head.rb +45 -36
- data/lib/action_controller/metal/helpers.rb +80 -64
- data/lib/action_controller/metal/http_authentication.rb +297 -244
- data/lib/action_controller/metal/implicit_render.rb +57 -9
- data/lib/action_controller/metal/instrumentation.rb +76 -64
- data/lib/action_controller/metal/live.rb +238 -176
- data/lib/action_controller/metal/logging.rb +22 -0
- data/lib/action_controller/metal/mime_responds.rb +177 -166
- data/lib/action_controller/metal/parameter_encoding.rb +84 -0
- data/lib/action_controller/metal/params_wrapper.rb +145 -118
- data/lib/action_controller/metal/permissions_policy.rb +38 -0
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +203 -64
- data/lib/action_controller/metal/renderers.rb +108 -65
- data/lib/action_controller/metal/rendering.rb +216 -56
- data/lib/action_controller/metal/request_forgery_protection.rb +496 -163
- data/lib/action_controller/metal/rescue.rb +19 -21
- data/lib/action_controller/metal/streaming.rb +179 -138
- data/lib/action_controller/metal/strong_parameters.rb +1058 -382
- data/lib/action_controller/metal/testing.rb +11 -17
- data/lib/action_controller/metal/url_for.rb +37 -21
- data/lib/action_controller/metal.rb +236 -138
- data/lib/action_controller/railtie.rb +89 -11
- data/lib/action_controller/railties/helpers.rb +5 -1
- data/lib/action_controller/renderer.rb +161 -0
- data/lib/action_controller/template_assertions.rb +13 -0
- data/lib/action_controller/test_case.rb +425 -497
- data/lib/action_controller.rb +44 -22
- data/lib/action_dispatch/constants.rb +34 -0
- data/lib/action_dispatch/deprecator.rb +9 -0
- data/lib/action_dispatch/http/cache.rb +119 -63
- data/lib/action_dispatch/http/content_disposition.rb +47 -0
- data/lib/action_dispatch/http/content_security_policy.rb +364 -0
- data/lib/action_dispatch/http/filter_parameters.rb +36 -34
- data/lib/action_dispatch/http/filter_redirect.rb +24 -12
- data/lib/action_dispatch/http/headers.rb +66 -31
- data/lib/action_dispatch/http/mime_negotiation.rb +106 -75
- data/lib/action_dispatch/http/mime_type.rb +196 -136
- data/lib/action_dispatch/http/mime_types.rb +25 -7
- data/lib/action_dispatch/http/parameters.rb +97 -45
- data/lib/action_dispatch/http/permissions_policy.rb +187 -0
- data/lib/action_dispatch/http/rack_cache.rb +6 -0
- data/lib/action_dispatch/http/request.rb +299 -170
- data/lib/action_dispatch/http/response.rb +311 -160
- data/lib/action_dispatch/http/upload.rb +52 -23
- data/lib/action_dispatch/http/url.rb +201 -125
- data/lib/action_dispatch/journey/formatter.rb +110 -50
- data/lib/action_dispatch/journey/gtg/builder.rb +37 -50
- data/lib/action_dispatch/journey/gtg/simulator.rb +20 -17
- data/lib/action_dispatch/journey/gtg/transition_table.rb +96 -36
- data/lib/action_dispatch/journey/nfa/dot.rb +5 -14
- data/lib/action_dispatch/journey/nodes/node.rb +100 -20
- data/lib/action_dispatch/journey/parser.rb +19 -17
- data/lib/action_dispatch/journey/parser.y +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +14 -4
- data/lib/action_dispatch/journey/path/pattern.rb +79 -63
- data/lib/action_dispatch/journey/route.rb +108 -44
- data/lib/action_dispatch/journey/router/utils.rb +41 -29
- data/lib/action_dispatch/journey/router.rb +64 -57
- data/lib/action_dispatch/journey/routes.rb +23 -21
- data/lib/action_dispatch/journey/scanner.rb +28 -17
- data/lib/action_dispatch/journey/visitors.rb +100 -54
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/journey.rb +7 -5
- data/lib/action_dispatch/log_subscriber.rb +25 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
- data/lib/action_dispatch/middleware/callbacks.rb +7 -6
- data/lib/action_dispatch/middleware/cookies.rb +471 -328
- data/lib/action_dispatch/middleware/debug_exceptions.rb +149 -66
- data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
- data/lib/action_dispatch/middleware/debug_view.rb +73 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +275 -73
- data/lib/action_dispatch/middleware/executor.rb +32 -0
- data/lib/action_dispatch/middleware/flash.rb +143 -101
- data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +36 -27
- data/lib/action_dispatch/middleware/reloader.rb +10 -92
- data/lib/action_dispatch/middleware/remote_ip.rb +133 -107
- data/lib/action_dispatch/middleware/request_id.rb +29 -15
- data/lib/action_dispatch/middleware/server_timing.rb +78 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +49 -27
- data/lib/action_dispatch/middleware/session/cache_store.rb +33 -16
- data/lib/action_dispatch/middleware/session/cookie_store.rb +86 -80
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +15 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +66 -36
- data/lib/action_dispatch/middleware/ssl.rb +134 -36
- data/lib/action_dispatch/middleware/stack.rb +109 -44
- data/lib/action_dispatch/middleware/static.rb +159 -90
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +7 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +46 -36
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +139 -15
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +6 -6
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +9 -9
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +7 -4
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +125 -93
- data/lib/action_dispatch/railtie.rb +44 -16
- data/lib/action_dispatch/request/session.rb +159 -69
- data/lib/action_dispatch/request/utils.rb +97 -23
- data/lib/action_dispatch/routing/endpoint.rb +11 -2
- data/lib/action_dispatch/routing/inspector.rb +195 -106
- data/lib/action_dispatch/routing/mapper.rb +1338 -955
- data/lib/action_dispatch/routing/polymorphic_routes.rb +234 -201
- data/lib/action_dispatch/routing/redirection.rb +78 -51
- data/lib/action_dispatch/routing/route_set.rb +460 -374
- data/lib/action_dispatch/routing/routes_proxy.rb +36 -12
- data/lib/action_dispatch/routing/url_for.rb +172 -124
- data/lib/action_dispatch/routing.rb +159 -158
- data/lib/action_dispatch/system_test_case.rb +206 -0
- data/lib/action_dispatch/system_testing/browser.rb +84 -0
- data/lib/action_dispatch/system_testing/driver.rb +85 -0
- data/lib/action_dispatch/system_testing/server.rb +33 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
- data/lib/action_dispatch/testing/assertion_response.rb +48 -0
- data/lib/action_dispatch/testing/assertions/response.rb +71 -39
- data/lib/action_dispatch/testing/assertions/routing.rb +228 -103
- data/lib/action_dispatch/testing/assertions.rb +9 -6
- data/lib/action_dispatch/testing/integration.rb +486 -306
- data/lib/action_dispatch/testing/request_encoder.rb +60 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +35 -22
- data/lib/action_dispatch/testing/test_request.rb +29 -34
- data/lib/action_dispatch/testing/test_response.rb +48 -15
- data/lib/action_dispatch.rb +82 -40
- data/lib/action_pack/gem_version.rb +8 -4
- data/lib/action_pack/version.rb +6 -2
- data/lib/action_pack.rb +21 -18
- metadata +146 -56
- data/lib/action_controller/caching/fragments.rb +0 -103
- data/lib/action_controller/metal/force_ssl.rb +0 -97
- data/lib/action_controller/metal/hide_actions.rb +0 -40
- data/lib/action_controller/metal/rack_delegation.rb +0 -32
- data/lib/action_controller/middleware.rb +0 -39
- data/lib/action_controller/model_naming.rb +0 -12
- data/lib/action_dispatch/http/parameter_filter.rb +0 -72
- data/lib/action_dispatch/journey/backwards.rb +0 -5
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -76
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -163
- data/lib/action_dispatch/journey/router/strexp.rb +0 -27
- data/lib/action_dispatch/middleware/params_parser.rb +0 -60
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +0 -27
- data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
- data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
- data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,104 +1,111 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :markup: markdown
|
2
4
|
|
3
5
|
module ActionDispatch
|
4
6
|
module Routing
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
7
|
+
# # Action Dispatch Routing PolymorphicRoutes
|
8
|
+
#
|
9
|
+
# Polymorphic URL helpers are methods for smart resolution to a named route call
|
10
|
+
# when given an Active Record model instance. They are to be used in combination
|
11
|
+
# with ActionController::Resources.
|
8
12
|
#
|
9
|
-
# These methods are useful when you want to generate correct URL or path to
|
10
|
-
# resource without having to know the exact type of the record in
|
13
|
+
# These methods are useful when you want to generate the correct URL or path to
|
14
|
+
# a RESTful resource without having to know the exact type of the record in
|
15
|
+
# question.
|
11
16
|
#
|
12
|
-
# Nested resources and/or namespaces are also supported, as illustrated in the
|
17
|
+
# Nested resources and/or namespaces are also supported, as illustrated in the
|
18
|
+
# example:
|
13
19
|
#
|
14
|
-
#
|
20
|
+
# polymorphic_url([:admin, @article, @comment])
|
15
21
|
#
|
16
22
|
# results in:
|
17
23
|
#
|
18
|
-
#
|
24
|
+
# admin_article_comment_url(@article, @comment)
|
25
|
+
#
|
26
|
+
# ## Usage within the framework
|
19
27
|
#
|
20
|
-
#
|
28
|
+
# Polymorphic URL helpers are used in a number of places throughout the Rails
|
29
|
+
# framework:
|
21
30
|
#
|
22
|
-
#
|
31
|
+
# * `url_for`, so you can use it with a record as the argument, e.g.
|
32
|
+
# `url_for(@article)`;
|
33
|
+
# * ActionView::Helpers::FormHelper uses `polymorphic_path`, so you can write
|
34
|
+
# `form_for(@article)` without having to specify `:url` parameter for the
|
35
|
+
# form action;
|
36
|
+
# * `redirect_to` (which, in fact, uses `url_for`) so you can write
|
37
|
+
# `redirect_to(post)` in your controllers;
|
38
|
+
# * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly
|
39
|
+
# specify URLs for feed entries.
|
23
40
|
#
|
24
|
-
# * <tt>url_for</tt>, so you can use it with a record as the argument, e.g.
|
25
|
-
# <tt>url_for(@article)</tt>;
|
26
|
-
# * ActionView::Helpers::FormHelper uses <tt>polymorphic_path</tt>, so you can write
|
27
|
-
# <tt>form_for(@article)</tt> without having to specify <tt>:url</tt> parameter for the form
|
28
|
-
# action;
|
29
|
-
# * <tt>redirect_to</tt> (which, in fact, uses <tt>url_for</tt>) so you can write
|
30
|
-
# <tt>redirect_to(post)</tt> in your controllers;
|
31
|
-
# * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs
|
32
|
-
# for feed entries.
|
33
41
|
#
|
34
|
-
#
|
42
|
+
# ## Prefixed polymorphic helpers
|
35
43
|
#
|
36
|
-
# In addition to
|
37
|
-
#
|
38
|
-
#
|
44
|
+
# In addition to `polymorphic_url` and `polymorphic_path` methods, a number of
|
45
|
+
# prefixed helpers are available as a shorthand to `action: "..."` in options.
|
46
|
+
# Those are:
|
47
|
+
#
|
48
|
+
# * `edit_polymorphic_url`, `edit_polymorphic_path`
|
49
|
+
# * `new_polymorphic_url`, `new_polymorphic_path`
|
39
50
|
#
|
40
|
-
# * <tt>edit_polymorphic_url</tt>, <tt>edit_polymorphic_path</tt>
|
41
|
-
# * <tt>new_polymorphic_url</tt>, <tt>new_polymorphic_path</tt>
|
42
51
|
#
|
43
52
|
# Example usage:
|
44
53
|
#
|
45
|
-
#
|
46
|
-
#
|
54
|
+
# edit_polymorphic_path(@post) # => "/posts/1/edit"
|
55
|
+
# polymorphic_path(@post, format: :pdf) # => "/posts/1.pdf"
|
47
56
|
#
|
48
|
-
#
|
57
|
+
# ## Usage with mounted engines
|
49
58
|
#
|
50
59
|
# If you are using a mounted engine and you need to use a polymorphic_url
|
51
60
|
# pointing at the engine's routes, pass in the engine's route proxy as the first
|
52
61
|
# argument to the method. For example:
|
53
62
|
#
|
54
|
-
#
|
55
|
-
#
|
63
|
+
# polymorphic_url([blog, @post]) # calls blog.post_path(@post)
|
64
|
+
# form_for([blog, @post]) # => "/blog/posts/1"
|
56
65
|
#
|
57
66
|
module PolymorphicRoutes
|
58
|
-
|
59
|
-
|
60
|
-
# Constructs a call to a named RESTful route for the given record and returns the
|
61
|
-
# resulting URL string. For example:
|
67
|
+
# Constructs a call to a named RESTful route for the given record and returns
|
68
|
+
# the resulting URL string. For example:
|
62
69
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
70
|
+
# # calls post_url(post)
|
71
|
+
# polymorphic_url(post) # => "http://example.com/posts/1"
|
72
|
+
# polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
|
73
|
+
# polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
|
74
|
+
# polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
|
75
|
+
# polymorphic_url(Comment) # => "http://example.com/comments"
|
69
76
|
#
|
70
|
-
#
|
77
|
+
# #### Options
|
71
78
|
#
|
72
|
-
# *
|
73
|
-
#
|
74
|
-
# *
|
75
|
-
# Default is <tt>:url</tt>.
|
79
|
+
# * `:action` - Specifies the action prefix for the named route: `:new` or
|
80
|
+
# `:edit`. Default is no prefix.
|
81
|
+
# * `:routing_type` - Allowed values are `:path` or `:url`. Default is `:url`.
|
76
82
|
#
|
77
|
-
# Also includes all the options from <tt>url_for</tt>. These include such
|
78
|
-
# things as <tt>:anchor</tt> or <tt>:trailing_slash</tt>. Example usage
|
79
|
-
# is given below:
|
80
83
|
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
# polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
|
84
|
-
# # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
|
84
|
+
# Also includes all the options from `url_for`. These include such things as
|
85
|
+
# `:anchor` or `:trailing_slash`. Example usage is given below:
|
85
86
|
#
|
86
|
-
#
|
87
|
+
# polymorphic_url([blog, post], anchor: 'my_anchor')
|
88
|
+
# # => "http://example.com/blogs/1/posts/1#my_anchor"
|
89
|
+
# polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
|
90
|
+
# # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
|
87
91
|
#
|
88
|
-
#
|
92
|
+
# For all of these options, see the documentation for
|
93
|
+
# [url_for](rdoc-ref:ActionDispatch::Routing::UrlFor).
|
89
94
|
#
|
90
|
-
#
|
91
|
-
# polymorphic_url(record) # same as article_url(record)
|
95
|
+
# #### Functionality
|
92
96
|
#
|
93
|
-
#
|
94
|
-
#
|
97
|
+
# # an Article record
|
98
|
+
# polymorphic_url(record) # same as article_url(record)
|
95
99
|
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
# polymorphic_url(record) # same as comments_url()
|
100
|
+
# # a Comment record
|
101
|
+
# polymorphic_url(record) # same as comment_url(record)
|
99
102
|
#
|
100
|
-
#
|
101
|
-
#
|
103
|
+
# # it recognizes new records and maps to the collection
|
104
|
+
# record = Comment.new
|
105
|
+
# polymorphic_url(record) # same as comments_url()
|
106
|
+
#
|
107
|
+
# # the class of a record will also map to the collection
|
108
|
+
# polymorphic_url(Comment) # same as comments_url()
|
102
109
|
#
|
103
110
|
def polymorphic_url(record_or_hash_or_array, options = {})
|
104
111
|
if Hash === record_or_hash_or_array
|
@@ -107,6 +114,10 @@ module ActionDispatch
|
|
107
114
|
return polymorphic_url record, options
|
108
115
|
end
|
109
116
|
|
117
|
+
if mapping = polymorphic_mapping(record_or_hash_or_array)
|
118
|
+
return mapping.call(self, [record_or_hash_or_array, options], false)
|
119
|
+
end
|
120
|
+
|
110
121
|
opts = options.dup
|
111
122
|
action = opts.delete :action
|
112
123
|
type = opts.delete(:routing_type) || :url
|
@@ -118,8 +129,7 @@ module ActionDispatch
|
|
118
129
|
opts
|
119
130
|
end
|
120
131
|
|
121
|
-
# Returns the path component of a URL for the given record.
|
122
|
-
# <tt>polymorphic_url</tt> with <tt>routing_type: :path</tt>.
|
132
|
+
# Returns the path component of a URL for the given record.
|
123
133
|
def polymorphic_path(record_or_hash_or_array, options = {})
|
124
134
|
if Hash === record_or_hash_or_array
|
125
135
|
options = record_or_hash_or_array.merge(options)
|
@@ -127,6 +137,10 @@ module ActionDispatch
|
|
127
137
|
return polymorphic_path record, options
|
128
138
|
end
|
129
139
|
|
140
|
+
if mapping = polymorphic_mapping(record_or_hash_or_array)
|
141
|
+
return mapping.call(self, [record_or_hash_or_array, options], true)
|
142
|
+
end
|
143
|
+
|
130
144
|
opts = options.dup
|
131
145
|
action = opts.delete :action
|
132
146
|
type = :path
|
@@ -138,9 +152,9 @@ module ActionDispatch
|
|
138
152
|
opts
|
139
153
|
end
|
140
154
|
|
141
|
-
|
142
155
|
%w(edit new).each do |action|
|
143
156
|
module_eval <<-EOT, __FILE__, __LINE__ + 1
|
157
|
+
# frozen_string_literal: true
|
144
158
|
def #{action}_polymorphic_url(record_or_hash, options = {})
|
145
159
|
polymorphic_url_for_action("#{action}", record_or_hash, options)
|
146
160
|
end
|
@@ -152,179 +166,198 @@ module ActionDispatch
|
|
152
166
|
end
|
153
167
|
|
154
168
|
private
|
155
|
-
|
156
|
-
|
157
|
-
polymorphic_url(record_or_hash, options.merge(:action => action))
|
158
|
-
end
|
159
|
-
|
160
|
-
def polymorphic_path_for_action(action, record_or_hash, options)
|
161
|
-
polymorphic_path(record_or_hash, options.merge(:action => action))
|
162
|
-
end
|
163
|
-
|
164
|
-
class HelperMethodBuilder # :nodoc:
|
165
|
-
CACHE = { 'path' => {}, 'url' => {} }
|
166
|
-
|
167
|
-
def self.get(action, type)
|
168
|
-
type = type.to_s
|
169
|
-
CACHE[type].fetch(action) { build action, type }
|
169
|
+
def polymorphic_url_for_action(action, record_or_hash, options)
|
170
|
+
polymorphic_url(record_or_hash, options.merge(action: action))
|
170
171
|
end
|
171
172
|
|
172
|
-
def
|
173
|
-
|
173
|
+
def polymorphic_path_for_action(action, record_or_hash, options)
|
174
|
+
polymorphic_path(record_or_hash, options.merge(action: action))
|
175
|
+
end
|
174
176
|
|
175
|
-
def
|
176
|
-
|
177
|
-
|
178
|
-
if action.to_s == 'new'
|
179
|
-
HelperMethodBuilder.singular prefix, suffix
|
177
|
+
def polymorphic_mapping(record)
|
178
|
+
if record.respond_to?(:to_model)
|
179
|
+
_routes.polymorphic_mappings[record.to_model.model_name.name]
|
180
180
|
else
|
181
|
-
|
181
|
+
_routes.polymorphic_mappings[record.class.name]
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
end
|
185
|
+
class HelperMethodBuilder # :nodoc:
|
186
|
+
CACHE = { path: {}, url: {} }
|
188
187
|
|
189
|
-
|
190
|
-
|
191
|
-
|
188
|
+
def self.get(action, type)
|
189
|
+
type = type.to_sym
|
190
|
+
CACHE[type].fetch(action) { build action, type }
|
191
|
+
end
|
192
192
|
|
193
|
-
|
194
|
-
|
193
|
+
def self.url; CACHE[:url][nil]; end
|
194
|
+
def self.path; CACHE[:path][nil]; end
|
195
195
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
if
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
recipient = record_or_hash_or_array.shift
|
196
|
+
def self.build(action, type)
|
197
|
+
prefix = action ? "#{action}_" : ""
|
198
|
+
suffix = type
|
199
|
+
if action.to_s == "new"
|
200
|
+
HelperMethodBuilder.singular prefix, suffix
|
201
|
+
else
|
202
|
+
HelperMethodBuilder.plural prefix, suffix
|
204
203
|
end
|
205
|
-
|
206
|
-
method, args = builder.handle_list record_or_hash_or_array
|
207
|
-
when String, Symbol
|
208
|
-
method, args = builder.handle_string record_or_hash_or_array
|
209
|
-
when Class
|
210
|
-
method, args = builder.handle_class record_or_hash_or_array
|
211
|
-
|
212
|
-
when nil
|
213
|
-
raise ArgumentError, "Nil location provided. Can't build URI."
|
214
|
-
else
|
215
|
-
method, args = builder.handle_model record_or_hash_or_array
|
216
204
|
end
|
217
205
|
|
218
|
-
|
219
|
-
|
220
|
-
recipient.send(method, *args)
|
221
|
-
else
|
222
|
-
recipient.send(method, *args, options)
|
206
|
+
def self.singular(prefix, suffix)
|
207
|
+
new(->(name) { name.singular_route_key }, prefix, suffix)
|
223
208
|
end
|
224
|
-
end
|
225
209
|
|
226
|
-
|
210
|
+
def self.plural(prefix, suffix)
|
211
|
+
new(->(name) { name.route_key }, prefix, suffix)
|
212
|
+
end
|
227
213
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
214
|
+
def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
|
215
|
+
builder = get action, type
|
216
|
+
|
217
|
+
case record_or_hash_or_array
|
218
|
+
when Array
|
219
|
+
record_or_hash_or_array = record_or_hash_or_array.compact
|
220
|
+
if record_or_hash_or_array.empty?
|
221
|
+
raise ArgumentError, "Nil location provided. Can't build URI."
|
222
|
+
end
|
223
|
+
if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
|
224
|
+
recipient = record_or_hash_or_array.shift
|
225
|
+
end
|
226
|
+
|
227
|
+
method, args = builder.handle_list record_or_hash_or_array
|
228
|
+
when String, Symbol
|
229
|
+
method, args = builder.handle_string record_or_hash_or_array
|
230
|
+
when Class
|
231
|
+
method, args = builder.handle_class record_or_hash_or_array
|
233
232
|
|
234
|
-
|
235
|
-
|
236
|
-
|
233
|
+
when nil
|
234
|
+
raise ArgumentError, "Nil location provided. Can't build URI."
|
235
|
+
else
|
236
|
+
method, args = builder.handle_model record_or_hash_or_array
|
237
|
+
end
|
237
238
|
|
238
|
-
|
239
|
-
|
240
|
-
|
239
|
+
if options.empty?
|
240
|
+
recipient.public_send(method, *args)
|
241
|
+
else
|
242
|
+
recipient.public_send(method, *args, options)
|
243
|
+
end
|
244
|
+
end
|
241
245
|
|
242
|
-
|
243
|
-
[get_method_for_class(klass), []]
|
244
|
-
end
|
246
|
+
attr_reader :suffix, :prefix
|
245
247
|
|
246
|
-
|
247
|
-
|
248
|
-
|
248
|
+
def initialize(key_strategy, prefix, suffix)
|
249
|
+
@key_strategy = key_strategy
|
250
|
+
@prefix = prefix
|
251
|
+
@suffix = suffix
|
252
|
+
end
|
249
253
|
|
250
|
-
|
251
|
-
|
254
|
+
def handle_string(record)
|
255
|
+
[get_method_for_string(record), []]
|
256
|
+
end
|
252
257
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
model.model_name.singular_route_key
|
257
|
-
else
|
258
|
-
@key_strategy.call model.model_name
|
259
|
-
end
|
258
|
+
def handle_string_call(target, str)
|
259
|
+
target.public_send get_method_for_string str
|
260
|
+
end
|
260
261
|
|
261
|
-
|
262
|
+
def handle_class(klass)
|
263
|
+
[get_method_for_class(klass), []]
|
264
|
+
end
|
262
265
|
|
263
|
-
|
264
|
-
|
266
|
+
def handle_class_call(target, klass)
|
267
|
+
target.public_send get_method_for_class klass
|
268
|
+
end
|
265
269
|
|
266
|
-
|
267
|
-
|
268
|
-
target.send(method, *args)
|
269
|
-
end
|
270
|
+
def handle_model(record)
|
271
|
+
args = []
|
270
272
|
|
271
|
-
|
272
|
-
|
273
|
-
|
273
|
+
model = record.to_model
|
274
|
+
named_route = if model.persisted?
|
275
|
+
args << model
|
276
|
+
get_method_for_string model.model_name.singular_route_key
|
277
|
+
else
|
278
|
+
get_method_for_class model
|
279
|
+
end
|
274
280
|
|
275
|
-
|
281
|
+
[named_route, args]
|
282
|
+
end
|
276
283
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
parent.to_s
|
281
|
-
when Class
|
282
|
-
args << parent
|
283
|
-
parent.model_name.singular_route_key
|
284
|
+
def handle_model_call(target, record)
|
285
|
+
if mapping = polymorphic_mapping(target, record)
|
286
|
+
mapping.call(target, [record], suffix == "path")
|
284
287
|
else
|
285
|
-
args
|
286
|
-
|
288
|
+
method, args = handle_model(record)
|
289
|
+
target.public_send(method, *args)
|
287
290
|
end
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
291
|
+
end
|
292
|
+
|
293
|
+
def handle_list(list)
|
294
|
+
record_list = list.dup
|
295
|
+
record = record_list.pop
|
296
|
+
|
297
|
+
args = []
|
298
|
+
|
299
|
+
route = record_list.map do |parent|
|
300
|
+
case parent
|
301
|
+
when Symbol
|
302
|
+
parent.to_s
|
303
|
+
when String
|
304
|
+
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
|
305
|
+
when Class
|
306
|
+
args << parent
|
307
|
+
parent.model_name.singular_route_key
|
308
|
+
else
|
309
|
+
args << parent.to_model
|
310
|
+
parent.to_model.model_name.singular_route_key
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
route <<
|
315
|
+
case record
|
316
|
+
when Symbol
|
317
|
+
record.to_s
|
318
|
+
when String
|
319
|
+
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
|
320
|
+
when Class
|
321
|
+
@key_strategy.call record.model_name
|
301
322
|
else
|
302
|
-
|
323
|
+
model = record.to_model
|
324
|
+
if model.persisted?
|
325
|
+
args << model
|
326
|
+
model.model_name.singular_route_key
|
327
|
+
else
|
328
|
+
@key_strategy.call model.model_name
|
329
|
+
end
|
303
330
|
end
|
304
|
-
end
|
305
331
|
|
306
|
-
|
332
|
+
route << suffix
|
307
333
|
|
308
|
-
|
309
|
-
|
310
|
-
|
334
|
+
named_route = prefix + route.join("_")
|
335
|
+
[named_route, args]
|
336
|
+
end
|
311
337
|
|
312
|
-
|
338
|
+
private
|
339
|
+
def polymorphic_mapping(target, record)
|
340
|
+
if record.respond_to?(:to_model)
|
341
|
+
target._routes.polymorphic_mappings[record.to_model.model_name.name]
|
342
|
+
else
|
343
|
+
target._routes.polymorphic_mappings[record.class.name]
|
344
|
+
end
|
345
|
+
end
|
313
346
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
347
|
+
def get_method_for_class(klass)
|
348
|
+
name = @key_strategy.call klass.model_name
|
349
|
+
get_method_for_string name
|
350
|
+
end
|
318
351
|
|
319
|
-
|
320
|
-
|
321
|
-
|
352
|
+
def get_method_for_string(str)
|
353
|
+
"#{prefix}#{str}_#{suffix}"
|
354
|
+
end
|
322
355
|
|
323
|
-
|
324
|
-
|
325
|
-
|
356
|
+
[nil, "new", "edit"].each do |action|
|
357
|
+
CACHE[:url][action] = build action, "url"
|
358
|
+
CACHE[:path][action] = build action, "path"
|
359
|
+
end
|
326
360
|
end
|
327
|
-
end
|
328
361
|
end
|
329
362
|
end
|
330
363
|
end
|