I'm working on a Rails app for my expenses.
Basically I enter some expenses giving a name, description, amount, currency and a date.
For this I have 3 models : User, Spending, Currency with this relations :
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
I'm using the show from the users_controller to index each user expenses. This is what I have in my 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
In this scenario the @user_amount shows me all the expenses from the current_user, the thing is that I have 2 currencies (maybe more in the future) and I would like to show different total amount depending on which currency has been selected when I create a new expense.
I thought about different things here, I tried to do a If statement so that the amount shows only if the currency_id == to 1 if € or to 2 if $ etc... But this wont work well if I add new currencies (and I couldn't make it work).
Maybe a loop ? Loop through the currencies and somehow show the total amount. But you can't do a sum in a loop so I don't know.
Also I'd like it to be flexible, so if in the future I add more currencies that I don't have to touch the code.
Any idea ?
If needed here is my 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 %>
Thanks alot.
Doing something along the lines of:
@sums_by_currency = Currency.joins(:spendings).
select(:symb, 'SUM(spendings.amount) AS amount').
where(spendings: { id: @user_spendings.map(&:id) }).
group(:symb)
would allow you to iterate over the currencies as in:
@sums_by_currency.each do |currency|
"#{currency.symb}#{currency.amount}"
end
or
@sums_by_currency.each do |currency|
number_to_currency(currency.amount, unit: currency.symb)
end
in your view.