From 5dd3db86157ce2bd08c4ec07826d3aaf5c29f458 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 5 Jun 2007 19:10:59 +0000 Subject: Resources: url_for([parent, child]) generates /parents/1/children/2 for the nested resource. Likewise with the other simply helpful methods like form_for and link_to. Closes #6432. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6951 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/action_controller/polymorphic_routes.rb | 64 +++++++++++++--------- .../lib/action_controller/record_identifier.rb | 2 +- 2 files changed, 40 insertions(+), 26 deletions(-) (limited to 'actionpack/lib/action_controller') diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index c60b533205..6c21bc27c5 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -1,31 +1,29 @@ module ActionController module PolymorphicRoutes - def polymorphic_url(record_or_hash, options = {}) - record = extract_record(record_or_hash) - - case - when options[:action] == "new" - send( - action_prefix(options) + RecordIdentifier.singular_class_name(record) + routing_type(options) - ) - - when record.respond_to?(:new_record?) && record.new_record? - send( - action_prefix(options) + RecordIdentifier.plural_class_name(record) + routing_type(options) - ) - - else - send( - action_prefix(options) + RecordIdentifier.singular_class_name(record) + routing_type(options), record_or_hash - ) - end + def polymorphic_url(record_or_hash_or_array, options = {}) + record = extract_record(record_or_hash_or_array) + + args = [] + inflection = + case + when options[:action] == "new" + :singular + when record.respond_to?(:new_record?) && record.new_record? + :plural + else + args = [record_or_hash_or_array] + :singular + end + + named_route = build_named_route_call(record_or_hash_or_array, inflection, options) + send(named_route, *args) end - def polymorphic_path(record_or_hash) - polymorphic_url(record_or_hash, :routing_type => :path) + def polymorphic_path(record_or_hash_or_array) + polymorphic_url(record_or_hash_or_array, :routing_type => :path) end - %w( edit new formatted ).each do |action| + %w(edit new formatted).each do |action| module_eval <<-EOT, __FILE__, __LINE__ def #{action}_polymorphic_url(record_or_hash) polymorphic_url(record_or_hash, :action => "#{action}") @@ -44,11 +42,27 @@ module ActionController end def routing_type(options) - "_#{options[:routing_type] || "url"}" + "#{options[:routing_type] || "url"}" + end + + def build_named_route_call(records, inflection, options = {}) + records = Array.new([extract_record(records)]) unless records.is_a?(Array) + base_segment = "#{RecordIdentifier.send("#{inflection}_class_name", records.pop)}_" + + method_root = records.reverse.inject(base_segment) do |string, name| + segment = "#{RecordIdentifier.send("singular_class_name", name)}_" + segment << string + end + + action_prefix(options) + method_root + routing_type(options) end - def extract_record(record_or_hash) - record_or_hash.is_a?(Hash) ? record_or_hash[:id] : record_or_hash + def extract_record(record_or_hash_or_array) + case record_or_hash_or_array + when Array: record_or_hash_or_array.last + when Hash: record_or_hash_or_array[:id] + else record_or_hash_or_array + end end end end diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 1a60becff3..bdf2753a79 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -25,7 +25,7 @@ module ActionController # end # end # - # As the example above shows, you can stop caring to a large extend what the actual id of the post is. You just know + # As the example above shows, you can stop caring to a large extent what the actual id of the post is. You just know # that one is being assigned and that the subsequent calls in redirect_to and the RJS expect that same naming # convention and allows you to write less code if you follow it. module RecordIdentifier -- cgit v1.2.3