UberMulti (uber_multi v1.0.0)

Provides the wrapper function for Ecto.Multi.

There are two differences when using UberMulti compared to the normal Multi methods. The first is the addition of the 'keys' argument. The keys provided in this argument are used in two ways. First, each key is used to try and extract a result from the list of previous changes in the execution of the Multi. If a result is not found, the key is instead used as-is as the parameter. In this way you can mix and match between providing your own arguments and automatically fetching them from previous Multi results.

The second difference is in the function that will be run when the Multi is executed. Given that the changes list is being preprocessed into a list of parameters to pass to the function, it will not need to take in the list of changes as normal, but simply take in the parameters it expects to perform its function.

So an UberMulti call which uses the following function: ''' def add_things(thing1, thing2) do

end '''

Might look like: ''' UberMulti.run(multi, :add_things, [:get_thing1, :get_thing2], &add_things/2) '''

Obviously this is very contrived, but shows how you can easily combine non-multi and multi-designed functions without having to wrap all the calls yourself and manually extract the results for the next one in the chain.

Another change is that the 'run' method will also automatically wrap the responses from any methods called that do not conform to the two element tuple response pattern. If a method returns '{:ok, term()}' or '{:error, term()}' the response will be used as is. By default any non-conforming response will be wrapped in a success tuple, see run/4 for configuration options.

Link to this section Summary

Types

The key to extract the parameters from using the changes map, or a value to pass directly to the callback.

One or more keys, with a single key optionally being in a list.

An '%Ecto.Multi{}' struct. See 'Ecto.Multi' for detailed specs.

A name to tag the multi function with. Must be unique within a single multi chain.

A callback function to call with the parameters extracted from the changes map.

Whether or not to trust the result by default if it does not come wrapped in a result tuple.

Functions

Adds a function to run as part of the Multi.

Link to this section Types

Specs

key() :: any()

The key to extract the parameters from using the changes map, or a value to pass directly to the callback.

Specs

keys() :: key() | [key()]

One or more keys, with a single key optionally being in a list.

Specs

multi() :: Ecto.Multi.t()

An '%Ecto.Multi{}' struct. See 'Ecto.Multi' for detailed specs.

Specs

name() :: any()

A name to tag the multi function with. Must be unique within a single multi chain.

Specs

run() :: function()

A callback function to call with the parameters extracted from the changes map.

Link to this type

trust_result()

Specs

trust_result() :: boolean() | (... -> any())

Whether or not to trust the result by default if it does not come wrapped in a result tuple.

Link to this section Functions

Link to this function

run(multi, name, keys, run, trust_result \\ false)

Specs

run(multi(), name(), keys(), run(), trust_result()) :: multi()

Adds a function to run as part of the Multi.

By default, functions which do not wrap their results in success tuples have their results returned as a successful call. By providing false as the last argument this behaviour is changed and results will be wrapped in an error tuple instead. Optionally, for finer grained control, a function which takes the result and returns a tagged value can be passed in as the last parameter instead of a boolean value.

examples

Examples

UberMulti.run(multi, :send_email, [:get_hot_news_items, :get_top_forum_post_headlines], fn(news, posts) ->
  ...do stuff...
end)
#Ecto.Multi{}

Multi.new()
|> UberMulti.run(:list_stars, ["Milky Way"], &Astronomy.list_stars/1)
|> UberMulti.run(:reverse, [:list_stars], &Enum.reverse/1)
|> UberMulti.run(:classify,
  [:reverse],
  &Astronomy.classify_stars/1,
  # Assume result is ok for brevity
  & {:ok, Enum.all?(&1, fn star -> star.class in ~w"O B A F G K M")})
|> Repo.transaction()