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:
parent
65ce3d1297
commit
ed3f042e99
11 changed files with 58 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
<%%= render 'form' %>
|
||||
|
||||
<%%= link_to 'Show', @<%= singular_name %> %> |
|
||||
<%%= link_to 'Back', <%= plural_name %>_path %>
|
||||
<%%= link_to 'Back', <%= index_helper %>_path %>
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
<%%= render 'form' %>
|
||||
|
||||
<%%= link_to 'Back', <%= plural_name %>_path %>
|
||||
<%%= link_to 'Back', <%= index_helper %>_path %>
|
||||
|
|
|
@ -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 %>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue