View Source Basic CRUD

In this document, "Internal data" represents data or logic hardcoded into your Elixir code. "External data" means data that comes from the user via forms, APIs, and often need to be normalized, pruned, and validated via Ecto.Changeset.

Fetching records

Single record

Fetching record by ID

Repo.get(Movie, 1)

Fetching record by attributes

Repo.get_by(Movie, title: "Ready Player One")

Fetching the first record

Movie |> Ecto.Query.first() |> Repo.one()

Fetching the last record

Movie |> Ecto.Query.last() |> Repo.one()

Use ! to raise if none is found

Repo.get!(Movie, 1)
Repo.get_by!(Movie, title: "Ready Player One")
Movie |> Ecto.Query.first() |> Repo.one!()

Multiple records

Fetch all at once

Movie |> Repo.all()

Stream all

Movie |> Repo.stream() |> Enum.each(fn record -> ... end)

Check at least one exists?

Movie |> Repo.exists?()

Querying records

Keyword-based queries

Bindingless queries

query =
  from Movie,
  where: [title: "Ready Player One"],
  select: [:title, :tagline]
Repo.all(query)

Bindings in queries

query =
  from m in Movie,
  where: m.title == "Ready Player One",
  select: [m.title, m.tagline]
Repo.all(query)

Interpolation with ^

title = "Ready Player One"
query =
  from m in Movie,
  where: m.title == ^title,
  select: [m.title, m.tagline]
Repo.all(query)

Pipe-based queries

Movie
|> where([m], m.title == "Ready Player One")
|> select([m], {m.title, m.tagline})
|> Repo.all

Inserting records

Single record

Using internal data

%Person{name: "Bob"}
|> Repo.insert()

Using external data

# Params represent data from a form, API, CLI, etc
params = %{"name" => "Bob"}

%Person{}
|> Ecto.Changeset.cast(params, [:name])
|> Repo.insert()

Multiple records

data = [%{name: "Bob"}, %{name: "Alice"}]
Repo.insert_all(Person, data)

Updating records

Single record

Using internal data

person =
  Person
  |> Ecto.Query.first()
  |> Repo.one!()

changeset = change(person, %{age: 29})
Repo.update(changeset)

Using external data

# Params represent data from a form, API, CLI, etc
params = %{"age" => "29"}

person =
  Person
  |> Ecto.Query.first()
  |> Repo.one!()

changeset = cast(person, params, [:age])
Repo.update(changeset)

Multiple records (using queries)

Repo.update_all(Person, set: [age: 29])

Deleting records

Single record

person = Repo.get!(Person, 1)
Repo.delete(person)

Multiple records (using queries)

Repo.delete_all(Person)