Fl4m3Ph03n1x

Fl4m3Ph03n1x

How to execute Ecto.Multi clause conditionally?

Background

I have 3 queries (A, B and C) that need to be run in a transaction. Query A is always run, as well as query B. Query C is run only if query B returns not empty.

These need to be in a transaction, because if query C fails, I want to rollback any changed made by query A.

Code

Currently my code looks like this:

query_A = 
    # some query 

query_B =
     # some other query

query_C =
      # final query

Multi.new()
    |> Multi.update_all(:a, query_A,
      set: [update_value: true]
    )
    |> Multi.all(:all, query_B)
    |> Multi.update_all(:c, query_C,
      set: [update_other_value: true]
    )
    |> Repo.transaction()

Problems

There are several problems here:

  1. Multi.all does not have an atom associated, so if this operation fails I don’t know how to identify it
  2. I am always running :c. This is not what I want, I only want to do this if the previous Multi.all returns non-empty.

Is it possible to achieve this, using Ecto.Multi? I have seen Multi.run but I am unsure on how to make it fit here.

Marked As Solved

Fl4m3Ph03n1x

Fl4m3Ph03n1x

I have built this query which now seems to work as intended:

Multi.new()
    |> Multi.update_all(:a, query_A, set:  [update_value: true])
    |> Multi.all(:b, query_B)
    |> Multi.merge(fn result ->     
      case result.b do
        [] ->
          Multi.new()

        _ ->
          Multi.new()
          |> Multi.update_all(:c, query_C, set: [update_other_value: true])
      end
    end)
    |> Repo.transaction()

It is important to notice that query_A should not affect query_B. In case this happens, query_B should be done first (as it is a read only operation).

Thank you all for the help!

Also Liked

LostKobrakai

LostKobrakai

if Enum.empty?(something.all) do
  …
else
  …
end
LostKobrakai

LostKobrakai

Exactly.

LostKobrakai

LostKobrakai

That doesn’t work, as before running Repo.transaction there’s no way to know if a certain query result will be empty or not.

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New

Other popular topics Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement