alakasam
alakasam
AEAsh Elixir
Created by alakasam on 6/24/2023 in #support
Using Ecto preload to load relationships in one query
Hello! Loving using Ash so far. I'm trying to make a simple Reddit clone, and I have a structure basically like this: - Post - belongs to an author (user) - belongs to a community When I display a post, I need to fetch the author and the community (so I can link to both). Currently I'm doing this by just building a load into my action:
read :for_display do
argument :id, :string, allow_nil?: false
get? true

filter expr(id == ^arg(:id))

prepare build(load: [:author, :community])
end
read :for_display do
argument :id, :string, allow_nil?: false
get? true

filter expr(id == ^arg(:id))

prepare build(load: [:author, :community])
end
However, this does not do a join, but instead does two separate queries (one for the author, one for the community):
[debug] QUERY OK source="posts" db=0.4ms idle=464.5ms
SELECT p0."id", p0."inserted_at", p0."updated_at", p0."title", p0."body", p0."removed", p0."locked", p0."nswf", p0."author_id", p0."community_id" FROM "posts" AS p0 WHERE (p0."id"::uuid = $1::uuid) ["f5862f1b-2693-4ce2-95f9-95d07bab91da"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
[debug] QUERY OK source="users" db=0.1ms queue=0.1ms idle=419.7ms
SELECT u0."id", u0."inserted_at", u0."updated_at", u0."email", u0."hashed_password" FROM "users" AS u0 WHERE (u0."id"::uuid = $1::uuid) ["949237b2-da56-453b-a0a0-1ab7bffc70f6"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
[debug] QUERY OK source="communities" db=0.3ms queue=0.1ms idle=467.6ms
SELECT c0."id", c0."inserted_at", c0."updated_at", c0."name", c0."title", c0."description", c0."nsfw" FROM "communities" AS c0 WHERE (c0."id"::uuid = $1::uuid) ["1b6b2517-8eb4-437a-a612-a065ccf109ca"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
[debug] QUERY OK source="posts" db=0.4ms idle=464.5ms
SELECT p0."id", p0."inserted_at", p0."updated_at", p0."title", p0."body", p0."removed", p0."locked", p0."nswf", p0."author_id", p0."community_id" FROM "posts" AS p0 WHERE (p0."id"::uuid = $1::uuid) ["f5862f1b-2693-4ce2-95f9-95d07bab91da"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
[debug] QUERY OK source="users" db=0.1ms queue=0.1ms idle=419.7ms
SELECT u0."id", u0."inserted_at", u0."updated_at", u0."email", u0."hashed_password" FROM "users" AS u0 WHERE (u0."id"::uuid = $1::uuid) ["949237b2-da56-453b-a0a0-1ab7bffc70f6"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
[debug] QUERY OK source="communities" db=0.3ms queue=0.1ms idle=467.6ms
SELECT c0."id", c0."inserted_at", c0."updated_at", c0."name", c0."title", c0."description", c0."nsfw" FROM "communities" AS c0 WHERE (c0."id"::uuid = $1::uuid) ["1b6b2517-8eb4-437a-a612-a065ccf109ca"]
↳ AshPostgres.DataLayer.run_query/2, at: lib/data_layer.ex:628
How do I modify this to fetch everything in a single query? When I get into fetching nested comments in a bit, having to fetch the users and the counts in separate queries feels like it would get slow. Is there a way I can use Ecto's preload option in Ash?
3 replies