在 rails 上从下到上计算并显示 ruby 中的余额
Calculate and display the balances from bottom to top in ruby on rails
为了按降序显示记录,我使用了“created_at DESC”,它适用于 table 的所有条目,即日期列、详细信息列、借方和 Credit 列,但 Balance 仍然从上到下计算和显示。但是我想从下往上计算显示。这可以在下图中看到。
expenses_controller.rb
class ExpensesController < ApplicationController
def index
@expenses = Expense.order("created_at DESC")
end
为了更好地理解,请找到银行对帐单的下图,因为我需要实现相同的效果。
index.html.erb
<% balance = 0 %>
<div class="container">
<table style="width:100%">
<thead>
<tr>
<th>Date</th>
<th>Particulars</th>
<th>Debit</th>
<th>Credit</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<% @expenses.each do |expense| %>
<tr>
<td><%= expense.date.strftime('%d/%m/%Y') %></td>
<td><%= expense.particulars %></td>
<td class="pos"><%= expense.debit %></td>
<td class="neg"><%= expense.credit %></td>
<% balance += expense.debit.to_f-expense.credit.to_f %>
<% color = balance >= 0 ? "pos" : "neg" %>
<td class="<%= color %>"><%= number_with_precision(balance.abs, :delimiter => ",", :precision => 0) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
欢迎提出任何建议。
提前致谢。
既然你告诉它按 Expense.order('created_at desc')
订购,那么它就是这样做的。如果您想按余额排序,则必须改为说 Expense.order('balance desc')
如果您需要先按创建日期再按余额排序,您可以使用
@expenses = Expense.order('created_at DESC, balance DESC')
我仍然不明白余额列 [2500, 1500, 2000]
是如何计算的,但我可以从屏幕截图中得出一些结论。
基本上您是按模型中不存在的列排序。因此,首先您需要构建该辅助列,填充它,然后按该列排序。
应该可以在 SQL 中执行此操作,但我在 Ruby 中使用哈希作为假数据库显示。您可以根据自己的情况轻松调整它或寻找最有效的方法 (SQL)。
假设数据如下:
expenses = [{date: 1, narration: :a, debit: 3.0, credit: 0},
{date: 2, narration: :b, debit: 0.15, credit: 0},
{date: 3, narration: :c, debit: 75.0, credit: 0}]
初始余额为:
balance = 1434.64
现在让我们循环数据添加新字段 balance
并在循环结束时排序:
expenses.each do |h|
balance += h[:credit] - h[:debit]
h[:balance] = balance
end.sort!{ |h| h[:balance]}
现在你排序的 expenses
是:
[
{:date=>3, :narration=>:a, :debit=>75.0, :credit=>0, :balance=>1356.49}
{:date=>2, :narration=>:b, :debit=>0.15, :credit=>0, :balance=>1431.49}
{:date=>1, :narration=>:c, :debit=>3.0, :credit=>0, :balance=>1431.64}
]
您可以在控制器中进行计算,然后将 expenses
传递给视图并循环,而无需在那里进行任何计算。
对于您的 rails 应用程序,您可以按如下方式实施。
将临时字段 balance
添加到您的模型(无需向数据库添加列)并初始化为值 0
:
class Expense < ApplicationRecord
attr_accessor :balance
after_initialize :init
def init
self.balance = 0
end
end
在控制器中进行计算,我使用初始值balance
,只是为了模拟示例:
def index
@expenses = Expense.all
balance = 1434.64
@expenses.each do |e|
balance += e.credit - e.debit
e.balance = balance
end
@expenses = @expenses.sort{ |e| e.balance }
end
那么在你看来,就是循环:
<% @expenses.each do |expense| %>
<tr>
<td><%= expense.narration %></td>
<td><%= expense.debit %></td>
<td><%= expense.credit %></td>
<td><%= expense.balance %></td>
</tr>
<% end %>
如果您像示例中那样插入记录,您应该得到以下结果:
# ["c", "0.0", "75.0", "1356.49"]
# ["b", "0.0", "0.15", "1431.49"]
# ["a", "0.0", "3.0", "1431.64"]
为了按降序显示记录,我使用了“created_at DESC”,它适用于 table 的所有条目,即日期列、详细信息列、借方和 Credit 列,但 Balance 仍然从上到下计算和显示。但是我想从下往上计算显示。这可以在下图中看到。
expenses_controller.rb
class ExpensesController < ApplicationController
def index
@expenses = Expense.order("created_at DESC")
end
为了更好地理解,请找到银行对帐单的下图,因为我需要实现相同的效果。
index.html.erb
<% balance = 0 %>
<div class="container">
<table style="width:100%">
<thead>
<tr>
<th>Date</th>
<th>Particulars</th>
<th>Debit</th>
<th>Credit</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<% @expenses.each do |expense| %>
<tr>
<td><%= expense.date.strftime('%d/%m/%Y') %></td>
<td><%= expense.particulars %></td>
<td class="pos"><%= expense.debit %></td>
<td class="neg"><%= expense.credit %></td>
<% balance += expense.debit.to_f-expense.credit.to_f %>
<% color = balance >= 0 ? "pos" : "neg" %>
<td class="<%= color %>"><%= number_with_precision(balance.abs, :delimiter => ",", :precision => 0) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
欢迎提出任何建议。
提前致谢。
既然你告诉它按 Expense.order('created_at desc')
订购,那么它就是这样做的。如果您想按余额排序,则必须改为说 Expense.order('balance desc')
如果您需要先按创建日期再按余额排序,您可以使用
@expenses = Expense.order('created_at DESC, balance DESC')
我仍然不明白余额列 [2500, 1500, 2000]
是如何计算的,但我可以从屏幕截图中得出一些结论。
基本上您是按模型中不存在的列排序。因此,首先您需要构建该辅助列,填充它,然后按该列排序。 应该可以在 SQL 中执行此操作,但我在 Ruby 中使用哈希作为假数据库显示。您可以根据自己的情况轻松调整它或寻找最有效的方法 (SQL)。
假设数据如下:
expenses = [{date: 1, narration: :a, debit: 3.0, credit: 0},
{date: 2, narration: :b, debit: 0.15, credit: 0},
{date: 3, narration: :c, debit: 75.0, credit: 0}]
初始余额为:
balance = 1434.64
现在让我们循环数据添加新字段 balance
并在循环结束时排序:
expenses.each do |h|
balance += h[:credit] - h[:debit]
h[:balance] = balance
end.sort!{ |h| h[:balance]}
现在你排序的 expenses
是:
[
{:date=>3, :narration=>:a, :debit=>75.0, :credit=>0, :balance=>1356.49}
{:date=>2, :narration=>:b, :debit=>0.15, :credit=>0, :balance=>1431.49}
{:date=>1, :narration=>:c, :debit=>3.0, :credit=>0, :balance=>1431.64}
]
您可以在控制器中进行计算,然后将 expenses
传递给视图并循环,而无需在那里进行任何计算。
对于您的 rails 应用程序,您可以按如下方式实施。
将临时字段 balance
添加到您的模型(无需向数据库添加列)并初始化为值 0
:
class Expense < ApplicationRecord
attr_accessor :balance
after_initialize :init
def init
self.balance = 0
end
end
在控制器中进行计算,我使用初始值balance
,只是为了模拟示例:
def index
@expenses = Expense.all
balance = 1434.64
@expenses.each do |e|
balance += e.credit - e.debit
e.balance = balance
end
@expenses = @expenses.sort{ |e| e.balance }
end
那么在你看来,就是循环:
<% @expenses.each do |expense| %>
<tr>
<td><%= expense.narration %></td>
<td><%= expense.debit %></td>
<td><%= expense.credit %></td>
<td><%= expense.balance %></td>
</tr>
<% end %>
如果您像示例中那样插入记录,您应该得到以下结果:
# ["c", "0.0", "75.0", "1356.49"]
# ["b", "0.0", "0.15", "1431.49"]
# ["a", "0.0", "3.0", "1431.64"]