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.Server
which 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
/hangman
approach which relies on bare path dependencies (which maximizes decoupling but makes many things less convenient (tradeoffs …)).