Chapters
- You're here
- Adding Authentication to Champions
- Adding a points system
- Adding points to users
- Listing our users
- Creating the user page
- Conceding points to the winner
- Distributed systems are hard
- TODO 😉
Endgame source code: https://github.com/lubien/champions (update as I write chapters).
Introduction
If you're like me, you're lazy. When it comes to learning new things you rather take it incrementally than jump on docs and spend a lot of time learning what it takes to use this new thing. That's fine, I guess. I mean, worked for me so far. I love to learn things doing projects so I'd like to invite you to learn LiveView with me doing a side project.
This project is going to be called Champions. Back in the day one of the very first projects that I created that made it into production was a side project of mine where my friends could compete with each other and get points by winning matches. It was a very simple system where all you'd have to do was declare that you lost to someone and they'd get 3 points if they confirmed their win, each would win 1 point on a draw. It was a trust-based system but worked just fine for us.
In these guides, I'm going to teach you how to rebuild that very system using Phoenix LiveView. My goal is to teach you LiveView concepts over time rather than dumping a ton of context you might not need at first. For that, you could feel like I'm not telling you the full history but I promise you by the end of it you're going to be able to make your very own side projects with the knowledge you get from here.
I'll approach these chapters as if I was just doing the project by myself and talking to the voices in my head. That means I'm going to do things incrementally and at random times I'm just going to suddenly add new scope to the app or change the current scope on a whim. I hope with that that you'd get some experience on how to change things on LiveView as needed over time since life is not all about generators, you also need to learn how to maintain code.
One more thing I'll be during throughout the entire process is that I'm going to link the documentation from Elixir, Phoenix, and Phoenix LiveView as much as possible. Those just happen to be one of the very best docs I've ever consumed as a developer and they also come packed with guides so don't feel scared of opening links from there.
Getting started
I love when a new thing I'm learning has a 'Get Started' page. That's usually where the maintainers put the minimal info you'd need to use something. I like it so much that I'm doing this section right here.
First, I assume you've installed Elixir. I'm using 1.14.1 with Erlang/OTP 24 but anything higher should just work. If you never installed it I highly recommend you to do it using asdf
, there's a ton of guides out there about it. If you're a Windows user, please make your life easier and use WSL to run everything. Another assumption I'm going to do is that you have PostgreSQL installed and running on your machine. We will be using it as our main database.
We will be using Phoenix 1.7.6 and that comes with LiveView v0.19.2 as of now. It was mentioned not much is going to change from LiveView as it's getting close to v1 so I'm confident I'm not going to need to rewrite this soon and you shouldn't be worried if you're reading this when Phoenix and LiveView are on higher versions.
Whenever I forget how to start a new Phoenix project all I have to do is go to https://www.phoenixframework.org/, click on Guides, and right on my left then open the 'Installation' page. To get the latest Phoenix installer run the command below.
$ mix archive.install hex phx_new
Resolving Hex dependencies...
Dependency resolution completed:
New:
phx_new 1.7.6
* Getting phx_new (Hex package)
All dependencies are up to date
Compiling 11 files (.ex)
Generated phx_new app
Generated archive "phx_new-1.7.6.ez" with MIX_ENV=prod
Found existing entry: /Users/lubien/.asdf/installs/elixir/1.14/.mix/archives/phx_new-1.7.3
Are you sure you want to replace it with "phx_new-1.7.6.ez"? [Yn]
* creating /Users/lubien/.asdf/installs/elixir/1.14/.mix/archives/phx_new-1.7.6
As you can see I already had v1.7.3 and it upgraded it to v1.7.6. You're also going to see a lot of paths like /Users/lubien/.asdf/installs/elixir/1.14/
since I'm using asdf
, don't worry about it. Let's create our project:
$ mix phx.new champions
* creating champions/config/config.exs
* creating champions/config/dev.exs
* creating champions/config/prod.exs
* creating champions/config/runtime.exs
* creating champions/config/test.exs
* creating champions/lib/champions/application.ex
* creating champions/lib/champions.ex
* creating champions/lib/champions_web/controllers/error_json.ex
* creating champions/lib/champions_web/endpoint.ex
* creating champions/lib/champions_web/router.ex
* creating champions/lib/champions_web/telemetry.ex
* creating champions/lib/champions_web.ex
* creating champions/mix.exs
* creating champions/README.md
* creating champions/.formatter.exs
* creating champions/.gitignore
* creating champions/test/support/conn_case.ex
* creating champions/test/test_helper.exs
* creating champions/test/champions_web/controllers/error_json_test.exs
* creating champions/lib/champions/repo.ex
* creating champions/priv/repo/migrations/.formatter.exs
* creating champions/priv/repo/seeds.exs
* creating champions/test/support/data_case.ex
* creating champions/lib/champions_web/controllers/error_html.ex
* creating champions/test/champions_web/controllers/error_html_test.exs
* creating champions/lib/champions_web/components/core_components.ex
* creating champions/lib/champions_web/controllers/page_controller.ex
* creating champions/lib/champions_web/controllers/page_html.ex
* creating champions/lib/champions_web/controllers/page_html/home.html.heex
* creating champions/test/champions_web/controllers/page_controller_test.exs
* creating champions/lib/champions_web/components/layouts/root.html.heex
* creating champions/lib/champions_web/components/layouts/app.html.heex
* creating champions/lib/champions_web/components/layouts.ex
* creating champions/priv/static/images/logo.svg
* creating champions/lib/champions/mailer.ex
* creating champions/lib/champions_web/gettext.ex
* creating champions/priv/gettext/en/LC_MESSAGES/errors.po
* creating champions/priv/gettext/errors.pot
* creating champions/priv/static/robots.txt
* creating champions/priv/static/favicon.ico
* creating champions/assets/js/app.js
* creating champions/assets/vendor/topbar.js
* creating champions/assets/css/app.css
* creating champions/assets/tailwind.config.js
* creating champions/assets/vendor/heroicons/LICENSE.md
* creating champions/assets/vendor/heroicons/UPGRADE.md
* extracting champions/assets/vendor/heroicons/optimized
Fetch and install dependencies? [Yn]
* running mix deps.get
* running mix assets.setup
* running mix deps.compile
We are almost there! The following steps are missing:
$ cd champions
Then configure your database in config/dev.exs and run:
$ mix ecto.create
Start your Phoenix app with:
$ mix phx.server
You can also run your app inside IEx (Interactive Elixir) as:
$ iex -S mix phx.server
This could take a while but our Elixir and JavaScript dependencies will come ready to be used. In the meantime feel free to open your favorite code editor on your project. Do pay attention that in the end, it will show commands that are useful to be run at first. Let's enter our project directory and create our database.
$ cd champions
$ mix ecto.create
Compiling 15 files (.ex)
Generated champions app
The database for Champions.Repo has been created
Just in case you don't know, mix
is the build and automation tool Elixir comes bundled with. Libraries such as Phoenix and Ecto can add commands to it. And now we see the first mention of Ecto. In short, it's the thing that lets you access databases. We will expand more on that later. If Postgres is not running on localhost on port 5432 with a user and password equal to postgres
, you're going to see a database error when running mix ecto.create
. In that case, feel free to open config/dev.exs
and change the ecto config.
# config/dev.exs
import Config
# Configure your database
config :champions, Champions.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "champions_dev",
stacktrace: true,
show_sensitive_data_on_connection_error: true,
pool_size: 10
# more stuff...
Time to start the server!
$ mix phx.server
[info] Running ChampionsWeb.Endpoint with cowboy 2.10.0 at 127.0.0.1:4000 (http)
[info] Access ChampionsWeb.Endpoint at http://localhost:4000
[watch] build finished, watching for changes...
Browserslist: caniuse-lite is outdated. Please run:
npx update-browserslist-db@latest
Why you should do it regularly: https://github.com/browserslist/update-db#readme
Rebuilding...
Done in 173ms.
Open http://localhost:4000 and you're going to see your app running.
Summary
- Phoenix is the web framework, and LiveView is a library that comes with it by default.
-
mix archive.install hex phx_new
installs or update your Phoenix CLI to create new projects. -
mix phx.new project_name
creates a new Phoenix project. - Phoenix uses Postgres by default for your database.
-
mix ecto.create
creates your database.
Top comments (6)
Hello João Ferreira,
thank you for your article.
I like how it is written as I find the language to be very easy to read (i.e. without complicated catchphrases and therefore suitable for beginners).
However, I will not learn Phoenix LiveView at this point in my life, but knowing a guide like yours is reassuring for future use should the need arise.
Thanks for the feedback! This was actually one of my goals here so I'm glad it resonated with you. See you anytime in the future!
"If you're like me, you're lazy."
No, I am not! 😊
Eager computing is also nice 😄
As a beginner this helped me a lot, I could properly understand what was happening, thanks for this
I really appreciate this message, many thanks!