Preload association after Repo.update

Hey I am doing an update like this:

reminder =
          Ecto.Changeset.change(reminder,
            counter: reminder.counter + 1,
            latest_reminder: DateTime.truncate(now, :second)
          )
          |> Repo.update()
          |> Repo.preload(:user_event)

After the update the association is not preloaded automatically like at update so I am trying to preload it, but it doesn’t want to work.
Any ideas how to do this properly?

1 Like

Repo.update/2 returns a tuple {:ok, struct} so either use Repo.update!/2 or check the result another way

yes, the item is returned, but it’s association is not preloaded just says this:

ecto.Association.NotLoaded

Take a look at the following code:

reminder =
  Ecto.Changeset.change(reminder,
    counter: reminder.counter + 1,
    latest_reminder: DateTime.truncate(now, :second)
  )
  |> Repo.update()
  |> case do
    {:ok, reminder} -> {:ok, Repo.preload(reminder, :user_event)}
    error -> error
  end
  
  # or
  
  reminder =
    Ecto.Changeset.change(reminder,
      counter: reminder.counter + 1,
      latest_reminder: DateTime.truncate(now, :second)
    )
    |> Repo.update!()
    |> Repo.preload(:user_event)

With your code you are passing the tuple {:ok, struct} from Repo.update/2 to Repo.preload/2 instead of just the struct

6 Likes

yeah I just got it working like this:

reminder =
          Ecto.Changeset.change(reminder,
            counter: reminder.counter + 1,
            latest_reminder: DateTime.truncate(now, :second)
          )
          |> Repo.update!()
          |> Repo.preload(:user_event)

Great!

Aside from that I’d recommend you put the changeset code in the Reminder schema, it cleans up the code a bit.

defmodule Reminder do
  import Ecto.Changeset
  
  ( ... )
  
  def counter_changeset(%Reminder{} = reminder) do
    change(reminder,
      counter: reminder.counter + 1,
      latest_reminder: DateTime.truncate(now, :second)
    )
  end
end
3 Likes