Module: ActionDispatch::Routing::PolymorphicRoutes
- Includes:
- ActionController::ModelNaming
- Included in:
- UrlFor, ActionView::TestCase::Behavior
- Defined in:
- actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
Overview
Polymorphic URL helpers are methods for smart resolution to a named route call when given an Active Record model instance. They are to be used in combination with ActionController::Resources.
These methods are useful when you want to generate correct URL or path to a RESTful resource without having to know the exact type of the record in question.
Nested resources and/or namespaces are also supported, as illustrated in the example:
polymorphic_url([:admin, @article, @comment])
results in:
admin_article_comment_url(@article, @comment)
Usage within the framework
Polymorphic URL helpers are used in a number of places throughout the Rails framework:
-
url_for
, so you can use it with a record as the argument, e.g.url_for(@article)
; -
ActionView::Helpers::FormHelper uses
polymorphic_path
, so you can writeform_for(@article)
without having to specify:url
parameter for the form action; -
redirect_to
(which, in fact, usesurl_for
) so you can writeredirect_to(post)
in your controllers; -
ActionView::Helpers::AtomFeedHelper, so you don’t have to explicitly specify URLs for feed entries.
Prefixed polymorphic helpers
In addition to polymorphic_url
and polymorphic_path
methods, a number of prefixed helpers are available as a shorthand to action: "..."
in options. Those are:
-
edit_polymorphic_url
,edit_polymorphic_path
-
new_polymorphic_url
,new_polymorphic_path
Example usage:
edit_polymorphic_path(@post) # => "/posts/1/edit"
polymorphic_path(@post, format: :pdf) # => "/posts/1.pdf"
Usage with mounted engines
If you are using a mounted engine and you need to use a polymorphic_url pointing at the engine’s routes, pass in the engine’s route proxy as the first argument to the method. For example:
polymorphic_url([blog, @post]) # calls blog.post_path(@post)
form_for([blog, @post]) # => "/blog/posts/1"
Instance Method Summary collapse
-
#polymorphic_path(record_or_hash_or_array, options = {}) ⇒ Object
Returns the path component of a URL for the given record.
-
#polymorphic_url(record_or_hash_or_array, options = {}) ⇒ Object
Constructs a call to a named RESTful route for the given record and returns the resulting URL string.
Methods included from ActionController::ModelNaming
#convert_to_model, #model_name_from_record_or_class
Instance Method Details
#polymorphic_path(record_or_hash_or_array, options = {}) ⇒ Object
Returns the path component of a URL for the given record. It uses polymorphic_url
with routing_type: :path
.
147 148 149 |
# File 'actionpack/lib/action_dispatch/routing/polymorphic_routes.rb', line 147 def polymorphic_path(record_or_hash_or_array, = {}) polymorphic_url(record_or_hash_or_array, .merge(:routing_type => :path)) end |
#polymorphic_url(record_or_hash_or_array, options = {}) ⇒ Object
Constructs a call to a named RESTful route for the given record and returns the resulting URL string. For example:
# calls post_url(post)
polymorphic_url(post) # => "http://example.com/posts/1"
polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
polymorphic_url(Comment) # => "http://example.com/comments"
Options
-
:action
- Specifies the action prefix for the named route::new
or:edit
. Default is no prefix. -
:routing_type
- Allowed values are:path
or:url
. Default is:url
.
Also includes all the options from url_for
. These include such things as :anchor
or :trailing_slash
. Example usage is given below:
polymorphic_url([blog, post], anchor: 'my_anchor')
# => "http://example.com/blogs/1/posts/1#my_anchor"
polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
# => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
For all of these options, see the documentation for url_for
.
Functionality
# an Article record
polymorphic_url(record) # same as article_url(record)
# a Comment record
polymorphic_url(record) # same as comment_url(record)
# it recognizes new records and maps to the collection
record = Comment.new
polymorphic_url(record) # same as comments_url()
# the class of a record will also map to the collection
polymorphic_url(Comment) # same as comments_url()
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'actionpack/lib/action_dispatch/routing/polymorphic_routes.rb', line 103 def polymorphic_url(record_or_hash_or_array, = {}) if record_or_hash_or_array.kind_of?(Array) record_or_hash_or_array = record_or_hash_or_array.compact if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy) proxy = record_or_hash_or_array.shift end record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1 end record = extract_record(record_or_hash_or_array) record = convert_to_model(record) args = Array === record_or_hash_or_array ? record_or_hash_or_array.dup : [ record_or_hash_or_array ] inflection = if [:action] && [:action].to_s == "new" args.pop :singular elsif (record.respond_to?(:persisted?) && !record.persisted?) args.pop :plural elsif record.is_a?(Class) args.pop :plural else :singular end args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)} named_route = build_named_route_call(record_or_hash_or_array, inflection, ) = .except(:action, :routing_type) unless .empty? args.last.kind_of?(Hash) ? args.last.merge!() : args << end args.collect! { |a| convert_to_model(a) } (proxy || self).send(named_route, *args) end |