From 89f6114a7f6da3f292d7ffe69188227899adb976 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sat, 19 Jun 2010 22:35:54 +0100 Subject: [PATCH] Make polymorphic_url and scaffolding work with uncountable resources --- .../lib/action_controller/polymorphic_routes.rb | 3 +- .../lib/action_controller/record_identifier.rb | 14 +++++++++-- .../test/activerecord/polymorphic_routes_test.rb | 1 + .../test/controller/record_identifier_test.rb | 23 ++++++++++++++++++- .../erb/scaffold/templates/edit.html.erb | 2 +- .../generators/erb/scaffold/templates/new.html.erb | 2 +- .../erb/scaffold/templates/show.html.erb | 2 +- railties/lib/rails/generators/named_base.rb | 8 +++++++ .../scaffold_controller/templates/controller.rb | 2 +- .../scaffold/templates/functional_test.rb | 2 +- railties/test/generators/named_base_test.rb | 10 ++++++++ 11 files changed, 58 insertions(+), 11 deletions(-) diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index 7f2eb43..bee50a7 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -11,7 +11,7 @@ module ActionController # polymorphic_url([:admin, @article, @comment]) # # results in: - # + # # admin_article_comment_url(@article, @comment) # # == Usage within the framework @@ -166,6 +166,7 @@ module ActionController route << RecordIdentifier.__send__("plural_class_name", record) route = route.singularize if inflection == :singular route << "_" + route << "index_" if RecordIdentifier.uncountable?(record) && inflection == :plural end action_prefix(options) + route + routing_type(options).to_s diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 907c369..d20c3b6 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -1,7 +1,7 @@ require 'active_support/core_ext/module' module ActionController - # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or + # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or # Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate # the view actions to a higher logical level. Example: # @@ -28,7 +28,7 @@ module ActionController # end # # 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 + # 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 extend self @@ -59,7 +59,7 @@ module ActionController # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id: # # dom_id(Post.find(45), :edit) # => "edit_post_45" - def dom_id(record, prefix = nil) + def dom_id(record, prefix = nil) if record_id = record_key_for_dom_id(record) "#{dom_class(record, prefix)}#{JOIN}#{record_id}" else @@ -102,6 +102,14 @@ module ActionController model_name_from_record_or_class(record_or_class).singular end + # Identifies whether the class name of a record or class is uncountable. Examples: + # + # uncountable?(Sheep) # => true + # uncountable?(Post) => false + def uncountable?(record_or_class) + plural_class_name(record_or_class) == singular_class_name(record_or_class) + end + private def model_name_from_record_or_class(record_or_class) (record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index 9f5e8ec..6e1e6cd 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -381,6 +381,7 @@ class PolymorphicRoutesTest < ActionController::TestCase with_test_routes do @series.save assert_equal "http://example.com/series/#{@series.id}", polymorphic_url(@series) + assert_equal "http://example.com/series", polymorphic_url(Series.new) end end diff --git a/actionpack/test/controller/record_identifier_test.rb b/actionpack/test/controller/record_identifier_test.rb index 813dedc..6a84475 100644 --- a/actionpack/test/controller/record_identifier_test.rb +++ b/actionpack/test/controller/record_identifier_test.rb @@ -13,6 +13,19 @@ class Comment end end +class Sheep + extend ActiveModel::Naming + include ActiveModel::Conversion + + attr_reader :id + def to_key; id ? [id] : nil end + def save; @id = 1 end + def new_record?; @id.nil? end + def name + @id.nil? ? 'new sheep' : "sheep ##{@id}" + end +end + class Comment::Nested < Comment; end class Test::Unit::TestCase @@ -20,7 +33,7 @@ class Test::Unit::TestCase def comments_url 'http://www.example.com/comments' end - + def comment_url(comment) "http://www.example.com/comments/#{comment.id}" end @@ -35,6 +48,7 @@ class RecordIdentifierTest < Test::Unit::TestCase @record = @klass.new @singular = 'comment' @plural = 'comments' + @uncountable = Sheep end def test_dom_id_with_new_record @@ -58,7 +72,7 @@ class RecordIdentifierTest < Test::Unit::TestCase def test_dom_class assert_equal @singular, dom_class(@record) end - + def test_dom_class_with_prefix assert_equal "custom_prefix_#{@singular}", dom_class(@record, :custom_prefix) end @@ -79,6 +93,11 @@ class RecordIdentifierTest < Test::Unit::TestCase assert_equal @plural, plural_class_name(@klass) end + def test_uncountable + assert_equal true, uncountable?(@uncountable) + assert_equal false, uncountable?(@klass) + end + private def method_missing(method, *args) RecordIdentifier.send(method, *args) diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb index 5bc507f..415f820 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb @@ -3,4 +3,4 @@ <%%= render 'form' %> <%%= link_to 'Show', @<%= singular_name %> %> | -<%%= link_to 'Back', <%= plural_name %>_path %> +<%%= link_to 'Back', <%= index_helper %>_path %> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb index 9a1c489..ddabc9d 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb @@ -2,4 +2,4 @@ <%%= render 'form' %> -<%%= link_to 'Back', <%= plural_name %>_path %> +<%%= link_to 'Back', <%= index_helper %>_path %> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb index 6b35187..31b8253 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb @@ -9,4 +9,4 @@ <% end -%> <%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> | -<%%= link_to 'Back', <%= plural_name %>_path %> +<%%= link_to 'Back', <%= index_helper %>_path %> diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 8d1dfbd..72ec285 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -46,6 +46,14 @@ module Rails end end + def uncountable? + singular_name == plural_name + end + + def index_helper + uncountable? ? "#{plural_name}_index" : plural_name + end + # Tries to retrieve the application name or simple return application. def application_name if defined?(Rails) && Rails.application diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb index bbdce66..b5f19b6 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb @@ -78,7 +78,7 @@ class <%= controller_class_name %>Controller < ApplicationController @<%= orm_instance.destroy %> respond_to do |format| - format.html { redirect_to(<%= table_name %>_url) } + format.html { redirect_to(<%= index_helper %>_url) } format.xml { head :ok } end end diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb index 4f8ddbf..d5d3d6d 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb @@ -46,6 +46,6 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase delete :destroy, :id => @<%= file_name %>.to_param end - assert_redirected_to <%= table_name %>_path + assert_redirected_to <%= index_helper %>_path end end diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index e73dd23..1badae0 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -93,6 +93,16 @@ class NamedBaseTest < Rails::Generators::TestCase assert_name g, "application", :application_name end + def test_index_helper + g = generator ['Post'] + assert_name g, 'posts', :index_helper + end + + def test_index_helper_with_uncountable + g = generator ['Sheep'] + assert_name g, 'sheep_index', :index_helper + end + protected def assert_name(generator, value, method) -- 1.7.1