rbino

rbino

Ash Core Team

I’m finding myself working with Ecto.Multi more and more recently, and I’m trying to understand what are the best practices to work with them.

My question for this topic is: what is the suggested approach to factor out a common Multi operation that you want to execute in multiple places?

The approaches I’m aware of are:

Creating a function that accepts a Multi and returns a Multi

Example:

def create_foo(attrs) do
  Multi.new()
  |> Multi.insert(:foo, Foo.changeset(%Foo{}, attrs))
  |> associate_foo_with_bars()
  |> ...
end

def update_foo(foo, attrs) do
  Multi.new()
  |> Multi.insert(:foo, Foo.changeset(foo, attrs))
  |> associate_foo_with_bars()
  |> ...
end

defp associate_foo_with_bars(multi) do
  multi
  |> Multi.update_all(...)
end

Extracting the function you pass as argument to Multi.whatever

Example:

def create_foo(attrs) do
  Multi.new()
  |> Multi.insert(:foo, Foo.changeset(%Foo{}, attrs))
  |> Multi.update_all(:associate, &associate_foo_with_bars/1, [])
  |> ...
end

def update_foo(foo, attrs) do
  Multi.new()
  |> Multi.insert(:foo, Foo.changeset(foo, attrs))
  |> Multi.update_all(:associate, &associate_foo_with_bars/1, [])
  |> ...
end

defp associate_foo_with_bars(%{foo: foo}) do
   from b in Bars,
     ...
end

Using Multi.merge

def create_foo(attrs) do
  Multi.new()
  |> Multi.insert(:foo, Foo.changeset(%Foo{}, attrs))
  |> Multi.merge(&associate_foo_with_bars/1)
  |> ...
end

def update_foo(foo, attrs) do
  Multi.new()
  |> Multi.insert(:foo, Foo.changeset(foo, attrs))
  |> Multi.merge(&associate_foo_with_bars/1)
  |> ...
end

defp associate_foo_with_bars(%{foo: foo}) do
  Multi.new()
  |> Multi.update_all(:associate, ...
    from b in Bars,
      ...
  end)
end

I’m interested in the pros and cons of the approaches (and possibly to other approaches), and what approach you think works best for specific situations.

Moreover, I’d like to know if you consider the name of the operations part of the API to compose your Multis.
I’ll expand on what I mean: in examples 2 and 3 above, my function accepts changes, and I assert that there’s a :foo key that contains the Foo I need to use in the next operation.
Another approach could be pattern match on :foo in the top Multi and just pass the Foo struct to the functions, that would not be coupled to the operation name.
Do you accept the whole changes map in your Multi composition function or the single result of an operation?


Please note the aim of threads like this is for you to explain things in your own words. Please see this thread for details :slight_smile: (videos/links to further reading are also welcome though!)

Showing Posts 1 to 1

Pavij

Pavij

I’m also interested in this topic!

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New

Other Trending Topics Top

mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews