aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2014-05-08 18:42:30 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2014-05-12 15:54:45 -0700
commitcfdda38088c95194c3d8bb2fedb70bc06e8fe2e0 (patch)
treebe5464d2026b8eff8e441126790469adbd87deda /actionpack/lib/action_dispatch
parent965664008001bb78f0369e3eb2a267991d7b6a84 (diff)
downloadrails-cfdda38088c95194c3d8bb2fedb70bc06e8fe2e0.tar.gz
rails-cfdda38088c95194c3d8bb2fedb70bc06e8fe2e0.tar.bz2
rails-cfdda38088c95194c3d8bb2fedb70bc06e8fe2e0.zip
use the helper method builder to construct helper methods
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb163
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb6
2 files changed, 112 insertions, 57 deletions
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index 83b8c11e70..7afb2838e0 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -101,62 +101,42 @@ module ActionDispatch
# polymorphic_url(Comment) # same as comments_url()
#
def polymorphic_url(record_or_hash_or_array, options = {})
- recipient = self
-
- opts = options.except(:action, :routing_type)
-
- prefix = action_prefix options
- suffix = routing_type options
-
- if options[:action] == 'new'
- builder = HelperMethodBuilder.singular prefix, suffix
- else
- builder = HelperMethodBuilder.plural prefix, suffix
+ if Hash === record_or_hash_or_array
+ options = record_or_hash_or_array.dup.merge!(options)
+ record = options.delete :id
+ return polymorphic_url record, options
end
- case record_or_hash_or_array
- when Array
- if record_or_hash_or_array.empty? || record_or_hash_or_array.any?(&:nil?)
- raise ArgumentError, "Nil location provided. Can't build URI."
- end
- if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
- recipient = record_or_hash_or_array.shift
- end
-
- method, args = builder.handle_list record_or_hash_or_array
- when Hash
- unless record_or_hash_or_array[:id]
- raise ArgumentError, "Nil location provided. Can't build URI."
- end
-
- opts = record_or_hash_or_array.dup.merge!(opts)
- record = opts.delete(:id)
-
- method, args = builder.handle_model record
-
- when String, Symbol
- method, args = builder.handle_string record_or_hash_or_array
- when Class
- method, args = builder.handle_class record_or_hash_or_array
-
- when nil
- raise ArgumentError, "Nil location provided. Can't build URI."
- else
- method, args = builder.handle_model record_or_hash_or_array
- end
+ opts = options.dup
+ action = opts.delete :action
+ type = opts.delete(:routing_type) || :url
+ HelperMethodBuilder.polymorphic_method self,
+ record_or_hash_or_array,
+ action,
+ type,
+ opts
- if opts.empty?
- recipient.send(method, *args)
- else
- recipient.send(method, *args, opts)
- end
end
# Returns the path component of a URL for the given record. It uses
# <tt>polymorphic_url</tt> with <tt>routing_type: :path</tt>.
def polymorphic_path(record_or_hash_or_array, options = {})
- polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
+ if Hash === record_or_hash_or_array
+ options = record_or_hash_or_array.dup.merge!(options)
+ record = options.delete :id
+ return polymorphic_path record, options
+ end
+
+ opts = options.dup
+ action = opts.delete :action
+ type = :path
+
+ HelperMethodBuilder.polymorphic_method self,
+ record_or_hash_or_array,
+ action,
+ type,
+ opts
end
@@ -179,6 +159,26 @@ module ActionDispatch
private
class HelperMethodBuilder # :nodoc:
+ CACHE = { 'path' => {}, 'url' => {} }
+
+ def self.get(action, type)
+ type = type.to_s
+ CACHE[type].fetch(action) { build action, type }
+ end
+
+ def self.url; CACHE['url'.freeze][nil]; end
+ def self.path; CACHE['path'.freeze][nil]; end
+
+ def self.build(action, type)
+ prefix = action ? "#{action}_" : ""
+ suffix = type
+ if action.to_s == 'new'
+ HelperMethodBuilder.singular prefix, suffix
+ else
+ HelperMethodBuilder.plural prefix, suffix
+ end
+ end
+
def self.singular(prefix, suffix)
new(->(name) { name.singular_route_key }, prefix, suffix)
end
@@ -187,6 +187,38 @@ module ActionDispatch
new(->(name) { name.route_key }, prefix, suffix)
end
+ def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
+ builder = get action, type
+
+ case record_or_hash_or_array
+ when Array
+ if record_or_hash_or_array.empty? || record_or_hash_or_array.include?(nil)
+ raise ArgumentError, "Nil location provided. Can't build URI."
+ end
+ if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
+ recipient = record_or_hash_or_array.shift
+ end
+
+ method, args = builder.handle_list record_or_hash_or_array
+ when String, Symbol
+ method, args = builder.handle_string record_or_hash_or_array
+ when Class
+ method, args = builder.handle_class record_or_hash_or_array
+
+ when nil
+ raise ArgumentError, "Nil location provided. Can't build URI."
+ else
+ method, args = builder.handle_model record_or_hash_or_array
+ end
+
+
+ if options.empty?
+ recipient.send(method, *args)
+ else
+ recipient.send(method, *args, options)
+ end
+ end
+
attr_reader :suffix, :prefix
def initialize(key_strategy, prefix, suffix)
@@ -196,13 +228,19 @@ module ActionDispatch
end
def handle_string(record)
- method = prefix + "#{record}_#{suffix}"
- [method, []]
+ [get_method_for_string(record), []]
+ end
+
+ def handle_string_call(target, str)
+ target.send get_method_for_string str
end
def handle_class(klass)
- name = @key_strategy.call klass.model_name
- [prefix + "#{name}_#{suffix}", []]
+ [get_method_for_class(klass), []]
+ end
+
+ def handle_class_call(target, klass)
+ target.send get_method_for_class klass
end
def handle_model(record)
@@ -221,6 +259,11 @@ module ActionDispatch
[named_route, args]
end
+ def handle_model_call(target, model)
+ method, args = handle_model model
+ target.send(method, *args)
+ end
+
def handle_list(list)
record_list = list.dup
record = record_list.pop
@@ -260,15 +303,23 @@ module ActionDispatch
named_route = prefix + route.join("_")
[named_route, args]
end
- end
- def action_prefix(options)
- options[:action] ? "#{options[:action]}_" : ''
+ private
+
+ def get_method_for_class(klass)
+ name = @key_strategy.call klass.model_name
+ prefix + "#{name}_#{suffix}"
+ end
+
+ def get_method_for_string(str)
+ prefix + "#{str}_#{suffix}"
end
- def routing_type(options)
- options[:routing_type] || :url
+ [nil, 'new', 'edit'].each do |action|
+ CACHE['url'][action] = build action, 'url'
+ CACHE['path'][action] = build action, 'path'
end
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index 0976e46903..e624fe3c4a 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -155,10 +155,14 @@ module ActionDispatch
_routes.url_for(options.symbolize_keys.reverse_merge!(url_options))
when String
options
+ when Symbol
+ HelperMethodBuilder.url.handle_string_call self, options
when Array
polymorphic_url(options, options.extract_options!)
+ when Class
+ HelperMethodBuilder.url.handle_class_call self, options
else
- polymorphic_url(options, {})
+ HelperMethodBuilder.url.handle_model_call self, options
end
end