jdj_dk

jdj_dk

Nesting Ecto.Multis

Hi all you lovely people

I have a situation where I have to import a data set with multiple items where each has some other items associated with them.
To do this I’ve created a nested Ecto.Multi where the outer one map through all items a each time creates and execute an Ecto.Multi.new

A part of the code can be seen below:

def import_issues(issues, %Pace.GitRepository{board: board = %Pace.Board{}} = git_repository) do
    Ecto.Multi.new
    |> Ecto.Multi.run(:insert_issues, fn(_) ->
      issues
      |> Enum.map(&insert_data_for_issue(&1, board, git_repository))
      |> all_ok?
    end)
    |> Repo.transaction
  end

  defp insert_data_for_issue(%Pace.Bitbucket.Issue{} = issue, board, git_repository) do
    column = find_board_column(board, issue)
    reporter_user = Pace.Accounts.find_by_token_uuid(issue.reporter.uuid)
    card_params = prepare_card_params(issue, board, git_repository)

    Ecto.Multi.new
    |> create_card(reporter_user, column, card_params)
    |> create_remote_issue(issue, git_repository)
    |> create_comments(issue, board, git_repository)
    |> Repo.transaction
  end

This is all well and fine until I started making negative tests forcing the inner transaction to fail. This creates the following error:

** (CaseClauseError) no case clause matching: {:error, :rollback}
	      (ecto) lib/ecto/repo/queryable.ex:21: Ecto.Repo.Queryable.transaction/4
	      (espec) lib/espec/example_runner.ex:205: ESpec.ExampleRunner.do_run_before/2
	      (espec) lib/espec/example_runner.ex:138: anonymous fn/3 in ESpec.ExampleRunner.run_befores_and_lets/1
	      (espec) lib/espec/example_runner.ex:176: ESpec.ExampleRunner.call_with_rescue/2
	      (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
	      (espec) lib/espec/example_runner.ex:136: ESpec.ExampleRunner.run_befores_and_lets/1
	      (espec) lib/espec/example_runner.ex:37: ESpec.ExampleRunner.run_example/2
	      (espec) lib/espec/suite_runner.ex:76: ESpec.SuiteRunner.spawn_task/0

I assume this is due to the outer Ecto.Multi expecting error tuples to look like {:error, _} but it is getting {:error, failed_operation, failed_value, changes_so_far}. So my question is, how does one go about solving this? Can one not nest Ecto.Multi like this? And if that is the case, how should I go about this challenge?

Should I instead look into appending Ecto.Multi together?

Most Liked

jdj_dk

jdj_dk

The error came from my all_ok? function which maps all results from map to find a single :error tuple. Fixing this made the nested structure work fine.

Where Next?

Popular in Questions Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130579 1222
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
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
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

We're in Beta

About us Mission Statement