← All series

Series contents

Log in to track your progress

  1. 1. Ecto Overview: The Repo Episode
  2. 2. Configuring a new project with Ecto Episode
  3. 3. Creating Ecto Migrations Episode
  4. 4. Schema-less Ecto Queries Episode
  5. 5. Our first Ecto schemas Episode
  6. 6. Some useful Ecto functions Episode
  7. 7. Configuring IEx for working with Ecto Episode
  8. 8. Ecto belongs_to and has_many Episode
  9. 9. Ecto many_to_many and joining through Episode
  10. 10. Naming things in an Ecto project Episode
  11. 11. Ecto changesets: change vs cast Episode
  12. 12. Ecto changesets, validations and constraints Episode
  13. 13. Ecto build_assoc and put_assoc Episode

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

Open standalone page ↗

No Comments