catrapato
catrapato
AEAsh Elixir
Created by catrapato on 5/30/2025 in #support
select fields from nested associations
I have two tables: users and user_profiles, with a one-to-one relationship. I know it might sound a bit silly, but I don't always need the information from the profile. Back to the point: I created a read action for searching that looks like this:
read :search_instructors_by_name do
argument :query, :ci_string do
constraints allow_empty?: true
default ""
end

require Ash.Query

prepare fn %{arguments: %{query: full_name}} = query, _context ->
query
|> Ash.Query.load(user_profile: :full_name)
|> Ash.Query.filter(expr(role == :instructor))
|> Ash.Query.filter(contains(user_profile.full_name, ^full_name))
end
end
read :search_instructors_by_name do
argument :query, :ci_string do
constraints allow_empty?: true
default ""
end

require Ash.Query

prepare fn %{arguments: %{query: full_name}} = query, _context ->
query
|> Ash.Query.load(user_profile: :full_name)
|> Ash.Query.filter(expr(role == :instructor))
|> Ash.Query.filter(contains(user_profile.full_name, ^full_name))
end
end
The full_name is a calculation field based on other fields in user_profiles. For the search functionality, I only need the user's id and full_name — nothing more. However, when I trigger the search, it returns a whole bunch of fields, including full_name and all other user_profile fields. Is there a way to modify the search so that it only returns a simple map with just the :id and :full_name fields? In Ecto terms, would be something like:
Comment
|> join(:inner, [c], p in Post, on: c.post_id == p.id)
|> select([c, p], {p.title, c.text})
Comment
|> join(:inner, [c], p in Post, on: c.post_id == p.id)
|> select([c, p], {p.title, c.text})
I’ve tried many things without success — such as adding Ash.Query.select(:id) or using modify_query, but I’m not sure how to get an alias. Another option is to do some post-processing with Ecto.map, but I’m wondering if there’s a more elegant solution.
19 replies