Ecto.Multi.insert() does not return same error as Ecto.Repo.insert()

I have a changeset that should fail because of foreign_key_constraint. When I run Ecto.Repo.insert(changeset) I get

{:error,
 #Ecto.Changeset<
   action: :insert,
   changes: %{
     binding_source: :github,
     org_id: "55074a5d-a394-485d-b4c7-3d8156db59dc",
     project_id: "55074a5d-a394-485d-b4c7-3d8156db59dc",
     role_id: "55074a5d-a394-485d-b4c7-3d8156db59dc",
     subject_id: "55074a5d-a394-485d-b4c7-3d8156db59dc"
   },
   errors: [
     role_id: {"does not exist",
      [
        constraint: :foreign,
        constraint_name: "subject_role_bindings_role_id_fkey"
      ]}
   ],
   data: #Guard.Repo.SubjectRoleBinding<>,
   valid?: false
 >}

which is expected. But, when I run

Ecto.Multi.new()
|> Ecto.Multi.insert(
  :insert_name,
  changeset
)
|> Ecto.Repo.transaction()

I get {:ok, %{}}, and no error is raised.

According to this documentation, Ecto.Multi.insert should raise errors from changeset before starting the transaction.

Does anyone know whats the problem here? Thanks

What SQL runs in the second case? The result of %{} suggests no SQL runs, which is peculiar.

3 Likes

This hint helped me solve the problem. No SQL was running indeed, because iex interpreter doesn’t always work the best with new line characters, so when I pasted the code from my IDE, instead of creating multi that executes the changeset, it created multi that executes nothing. Once I retyped same code, but as part of one line, it all worked well. Thanks

2 Likes