Rails 5.1 多种货币的不同总和计算

Rails 5.1 different sum calculation with multiple currencies

我正在开发一个 Rails 应用程序来支付我的费用。
基本上我输入一些费用,给出名称、描述、金额、货币和日期。
为此,我有 3 个模型:用户、支出、货币与此关系:

class Currency < ApplicationRecord

    has_many :spendings
    has_many :users, through: :spendings

end

class Spending < ApplicationRecord

    belongs_to :user
    belongs_to :currency

end

class User < ApplicationRecord

  has_many :spendings
  has_many :currencies, through: :spendings

end

我正在使用 users_controller 中的节目来索引每个用户的费用。这就是我 users_controller

中的内容
class UsersController < ApplicationController

    def show
        @user_spendings = @current_user.spendings.all.order('date DESC').paginate(:page => params[:page], :per_page => 10)
        @user_amount = @user_spendings.sum(:amount)
    end
end

在这种情况下,@user_amount 显示了 current_user 的所有费用,问题是我有 2 种货币(将来可能更多),我想显示不同的总金额取决于我在创建新费用时选择的货币。
我在这里考虑了不同的事情,我尝试做一个 If 语句,以便仅当 currency_id == 为 1 if € 或 2 if $ 等时才显示金额......但是如果我添加,这将无法正常工作新货币(我无法让它工作)。
也许是一个循环?遍历货币并以某种方式显示总金额。但是你不能在循环中求和,所以我不知道。
此外,我希望它具有灵活性,因此如果将来我添加更多货币,我不必触及代码。
有什么想法吗?
如果需要,这里是我的 show.html.erb

  <% @user_spendings.each do |spending| %>
  <tr>
    <td><%= spending.title %></td>
    <td><%= spending.description %></td>
    <td><%= '%.02f' % spending.amount %></td>
    <td><%= spending.currency.symb %></td>
    <td><%= spending.date.strftime('%d %B %Y') %></td>
  </tr>
  <% end %>

非常感谢。

如果您已经设置了表之间的关系,您实际上可以访问 belongs_to Currency 的所有 Spendings,方法是执行以下操作

Currency.all.each do |c|
  c.spendings.sum(&:amount)
end

或者对于每一种货币,您都可以这样做:

Currency.first.spendings.all

先查看上的所有费用Currency

Currency.first.spendings.sum(&:amount)

首先查看Currency

的所有费用总和

当然,对于具有 has_many - belongs_to 关系

的所有其他模型也可以这样做

按照以下方式做一些事情:

@sums_by_currency = Currency.joins(:spendings).
  select(:symb, 'SUM(spendings.amount) AS amount').
  where(spendings: { id: @user_spendings.map(&:id) }).
  group(:symb)

将允许您迭代货币,如:

@sums_by_currency.each do |currency|
  "#{currency.symb}#{currency.amount}"
end

@sums_by_currency.each do |currency|
  number_to_currency(currency.amount, unit: currency.symb)
end

在你看来。

我知道还有其他答案,但这是我的方法。

控制器

class UsersController < ApplicationController

  def show
    @user = current_user
    @spendings = @user.spendings
    @currencies = @user.currencies
  end

end

型号

class Currency < ApplicationRecord

  has_many :spendings
  has_many :users, through: :spendings

  def user_spendings user
    spendings.where(user_id: user.id)
  end

  def total_user_spendings user
    user_spendings(user).sum(:amount)
  end

end

查看

<h2>Spendings summary by currency</h2>
<table>
  <% @currencies.each do |currency| %>
    <tr>
      <td><%= currency.symb %></td>
      <td><%= currency.name %></td>
      <td><%= '%.02f' % currency.total_user_spendings @user %></td>
    </tr>
  <% end %>
</table>

<h2>Detailed spendings</h2>
<table>
  <% @spendings.each do |spending| %>
    <tr>
      <td><%= spending.title %></td>
      <td><%= spending.description %></td>
      <td><%= '%.02f' % spending.amount %></td>
      <td><%= spending.currency.symb %></td>
      <td><%= spending.date.strftime('%d %B %Y') %></td>
    </tr>
  <% end %>
</table>