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?