Where Post has_many Comments, I’d like to define a calculation in Post that essentially produces the following query. What’s the expression that I should define?
select *, coalesce(c.title, p.title) as title from Post p
left join Comments c
on c.post_id = p.id
Apparently, this doesn’t work.
calculate :combined_title, :string, expr(coalesce(comments.title, title))
so the post can have multiple comments, what should its combined_title
be if it has multiple?
For referring to has_one
or belongs_to
relationships, you can refer to them as references, i.e post.title
For coalescing, you have two options:
The || operator
calculate title_or_author_name, :string, expr(title || author.name)
Fragments
calculate title_or_author_name, :string, expr(fragment("coalesce(?, ?)", title, author.name))
Thank you. Is it possible to refer to the calculated field in a fragment in the same query? The following code results in an error “** (Postgrex.Error) ERROR 42703 (undefined_column) column “date” does not exist”. The SQL code that Ash generates does seem to define a calculated field but with no alias name “date”, and that’s why the query execution fails.
calculate :date, :utc_datetime, expr(instance.revised_date || original_date)
Post
|> Ash.Query.load([:date, :instance])
|> Ash.Query.filter(fragment("date_part('year', date)") == 2023")
|> Api.read()
You can reference it, but you can’t terence it “raw” like that. You use the reference in the expression, and interpolate that into the fragment string with ?
. In that specific instance it would look like this:
calculate :date, :utc_datetime, expr(instance.revised_date || original_date)
Post
|> Ash.Query.load([:date, :instance])
|> Ash.Query.filter(fragment("date_part('year',?)", date) == 2023)
|> Api.read()
1 Like
Thank you, and Happy New Year!!