在 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"]