Does anyone create reports with Ash to summarize resources?
I asked about querying SELECT count(1), title FROM posts GROUP BY title
with Ash, but Zach said we should use Ecto directly.
Since we’re using Ash as our application framework, I’m uncertain about when to use Ash queries versus Ecto queries for reporting functionality.
It depends largely on the reporting. The primary way actions are expected to behave is to return 1+ of the resource that action is referencing. For actions that return something other than the resource itself, you can use Generic Actions to use Ecto. The perk of doing it this way is you still have access to many of Ash’s features, e.g. authz policies.
If I understand correctly, you could also do simple counts directly on the domain with define_calculation. I could be wrong on that though, haven’t tried it yet!
1 Like
Depends on the complexity of the report. If it requires simple calculations or aggregates then I use the resource aggregates and calculations. But if it is a more complex report, I use the generic action to run ecto query.
Untested example that should work:
action :my_report, {:array, :map} do
argument :inserted_at, :datetime, allow_nil?: false
run fn input, _ ->
query = """
SELECT id, name, inserted_at
FROM users
WHERE inserted_at = $1
UNION
SELECT id, name, inserted_at
FROM customers
WHERE inserted_at = $1
"""
case Ecto.Adapters.SQL.query(MyApp.Repo, query, [input.inserted_at]) do
{:ok, %Postgrex.Result{rows: rows, columns: columns}} ->
results = Enum.map(rows, fn row ->
columns
|> Enum.zip(row)
|> Map.new()
end)
{:ok, results}
{:error, error} ->
{:error, error}
end
end
end
It’s worth pointing out that all Ash resources are Ecto schemas too. from row in MyApp.Accounts.User
etc also works 
2 Likes