Hi, am new to Phoenix Ecto. I am doing a cashflow record system, where each cashflow_entry can be assigned a cashflow_category.
here is the Schema:
schema "cashflow_entries" do
field :amount, :decimal
field :date, :date
field :entry_type, Ecto.Enum, values: [:income, :expense]
field :note, :string
belongs_to :cashflow_category, Epic.CashflowCategories.CashflowCategory
belongs_to :user, Epic.Accounts.User
timestamps()
end
schema "cashflow_categories" do
field :description, :string
field :entry_type, Ecto.Enum, values: [:income, :expense]
field :title, :string
has_many :cashflow_entries, Epic.CashflowEntries.CashflowEntry
belongs_to :user, Epic.Accounts.User
timestamps()
end
I am trying to query all cashflow_categories with SUM of all related cashflow_entries (where it belongs to the category) so I can display them as follows:
Category 1, total 35 (this is the SUM of all cashflow_entry.amount with category 1)
Category 2, total 125
…
I wanted to do it the Ecto way, but I have almost 0% idea how to accomplish this.
Extra nonsense
Currently I am doing this but don’t know how to go from here. Do i need subquery? or aggregate? or anything i didn’t know?
One exception / special case for that rule (at least on modern Postgres) - grouping by primary key means you don’t need to mention other columns on that table, since for instance there can only be one cc.description value for a given cc.id.
Thanks @sabiwara this works. But in Phoenix template I am unable to loop through them, I got error like “1st argument not an atom” I have to change a bit
CashflowCategory
|> where(user_id: ^user.id)
|> join(:left, [cc], ce in assoc(cc, :cashflow_entries))
|> group_by([cc], cc.id)
|> select(
[cc, ce],
%{
id: cc.id,
title: cc.title,
description: cc.description,
entry_type: cc.entry_type,
total: sum(ce.amount)
} # here! is this call struct?
)
|> Repo.all()
One more question
If I want to filter the cashflow_entry with specific date, example: SUM of all entries but within current month. total: sum(ce.amount) # only SUM if current month.
this requires a subquery?