Ecto:

An Introduction

Dan McClain

3 components

  • Ecto.Repo
  • Ecto.Model
  • Ecto.Query

Ecto.Repo

  • Database Wrapper
  • Performs actions (insert, delete, get, update)
  • Bullet One
  • Bullet Two
  • Bullet Three
# config.exs
config :ecto_examples, EctoExamples.Repo,
  database: "ecto_examples",
  username: "dan",
  password: "",
  hostname: "localhost"

# repo.ex
defmodule EctoExamples.Repo do
  use Ecto.Repo,
    otp_app: :ecto_examples,
    adapter: Ecto.Adapters.Postgres
end

EctoExamples.Repo.insert user
EctoExamples.Repo.delete user
EctoExamples.Repo.all query

Migrations

  • Bullet One
  • Bullet Two
  • Bullet Three
$ mix ecto.gen.migration initial_users_create # Generate a migration

# priv/repo/migrations/20150224173410_initial_users_create.exs
defmodule EctoExamples.Repo.Migrations.InitialUsersCreate do
  use Ecto.Migration

  def up do
    create table(:users) do
      add :token, :string
      add :username, :string, null: false
      timestamps
    end
  end

  def down do
    drop table(:users)
  end
end

$ mix ecto.create   # Create our database

$ mix ecto.migrate  # Run migrations
$ mix ecto.rollback # Rollback migration

Ecto.Model

  • Defines data structures
  • Define changesets
    • Allow you to validate changes
  • Bullet One
  • Bullet Two
  • Bullet Three
defmodule EctoExamples.User do
  alias EctoExamples.Repo
  use Ecto.Model

  schema "users" do
    field :username
    field :token

    timestamps
  end

  # Contextual Validations <3
  def changeset(:insert, user, params) do
    params
    #             Required      Optional
    |> cast(user, ~w(username), ~w(token))
    |> validate_unique(:username, on: Repo)
    |> validate_format(:token, ~r/^\S*$/)
  end

  def changeset(:update, user, params) do
    params
    #             Required      Optional
    |> cast(user, ~w(username token), ~w())
    |> validate_unique(:username, on: Repo)
    |> validate_format(:token, ~r/^\S*$/)
  end
end

Ecto.Query

  • Encapsulates query with DSL
  • Inspired by .Net's LINQ
  • Composable
  • Bullet One
  • Bullet Two
  • Bullet Three
defmodule EctoExamples.UserQueries do
  import Ecto.Query

  def users_with_tokens do
    from u in EctoExamples.User,
      where: not(is_nil(u.token))
  end
end

defmodule EctoExamples.Pagination do
  import Ecto.Query

  def page(query, page_number, page_size) do
    _offset = (page_number - 1) * page_size

    query
    |> limit([q], ^page_size)
    |> offset([q], ^_offset)
  end
end

EctoExamples.Repo.all EctoExamples.UserQueries.users_with_tokens

EctoExamples.UserQueries.users_with_tokens
|> EctoExamples.Pagination.page(1,1)
|> EctoExamples.Repo.all

Questions?

Resources

Ecto: An Introduction

By Dan McClain

Ecto: An Introduction

  • 3,534