Add _is_first and _is_last to partial rendered by collection #5634

Closed
wants to merge 2 commits into from
View
20 actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -340,7 +340,7 @@ def setup(context, options, block)
end
if @path
- @variable, @variable_counter = retrieve_variable(@path)
+ @variable, @variable_counter, @variable_is_first, @variable_is_last = retrieve_variable(@path)
else
paths.map! { |path| retrieve_variable(path).unshift(path) }
end
@@ -371,7 +371,11 @@ def find_partial
if path = @path
locals = @locals.keys
locals << @variable
- locals << @variable_counter if @collection
+ if @collection
+ locals << @variable_counter
+ locals << @variable_is_first
+ locals << @variable_is_last
+ end
find_template(path, locals)
end
end
@@ -383,12 +387,14 @@ def find_template(path=@path, locals=@locals.keys)
def collection_with_template
segments, locals, template = [], @locals, @template
- as, counter = @variable, @variable_counter
+ as, counter, is_first, is_last = @variable, @variable_counter, @variable_is_first, @variable_is_last
locals[counter] = -1
@collection.each do |object|
locals[counter] += 1
+ locals[is_first] = locals[counter] == 0
+ locals[is_last] = locals[counter] == @collection.size-1
locals[as] = object
segments << template.render(@view, locals)
end
@@ -445,8 +451,12 @@ def merge_prefix_into_object_path(prefix, object_path)
def retrieve_variable(path)
variable = @options[:as].try(:to_sym) || path[%r'_?(\w+)(\.\w+)*$', 1].to_sym
- variable_counter = :"#{variable}_counter" if @collection
- [variable, variable_counter]
+ if @collection
+ variable_counter = :"#{variable}_counter"
+ variable_is_first = :"#{variable}_is_first"
+ variable_is_last = :"#{variable}_is_last"
+ end
+ [variable, variable_counter, variable_is_first, variable_is_last]
end
end
end
View
4 actionpack/test/controller/render_test.rb
@@ -612,6 +612,10 @@ def partial_collection_with_as_and_counter
render :partial => "customer_counter_with_as", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :client
end
+ def partial_collection_with_first_and_last
+ render :partial => "customer_first_last", :collection => [ Customer.new("david"), Customer.new("mary"), Customer.new("joseph") ]
+ end
+
def partial_collection_with_locals
render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
end
View
1 actionpack/test/fixtures/test/_customer_first_last.erb
@@ -0,0 +1 @@
+<%= customer_first_last.name %><%= customer_first_last_is_first %><%= customer_first_last_is_last %>
View
7 actionpack/test/template/render_test.rb
@@ -223,10 +223,15 @@ def test_render_partial_collection_as_by_symbol
end
def test_render_partial_collection_without_as
- assert_equal "local_inspector,local_inspector_counter",
+ assert_equal "local_inspector,local_inspector_counter,local_inspector_is_first,local_inspector_is_last",
@view.render(:partial => "test/local_inspector", :collection => [ Customer.new("mary") ])
end
+ def test_render_partial_collection_with_first_and_last
+ assert_equal "davidtruefalsemaryfalsefalsejosephfalsetrue",
+ @view.render(:partial => "test/customer_first_last", :collection => [ Customer.new("david"), Customer.new("mary"), Customer.new("joseph") ])
+ end
+
def test_render_partial_with_empty_collection_should_return_nil
assert_nil @view.render(:partial => "test/customer", :collection => [])
end