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
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.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









