I have the following requirement.
Ex: There is a transaction table where it has columns say, transaction_name and amount. I want to loop through the transactions and display their details (transaction_name and amount) and finally I want to display the total amount (sum of all the amounts) in th开发者_StackOverflow社区e head (before the loop) section of my page. (Think about it as a summary display)
Example page structure would be like
Sum of all the transactions - 200
transaction amount trn1 100 trn2 50 trn3 50
And I tried to use yield and content_for tag but no luck.
my code is as follows (i'm calling inside my erb file.)
<%= yield :transaction_summary %>
<table>
<% total_amount = 0%>
<%for transaction in @transactions%>
<tr>
<td><%= transaction.transaction_name %></td>
<td><%= transaction.amount %></td>
<% total_amount += transaction.amount %>
</tr>
<%end%>
</table>
<% content_for :transaction_summary do %>
<h1>
Sum of all the transactions - <%= total_amount %>
</h1>
<% end %>
And
I'm using with inside a view (not inside a layout)
I'm using rails 2.2.2
Please help me and let me know if there is a better way
thanks in advance
cheers
sameera
EDIT:
Actually what I want to do is , Display some details before a particular loop where those details can be collected after the loop
Ex: If i have an array of transaction objects, I want to show a count of pass and failed transactions before the transactions loop in my view
thanks
In other cases where you really need to reuse content_for, the following may be useful.
In Rails 4, you can pass :flush => true
as an option to content_for:
<% content_for :example, flush: true do %>
<h1>Deletes previous content</h1>
<% end %>
In Rails 3.1.1 (approx) you can delete the content from the view_flow when you yield by defining and using the following (eg in application_helper):
def yield_and_flush!(content_key)
view_flow.content.delete(content_key)
end
I think you have the wrong idea about content_for and yield. :) http://guides.rubyonrails.org/layouts_and_rendering.html
<h1>
<%= @transactions.collect(&:amount).sum -%>
</h1>
<table>
<%for transaction in @transactions%>
<tr>
<td><%= transaction.transaction_name %></td>
<td><%= transaction.amount %></td>
</tr>
<%end%>
</table>
edit -
Regarding collecting data, I suggest you put them in helper methods:
#transactions_helper.rb
def transactions_total transactions
@transactions_total ||= @transactions.collect(&:amount).sum
end
def passed_transactions transactions
@passed_transactions ||= @transactions.collect{|transaction| transaction.passed == true}
end
def failed_transactions transactions
@failed_transactions ||= transactions - passed_transactions(transactions)
end
Just noticed your comment to theTRON. The whole dry principle doesn't really apply to executing tiny logic such as looping through a array.
I would write a helper method which calculates the total separately, perhaps something along the lines of:
# app/helpers/transactions_helper.rb
def calculate_total(transactions)
total = 0
transactions.each {|transaction| total += transaction.amount}
total
end
Then you can display it in your view wherever you like, with:
<%= calculate_total(@transactions) %>
In Rails 3 you can yield after content_for; so your code will become:
<% content_for :transaction_table do %>
<table>
<% total_amount = 0%>
<% for transaction in @transactions do %>
<tr>
<td><%= transaction.transaction_name %></td>
<td><%= transaction.amount %></td>
<% total_amount += transaction.amount %>
</tr>
<%end%>
</table>
<% content_for :transaction_summary do %>
<h1>
Sum of all the transactions - <%= total_amount %>
</h1>
<% end %>
<% end %> <!- End content_for :transaction_table -->
<%= yield :transaction_summary %>
<%= yield :transaction_table %>
Note:
<% content_for :transaction_summary do %>
doesn't have to be inside of
<% content_for :transaction_table do %>
, but for some more complex cases it could.
精彩评论