If you want to write purely functional functions based on Ecto data, you need to separate out your Repo.preload
s. This library helps you insert clean exceptions into those functions to make it clear when you have association dependencies. See this blog post for a more details discussion.
A EctoRequireAssociations.ensure!/2
function is defined which takes an ecto struct record and a specification of associations. The specification works the same as the Ecto.Repo.preload/3
callback.
def self_edited_posts(person) do
EctoRequireAssociations.ensure!(person, [:settings, authored_posts: :editor])
# Code which uses person.settings, person.authored_posts, and the
# `editor` association on the authored posts
end
If any of the specified associations aren't loaded an ArgumentError
will be raised
with a message like:
Expected association to be set: `authored_posts`
or if a nested preload is missing:
Expected association to be set: `authored_posts.editor`
If two associations are missing preloads:
Expected associations to be set: `settings`, `authored_posts.editor`
Ecto's Ecto.assoc_loaded?/1
is used, so nil
is considered a loaded value.
If an association isn't defined in the schema, a readable exception is produced instead:
Association `authored_psts` is not defined for the `MyApp.People.Person` struct
If available in Hex, the package can be installed
by adding ecto_require_associations
to your list of dependencies in mix.exs
:
def deps do
[
{:ecto_require_associations, "~> 0.1.3"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ecto_require_associations.