acrolink
Strange error in Ecto.Multi
I am trying to load a book, update it and update the associated record like this:
Multi.new()
|> Multi.run(:get_book, fn _ -> Mango.Books.get_book!(line.book_id) end)
|> Ecto.Multi.run(:update_book, fn %{book: book} ->
Books.update_book(Books.get_book!(book.book_id), %{status: 1})
end)
|> Ecto.Multi.run(:update_associated_record, fn %{book: book} ->
Records.update_record(Records.get_record!(book.record_id), %{
returned_at: :os.system_time(:seconds)
})
end)
|> Repo.transaction()
|> case do
{:ok, result} -> result
{:ok, %{book: book}} -> book
{:ok, %{record: record}} -> record |> whitelist_record_fields
end
This produces this error message:
** (exit) an exception was raised:
** (CaseClauseError) no case clause matching: %Mango.Books.Book{__meta__: #Ecto.Schema.Metadata<:loaded, "books">, author: "Waseem", code: 1116, id: 107, inserted_at: ~N[2018-05-05 11:39:49.688053], institute: #Ecto.Association.NotLoaded<association :institute is not loaded>, institute_id: 1, isbn: "13-1234-78", record_id: 17, records: #Ecto.Association.NotLoaded<association :records is not loaded>, status: :out, title: "Hello World", updated_at: ~N[2018-05-25 16:01:41.752519], year: 1982}
(ecto) lib/ecto/multi.ex:421: Ecto.Multi.apply_operation/5
(elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto) lib/ecto/multi.ex:411: anonymous fn/5 in Ecto.Multi.apply_operations/5
(ecto) lib/ecto/adapters/sql.ex:576: anonymous fn/3 in Ecto.Adapters.SQL.do_transaction/3
(db_connection) lib/db_connection.ex:1283: DBConnection.transaction_run/4
(db_connection) lib/db_connection.ex:1207: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:798: DBConnection.transaction/3
(ecto) lib/ecto/repo/queryable.ex:23: Ecto.Repo.Queryable.transaction/4
(mango) lib/mango/records/records.ex:112: anonymous fn/1 in Mango.Records.create_record_in/2 # referring to this line: |> Repo.transaction()
..
..
Any idea what might be going on here? Thank you.
Marked As Solved
OvermindDL1
Update is a different kind of call, it is better to use though, but still, run requires {:ok, result}/{:error, reason} and I bet that one of those were not.
Also Liked
OvermindDL1
A couple of things now that I have time to look:
-
Books.update_book(Books.get_book!(book.book_id), %{status: 1})
What is this returning? An{:ok, result}term?
Records.update_record(Records.get_record!(book.record_id), %{
returned_at: :os.system_time(:seconds)
})
What is this returning? Also an {:ok, result} term?
{:ok, %{book: book}} -> book
{:ok, %{record: record}} -> record |> whitelist_record_fields
These will never ever be matched on because {:ok, result} -> result will grab it all first.
amnu3387
I think you just need to name your first Multi.run(:get_book... as Multi.run(:book... ?
OvermindDL1
The name is how you reference that step in later steps though.
Ecto.Multi very much is a named monadic pipeline.
Elixir really needs some monad stuff built in better so umpteen libraries don’t have to keep remaking it and could just use a behaviour…
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
- #javascript
- #code-sync
- #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
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








