In many of the examples I’ve seen, Ecto models are kept simple. They only define a schema and changesets. I don’t see developers baking in additional functionality such that the model is significantly more than a wrapper around the database row.
But sometimes I need to define functionality specific to one model that will be used in several places. For instance, I have a function that returns true or false depending on the output of an Ecto query. I’m used to fatter models that know lots about their domain, and can then be referenced from traditional controllers/GraphQL schemas/whatever else we might imagine in the future without the need to teach each of these things how to interact with the model.
I’ve taken to stashing reusable query fragments in descriptive functions on the model, then composing them at the call site if I need some additional functionality. But where should I place a query that needs to run itself against the repo, then return a more appropriate result based on the result of the query?
Normally I’d just put it in the model as well, but given that models and repos are separate Ecto concepts, that the model essentially calls the repo module directly feels like a bit of a smell.
Should I put the code in the model, then accept the repo as an argument so the two aren’t dependencies? Is there a scenario where that actually yields a benefit, and isn’t just extra ceremony?
I suppose it isn’t a huge deal right now, but I’m trying to start out with Elixir/Ecto/Phoenix best practices early on.