(ArgumentError: error when merging the following Ecto.Multi structs:)

I run into (ArgumentError error when merging the following Ecto.Multi structs:) this showed when I appended records using Ecto Multi.
below is the code

def handle_posting(user) do
    with(
      txn_details when txn_details != [] <- Transaction.where([auth_stat: "A"),
      fees = Fees_tbl.fee_query()
    ) do
      Enum.map(txn_details, fn txns ->
        Enum.map(Enum.with_index(fees, 1), fn {fee, index} ->
          with {cr_params, dr_params} <- handle_fee(fee, txn_details, user, index) do
            Ecto.Multi.new()
            |> Ecto.Multi.insert({:txn, "#{txn_details.id}#{index}"},
            Transaction.changeset(%Transaction{}, cr_params))
            |> Ecto.Multi.insert({:txn, "#{txn_details.id}#{index}"},
            Transaction.changeset(%Transaction{}, dr_params))
          end
        end)
      end)
      |> List.flatten()
      |> Enum.reject(& !&1)
      |> Enum.reduce(Ecto.Multi.new(), &Ecto.Multi.append/2)
      |> execute_multi()
    else
      _->
        {:error, "No records in the transaction table"}
    end
  end

The code is easier to read when you use
```elixir
…
````

  def handle_posting(user) do
    with txn_details when txn_details != [] <- Transaction.where(auth_stat: "A"),
         fees = Fees_tbl.fee_query() do
      Enum.map(txn_details, fn txns ->
        Enum.map(Enum.with_index(fees, 1), fn {fee, index} ->
          with {cr_params, dr_params} <- handle_fee(fee, txn_details, user, index) do
            Ecto.Multi.new()
            |> Ecto.Multi.insert(
              {:txn, "#{txn_details.id}#{index}"},
              Transaction.changeset(%Transaction{}, cr_params)
            )
            |> Ecto.Multi.insert(
              {:txn, "#{txn_details.id}#{index}"},
              Transaction.changeset(%Transaction{}, dr_params)
            )
          end
        end)
      end)
      |> List.flatten()
      |> Enum.reject(&(!&1))
      |> Enum.reduce(Ecto.Multi.new(), &Ecto.Multi.append/2)
      |> execute_multi()
    else
      _ -> {:error, "No records in the transaction table"}
    end
  end
2 Likes

ArgumentError alone is usually not enough to diagnose an issue (what is the REST of the error?), but I suspect the thing you’re hitting is this error:

yes thanks, that’s the error you have highlighted

I think there’s a copy-paste error putting the code in the post; when both calls to insert have the same name as shown here, I get a different-but-similar error:

Assuming those two operations in the inner loop have different names, the error message you’re seeing means that sometimes {:txn, "#{txn_details.id}#{index}"} is not unique. How is Transaction.where/1 implemented? Can it return duplicate rows?

1 Like

Thanks it has worked Transaction.where/1 was returning duplicate rows at {:txn, “#{txn_details.id}#{index}”}. hence i used:

Ecto.UUID.generate() 

to replace {:txn, "#{txn_details.id}#{index}