Creating Ecto Migrations

When we work with Ecto, we don't create database tables directly. Instead, we write migrations, which are a record of changes to be made to a database. These migrations can be run and can also be undone in the case of a mistake. They serve as both a clear record of what's been done to the database and a way to reliably configure a new database (e.g. on a different development machine).

In order to make the DB changes specified by our migrations, we "run" them with the command mix ecto.migrate. If any were incorrect, we can "undo" them with the command mix ecto.rollback. Migrations go in the priv/repo/migrations directory.

Migrations added in this episode

We can generate migration files with mix ecto.gen.migration some_name. In this episode we created five:

mix ecto.gen.migration create_users
mix ecto.gen.migration create_links
mix ecto.gen.migration add_bookmarks
mix ecto.gen.migration add_titles
mix ecto.gen.migration add_link_tag

Note that in the tenth episode of the series, we standardized the names and changed "add" to create for each of the migration file names above. It has no impact on the functionality of the code but it's better to use "create" when talking of tables and "add" when talking of rows.

After generating the migrations, customize them as below:

Create Users

defmodule Linkly.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do
    create table(:users) do
      add :about, :text
      add :email, :string
      add :username, :string

      timestamps()
    end

    create unique_index(:users, [:email])
    create unique_index(:users, [:username])
  end
end

There was a typo on the unique indexes for users in the episode. There should be one unique index on :email and a second unique index on :user.

Create Links

defmodule Linkly.Repo.Migrations.CreateLinks do
  use Ecto.Migration

  def change do
    create table(:links) do
      add :url, :string

      timestamps()
    end

    create unique_index(:links, [:url])
  end
end

Create Bookmarks

defmodule Linkly.Repo.Migrations.AddBookmarks do
  use Ecto.Migration

  def change do
    create table(:bookmarks) do
      add :title, :string
      add :link_id, references(:links, on_delete: :delete_all)
      add :user_id, references(:users, on_delete: :delete_all)

      timestamps()
    end

    create unique_index(:bookmarks, [:link_id, :user_id])
  end
end

Create Tags

defmodule Linkly.Repo.Migrations.AddTags do
  use Ecto.Migration

  def change do
    create table(:tags) do
      add :title, :string

      timestamps()
    end

    create unique_index(:tags, [:title])
  end
end

Create LinkTags

defmodule Linkly.Repo.Migrations.AddLinkTags do
  use Ecto.Migration

  def change do
    create table(:link_tags) do
      add :link_id, references(:links, on_delete: :delete_all)
      add :tag_id, references(:tags, on_delete: :delete_all)
      add :user_id, references(:users, on_delete: :delete_all)

      timestamps()
    end

    create unique_index(:link_tags, [:link_id, :tag_id, :user_id])
  end
end
Back to index

No Comments