Using mix to Easily Create an Ecto Repo

June 08, 2016 4 minutes read

After reading my post From Zero to Ecto in 10 Minutes, @michalmuskala responded to me on Twitter with an excellent suggestion:

While I stepped through creating the files each by hand, there is indeed a faster way to get Ecto in your Elixir application even faster! If I had used this in the above post, perhaps it would have been From Zero to Ecto in 8 Minutes.

Let’s take a look at what mix ecto.gen.repo does.

Asking mix for help

I love to learn how to learn. Whenever I encounter a new piece of technology, the first thing I want to know is how to get help when and if I need it. I just recently switched from being a vim user for 10 years to being an emacs user. One of the things I really like about emacs is that it is easy and VERY helpful to ask emacs itself for help.

Elixir and mix provide similar ways to ask it for help.

A great way to learn about the mix tasks available to you is to ask mix itself what is available. After adding the ecto hex package to my fresh application and running mix deps.get && mix compile, I get the following output for mix help | grep ecto:

> mix help | grep ecto
mix ecto.create        # Create the storage for the repo
mix ecto.drop          # Drop the storage for the repo
mix ecto.gen.migration # Generate a new migration for the repo
mix ecto.gen.repo      # Generate a new repository
mix ecto.migrate       # Run migrations up on a repo
mix ecto.rollback      # Rollback migrations from a repo

We can see here that there is a task named mix ecto.gen.repo and it has a description of Generate a new repository. Hey, that’s what we want to do! Let’s ask it to tell us its details:

> mix help ecto.gen.repo
Generates a new repository.

The repository will be placed in the lib directory.

Examples

  mix ecto.gen.repo
  mix ecto.gen.repo -r Custom.Repo

This generator will automatically open the config/config.exs after generation
if you have ECTO_EDITOR set in your environment variable.

Command line options

  * -r, --repo - the repo to generate (defaults to YourApp.Repo)

Location: _build/dev/lib/ecto/ebin

Now that we know how to use it, let’s use it!

mix ecto.gen.repo

When a tool is provided to make my life easier, I generally like to take advantage of it.

> mix ecto.gen.repo
* creating lib/racebook
* creating lib/racebook/repo.ex
* updating config/config.exs
Don't forget to add your new repo to your supervision tree
(typically in lib/racebook.ex):

    supervisor(Racebook.Repo, [])

What this task did is generate the files we need in order to have an Ecto Repo in our application. It didn’t ask us for a name for it (though we could have specified one with the --repo option) as it is typically named Repo and lives in our lib directory. The task also printed some helpful information for us as well about what it was doing. It says it created the lib/racebook directory and a repo.ex file inside and also updated our config.exs file. Finally, it gives us a tip that we’ll want to add the Repo to our supervision tree.

Let’s take a look at each of these things in more detail.

lib/racebook/repo.ex

The task created this file for us but let’s take a look inside.

defmodule Racebook.Repo do
  use Ecto.Repo, otp_app: :racebook
end

Not a whole lot inside, but it is all we need to get the Repo defined. You’ll notice that this file directly matches the file we created in the From Zero to Ecto post.

config/config.exs

The task notified us that it updated an existing file in our application. That can sometimes be alarming but let’s see what it actually did (after removing comments in the file):

use Mix.Config

config :racebook, Racebook.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "racebook_repo",
  username: "user",
  password: "pass",
  hostname: "localhost"

We can see that it added the configuration of our Ecto Repo that it created. In that configuration, it provided some defaults that we can easily update for our particular environment. Once we edit those defaults, we should be good to go on the configuration side. So cool!

lib/racebook.ex

Finally, it gave us a pointer to add the repo to our supervision tree:

Don't forget to add your new repo to your supervision tree
(typically in lib/racebook.ex):

    supervisor(Racebook.Repo, [])

So let’s do that! In lib/racebook.ex:

defmodule Racebook do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      supervisor(Racebook.Repo, [])
    ]

    opts = [strategy: :one_for_one, name: Racebook.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Well, that was pretty easy.

Wrapping up

While we can pretty easily create and update the files ourselves, it is very nice that Ecto provides us with a mix task that does some of this work for us. I appreciate that — not just because it saves me some typing, but it helps me remember the things that need to be done in order to get up and running.

Use this task the next time you need an Ecto Repo in your application and also explore some of the other mix tasks that are provided to you. What are the ones you find most helpful?

Thanks again to @michalmuskala for inspiring this post. If you have any questions, comments, or other feedback, reach out to me on Twitter at @geolessel or in the Elixir Slack group at @geo.

Also, please sign up for my mailing list below. I stil haven’t sent out a single email to the list, but I am planning on some cool upcoming content that I don’t think you’ll want to miss. Thanks!

Updated: