Organising Ecto schemas

In a Phoenix application, you typically organise your schemas by context1.

In theory this makes sense. The schemas are responsible for data validation, and the other modules within the context are responsible for data access.

In practise, there’s a problem: it’s difficult to tell which is which.

Take the Accounts context, as generated by the mix phx.gen.auth command:

myapp/
  accounts/
    user.ex
    user_notifier.ex
    user_token.ex

Two of those files are schemas, the other provides data access functions. You could probably figure out that UserNotifier is the odd one out because the name contains a verb, but that’s far too much mental overhead for my liking. It should be immediately obvious whether I’m dealing with data (schemas) or actions.

Use a schemas directory

On a recent project, we solved this problem by creating a new myapp_schemas directory alongside myapp and myapp_web. Schemas are organised by context within myapp_schemas.

Taking the Phoenix auth example above, the new directory structure looks like this:

myapp/
  accounts/
    user_notifier.ex
myapp_schemas/
  accounts/
    user.ex
    user_token.ex

By moving schemas into their own directory, we clarify the distinction between data and actions. The subdirectories within myapp_schemas ensures that the relationship between a context and its schemas remains clear.

Footnotes

  1. Contexts are used to group related functionality and encapsulate data access.

Sign up for my newsletter

A monthly round-up of blog posts, projects, and internet oddments.