If I understand you correctly it sounds like Ecto was installed as part of the Phoenix project setup.
The “pattern” that you seem to be looking for would make Ecto part of the Todo application - not Phoenix.
The “pattern” is demonstrated in
hangman is the equivalent to your Todo application. gallows is the Phoenix based web interface for hangman. Now hangman doesn’t use a database - but if it did Ecto would be part of hangman - not gallows.
Therefore your Todo application should be designed to use Ecto (or whatever other persistent storage you use) even before Phoenix get involved.
You list Elixir in Action 2e as one of your books. If you look at the Chapter 11 example you have:
- A “Database”.
- The
Todo.Serverwhich directly depends on the “Database”. - And finally the Plug-based web server which depends directly on the
Todo.Server(andTodo.Cache). - Meanwhile application.ex/system.ex are responsible for starting everything up.
Now the big difference here is that it’s organized as one single Mix project. The gallows/hangman approach would organize Todo.Server and Todo.Database in a separate OTP application (i.e. separate Mix project) that can then be used as a dependency for Todo.Web (in a different Mix project).
Similarly a Phoenix application could simply use a “Todo OTP Application” (that uses Ecto internally) as a dependency without directly getting Ecto involved. Meanwhile the Phoenix project acts as “the application” that starts everything up but the “Todo Application” is responsible for managing its persistent storage (e.g. through Ecto or possibly yet another OTP application).
However that is probably the most complicated way of using Phoenix.
-
You can build “Phoenix is your application” style applications where simply each request to the web server initiates some interaction with the database that results in a response.
-
The next level of refinement is to use “Phoenix contexts” - i.e. organizing code into domain/business (i.e. context) specific modules rather than simply leaving all the code in the various controllers.
-
For even better separation there are umbrella projects which allows multiple OTP applications to run under the same configuration.
-
Finally the
gallows/hangmanapproach which relies on bare path dependencies (which maximizes decoupling but makes many things less convenient (tradeoffs …)).






















