Ecto - idiomatic way to update a record?

Hi,

What is the idiomatic way to update a record? I need to handle the case where the id may not be found, and return the error if that is the case. I’ve come up with the following code, although it looks rather ugly:

  def update(params, person_id) do
    person = Repo.get(Person, person_id)

    person =
      person &&
        person
        |> cast(params, @permitted)
        |> validate()
        |> Repo.update()

    case person do
      nil ->
        {:error,
         %Person{}
         |> change()
         |> add_error(:person_id, "not found")}

      {:ok, p} -> {:ok, p}

      err -> err
    end
  end

Thank you!

Hi,

Welcome to the forum

Do you use Ecto?

Then use the changesets to do the validation.

Also learn from here to understand faster the whole framework https://hexdocs.pm/phoenix/overview.html#content

Here is an example from the docs how to do it

def update_user(%User{} = user, attrs) do
    user
    |> User.changeset(attrs)
    |> Repo.update()
  end
3 Likes

BTW You are using a lot of local variables, You might have written this, maybe…

def update(params, person_id) do
  case Repo.get(Person, person_id) do
    nil ->
      {:error,
         %Person{}
         |> cast(%{}, [])
         |> add_error(:person_id, "not found")}
    person ->
      person
        |> cast(params, @permitted)
        |> validate()
        |> Repo.update()
  end
end
4 Likes