Module: ActionDispatch::Routing::PolymorphicRoutes
- Included in:
- Helpers, 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"
Using with mounted engines
If you use mounted engine, there is a possibility that you will need to use polymorphic_url pointing at engine’s routes. To do that, just pass proxy used to reach engine’s routes as a first argument:
For example:
polymorphic_url([blog, @post]) # it will call 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.
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
.
134 135 136 |
# File 'actionpack/lib/action_dispatch/routing/polymorphic_routes.rb', line 134 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
.
Examples
# 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()
90 91 92 93 94 95 96 97 98 99 100 101 102 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 |
# File 'actionpack/lib/action_dispatch/routing/polymorphic_routes.rb', line 90 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 |