Ecto's `preload` with joins uses a single query!

TIL that when you explicitly join associations in Ecto and use preload, it executes just ONE query: # ✅ Single query - uses the joined data! from(rt in RaceTeam, left_join: r in assoc(rt, :race), left_join: cl in assoc(rt, :clues), where: rt.id == ^team_id, preload: [race: r, clues: cl] ) |> Repo.one() I always thought preload meant multiple queries, but that’s only true without explicit joins: # ❌ Multiple queries RaceTeam |> preload([:race, :clues]) |> Repo.one() The joined version handles the SQL row duplication problem automatically, grouping everything into the proper nested structure. No more N+1 queries AND no manual grouping needed! 🚀 ...

May 28, 2025 · 1 min · 102 words

Ecto changeset retrieval methods

When working with Ecto.changesets I have a hard time remembering when I should use get_field/3, get_change/3, fetch_field/2 and fetch_change/2 Here’s my summary: the get_* methods are used when want to be able to provide a default value the fetch_* methods return a tuple with the source of the data (or :ok) OR :error the *_field methods will search either the existing data or the changes the *_change methods will search only the changes for the key Short doc snippets for each of the methods ...

November 5, 2024 · 1 min · 165 words