1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Make polymorphic_url and scaffolding work with uncountable resources [#3930 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
This commit is contained in:
Andrew White 2010-06-19 22:35:54 +01:00 committed by José Valim
parent 65ce3d1297
commit ed3f042e99
11 changed files with 58 additions and 11 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -3,4 +3,4 @@
<%%= render 'form' %>
<%%= link_to 'Show', @<%= singular_name %> %> |
<%%= link_to 'Back', <%= plural_name %>_path %>
<%%= link_to 'Back', <%= index_helper %>_path %>

View file

@ -2,4 +2,4 @@
<%%= render 'form' %>
<%%= link_to 'Back', <%= plural_name %>_path %>
<%%= link_to 'Back', <%= index_helper %>_path %>

View file

@ -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 %>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)