aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2007-05-12 21:12:31 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2007-05-12 21:12:31 +0000
commitc769ad85336713b7e5bdadd57d92a007783f8208 (patch)
treeecd60b6abc044f8eb80558a631edcf7f8662c406 /actionpack/lib
parent2ca6f57f85fe06932f64685bea2687fec7d6c3d3 (diff)
downloadrails-c769ad85336713b7e5bdadd57d92a007783f8208.tar.gz
rails-c769ad85336713b7e5bdadd57d92a007783f8208.tar.bz2
rails-c769ad85336713b7e5bdadd57d92a007783f8208.zip
Removed deprecated parameters_for_method_reference concept (legacy from before named routes) [DHH] Added record identification with polymorphic routes for ActionController::Base#url_for and ActionView::Base#url_for [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6729 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib')
-rwxr-xr-xactionpack/lib/action_controller.rb2
-rwxr-xr-xactionpack/lib/action_controller/base.rb14
-rw-r--r--actionpack/lib/action_controller/polymorphic_routes.rb52
-rw-r--r--actionpack/lib/action_controller/routing.rb2
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb50
5 files changed, 95 insertions, 25 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index 96192809e5..162669b79e 100755
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -82,4 +82,4 @@ ActionController::Base.class_eval do
include ActionController::RecordIdentifier
include ActionController::Macros::AutoComplete
include ActionController::Macros::InPlaceEditing
-end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index c1c9e57342..a9d502e6f1 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -560,7 +560,7 @@ module ActionController #:nodoc:
when Hash
@url.rewrite(rewrite_options(options))
else
- raise ArgumentError, "Unrecognized url_for options: #{options.inspect}"
+ polymorphic_url(options, self)
end
end
@@ -1015,7 +1015,7 @@ module ActionController #:nodoc:
# When using <tt>redirect_to :back</tt>, if there is no referrer,
# RedirectBackError will be raised. You may specify some fallback
# behavior for this case by rescueing RedirectBackError.
- def redirect_to(options = {}, *parameters_for_method_reference) #:doc:
+ def redirect_to(options = {}) #:doc:
case options
when %r{^\w+://.*}
raise DoubleRenderError if performed?
@@ -1031,14 +1031,8 @@ module ActionController #:nodoc:
request.env["HTTP_REFERER"] ? redirect_to(request.env["HTTP_REFERER"]) : raise(RedirectBackError)
else
- if parameters_for_method_reference.empty?
- redirect_to(url_for(options))
- response.redirected_to = options
- else
- # TOOD: Deprecate me!
- redirect_to(url_for(options, *parameters_for_method_reference))
- response.redirected_to, response.redirected_to_method_params = options, parameters_for_method_reference
- end
+ redirect_to(url_for(options))
+ response.redirected_to = options
end
end
diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb
new file mode 100644
index 0000000000..eeddc28d60
--- /dev/null
+++ b/actionpack/lib/action_controller/polymorphic_routes.rb
@@ -0,0 +1,52 @@
+module ActionController
+ module PolymorphicRoutes
+ extend self
+
+ def polymorphic_url(record_or_hash, url_writer, options = {})
+ record = extract_record(record_or_hash)
+
+ case
+ when options[:action] == "new"
+ url_writer.send(action_prefix(options) + RecordIdentifier.singular_class_name(record) + routing_type(options))
+
+ when record.respond_to?(:new_record?) && record.new_record?
+ url_writer.send(RecordIdentifier.plural_class_name(record) + routing_type(options))
+
+ else
+ url_writer.send(
+ action_prefix(options) + RecordIdentifier.singular_class_name(record) + routing_type(options), record_or_hash
+ )
+ end
+ end
+
+ def polymorphic_path(record_or_hash, url_writer)
+ polymorphic_url(record_or_hash, url_writer, :routing_type => :path)
+ end
+
+ %w( edit new formatted ).each do |action|
+ module_eval <<-EOT
+ def #{action}_polymorphic_url(record_or_hash, url_writer)
+ polymorphic_url(record_or_hash, url_writer, :action => "#{action}")
+ end
+
+ def #{action}_polymorphic_path(record_or_hash, url_writer)
+ polymorphic_url(record_or_hash, url_writer, :action => "#{action}", :routing_type => :path)
+ end
+ EOT
+ end
+
+
+ private
+ def action_prefix(options)
+ options[:action] ? "#{options[:action]}_" : ""
+ end
+
+ def routing_type(options)
+ "_#{options[:routing_type] || "url"}"
+ end
+
+ def extract_record(record_or_hash)
+ record_or_hash.is_a?(Hash) ? record_or_hash[:id] : record_or_hash
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb
index 9bbb51cfbf..49661850ea 100644
--- a/actionpack/lib/action_controller/routing.rb
+++ b/actionpack/lib/action_controller/routing.rb
@@ -1,5 +1,6 @@
require 'cgi'
require 'uri'
+require 'action_controller/polymorphic_routes'
class Object
def to_param
@@ -255,6 +256,7 @@ module ActionController
# A helper module to hold URL related helpers.
module Helpers
+ include PolymorphicRoutes
end
class << self
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index ca7e9872cc..2329fb4bc6 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -29,6 +29,13 @@ module ActionView
# * <tt>:password</tt> -- Inline HTTP authentication (only plucked out if :user is also present)
# * <tt>:escape</tt> -- Determines whether the returned URL will be HTML escaped or not (<tt>true</tt> by default)
#
+ # ==== Relying on named routes
+ #
+ # If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter,
+ # you'll trigger the named route for that record. The lookup will happen on the name of the class. So passing
+ # a Workshop object will attempt to use the workshop_path route. If you have a nested route, such as
+ # admin_workshop_path you'll have to call that explicitly (it's impossible for url_for to guess that route).
+ #
# ==== Examples
# <%= url_for(:action => 'index') %>
# # => /blog/
@@ -47,15 +54,30 @@ module ActionView
#
# <%= url_for(:action => 'checkout', :anchor => 'tax&ship', :escape => false) %>
# # => /testing/jump/#tax&ship
- def url_for(options = {}, *parameters_for_method_reference)
- if options.kind_of? Hash
+ #
+ # <%= url_for(Workshop.new) %>
+ # # relies on Workshop answering a new_record? call (and in this case returning true)
+ # # => /workshops
+ #
+ # <%= url_for(@workshop) %>
+ # # calls @workshop.to_s
+ # # => /workshops/5
+ def url_for(options = {})
+ case options
+ when Hash
options = { :only_path => true }.update(options.symbolize_keys)
- escape = options.key?(:escape) ? options.delete(:escape) : true
- else
+ escape = options.key?(:escape) ? options.delete(:escape) : true
+ url = @controller.send(:url_for, options)
+ when String
escape = true
+ url = options
+ when NilClass
+ url = @controller.send(:url_for, nil)
+ else
+ escape = false
+ url = polymorphic_path(options, self)
end
- url = @controller.send(:url_for, options, *parameters_for_method_reference)
escape ? html_escape(url) : url
end
@@ -104,7 +126,7 @@ module ActionView
# f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
# var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
# m.setAttribute('value', 'delete'); f.appendChild(m);f.submit(); };return false;">Delete Image</a>
- def link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
+ def link_to(name, options = {}, html_options = nil)
if html_options
html_options = html_options.stringify_keys
convert_options_to_javascript!(html_options)
@@ -113,7 +135,7 @@ module ActionView
tag_options = nil
end
- url = options.is_a?(String) ? options : self.url_for(options, *parameters_for_method_reference)
+ url = options.is_a?(String) ? options : self.url_for(options)
"<a href=\"#{url}\"#{tag_options}>#{name || url}</a>"
end
@@ -222,8 +244,8 @@ module ActionView
# link_to("Go back", { :controller => 'posts', :action => 'index' })
# end
# %>
- def link_to_unless_current(name, options = {}, html_options = {}, *parameters_for_method_reference, &block)
- link_to_unless current_page?(options), name, options, html_options, *parameters_for_method_reference, &block
+ def link_to_unless_current(name, options = {}, html_options = {}, &block)
+ link_to_unless current_page?(options), name, options, html_options, &block
end
# Creates a link tag of the given +name+ using a URL created by the set of
@@ -246,15 +268,15 @@ module ActionView
# # => <a href="/controller/reply/">Reply</a>
# # If not...
# # => <a href="/accounts/signup">Reply</a>
- def link_to_unless(condition, name, options = {}, html_options = {}, *parameters_for_method_reference, &block)
+ def link_to_unless(condition, name, options = {}, html_options = {}, &block)
if condition
if block_given?
- block.arity <= 1 ? yield(name) : yield(name, options, html_options, *parameters_for_method_reference)
+ block.arity <= 1 ? yield(name) : yield(name, options, html_options)
else
name
end
else
- link_to(name, options, html_options, *parameters_for_method_reference)
+ link_to(name, options, html_options)
end
end
@@ -278,8 +300,8 @@ module ActionView
# # => <a href="/sessions/new/">Login</a>
# # If they are logged in...
# # => <a href="/accounts/show/3">my_username</a>
- def link_to_if(condition, name, options = {}, html_options = {}, *parameters_for_method_reference, &block)
- link_to_unless !condition, name, options, html_options, *parameters_for_method_reference, &block
+ def link_to_if(condition, name, options = {}, html_options = {}, &block)
+ link_to_unless !condition, name, options, html_options, &block
end
# Creates a mailto link tag to the specified +email_address+, which is