Mastering Phoenix Framework book's specific question: What does the following error mean?

I’m following the book Mastering Phoenix Framework from Phoenix inside-out series. At page #158, whenever I run this test (highlighted in the screenshot),

it give me the following error,

I tried my best and repeated from the start of the chapter several times, but every time it’s giving me the same problem.
Did anyone else face this problem while following this book? If yes, how did you solve it?

Thank You!

You probably have leftover items in your test database.

Try in your shell in the root of your project

MIX_ENV=test mix ecto.drop

This will drop your test database and when you will run the test again it will get rebuilt.

2 Likes

Thank you @voger for your reply, and for being so much helpful at this forum! :slight_smile:

I asked Shankar (the author of the book) through his email a while ago and he replied within minutes. He said the reason might be multiple migration files (may be because of going back and forth to different git branches). He told me similar solution and it worked for me :slight_smile:

Thank You @shankardevy for writing this fantastic book series and for being a humble and great human being!

2 Likes

I also have a question from this book, which is kind of an Elixir language question, so I thought I’ll add my question here instead of cluttering the book’s page.

Will somebody please explain the with part in this code?
When I was learning basics of Elixir, I wasn’t able to learn the with, and once again this with is in front of me, and I’m not able to get it.

Screenshot%20from%202019-09-19%2007-07-08

https://shankardevy.com/phoenix-inside-out-mpf/#creating-fetch-cart-plug

cart_id <- get_session(conn, :cart_id),

The result is bound to cart_id

true <- is_integer(cart_id),

Match only succeeds if is_integer/2 is true

%Order{} = cart <- Sales.get_cart(cart_id)

Match only succeeds if result is an Order struct which is then bound to cart

do   
   conn |> assign(:cart, cart)

Place that cart in the conn's assign

if any of the above matches fail

else 
  _ -> 
    cart = Sales.create_cart()
    conn
    |> put_session(:cart_id, cart.id)
    |> assign(:cart, cart)

put a fresh cart into the conn's assign

Kernel.SpecialForms.with/1

3 Likes

Thank you!
Now it makes sense.

The do block is only executed when the conditions of with are met, otherwise the else block will be executed.

To put it very short, all a with does is create a case tree. Anytime you see a new <- it is making a new case block, essentially this:

with(
  {:ok, a} <- something(),
  :blah <- something_else(),
  do: a,
  else: (
    {:error, reason} -> Logger.error(reason)
    err -> Logger.error("Unknown Error: #{inspect error}")
  )
)

Will be conceptually turned in to this:

else_fn = fn
  {:error, reason} -> Logger.error(reason)
  err -> Logger.error("Unknown error: #{inspect error}")
  else -> else
end
case something() do
  {:ok, a} ->
    case something_else() do
      :blah -> a
      else -> err_fn.(else))
    end
  else -> err_fn.(else))
end
1 Like