For awhile now I’ve been a big fan of simple rules while programming, especially related to code organization. It’s really nice when working on a team to have simple rules to follow so that everyone know where things go. A pretty simple rule with phoenix is to put database CRUD related code that interacts with the Repo
inside of the Phoenix Context’s. If this rule is followed it allows anyone to pick up a phoenix application and know where database related code would be.
Another common rule I’ve heard of in the Elixir/Phoenix community is that public Ecto Schema file functions should always return a changeset. Don’t put business logic functions on the schema.
I’ve recently ran into a code review at work that challenged this rule. The code that was added was a public function that is both used in the changeset validation but also used in the rendering of the template.
I’ve created a basic example application to show what I mean: bike shop
The story behind this example application is that we are a bike shop, and we are using this application to keep track of what bikes we make. Right now the only difference between bikes are their color. We are a small startup bike shop so we’ve kept our colors small, we only sell red and blue bikes. In the future, if we get enough requests from customers we might add more colors.
The code added to the schema is this:
It’s a public function that exposes what colors we have available for bikes.
We use that for validation via validate_inclusion
:
But we also want to use those options when rendering the form for a dropdown when creating or editing a bike:
So the question is, does this available_colors/0
function belong on the schema? If the rule is that all public functions of a schema should always return a changeset then the obvious answer is no, it does not belong here.
So where does it belong? The context? I thought the context was mainly for CRUD related functions though, this wouldn’t seem to fit very well there.
Where do you store things like this?