Elixir, Ecto pattern matching conditional with db query not behaving as expected
Asked Answered
T

1

0

If the record does not exist, I would expect this conditional to create it, but it does not.... nil is returned.

case Repo.get_by(User, %{email: "[email protected]"}) do
    struct ->
      struct
    nil ->
      params = Map.merge(%{email: "[email protected]"}, %{password: "password"})
      Repo.insert!(User.changeset(User.__struct__, params))
end

# returns nil.... huwutt???

However, if I change the ordering of the condition, it works. What am I missing here?

case Repo.get_by(User, %{email: "[email protected]"}) do
    nil ->
      params = Map.merge(%{email: "[email protected]"}, %{password: "password"})
      Repo.insert!(User.changeset(User.__struct__, params))
    struct ->
      struct
end

# returns a set of 24" pythons, brother.... huzah!
Tamikatamiko answered 14/3, 2017 at 0:57 Comment(1)
In your first example, the first case will always be matched since you are not providing any guard, and as such, struct will bind to nilSpermous
S
2

According to the documentation

case allows us to compare a value against many patterns until we find a matching one:

In another word, the first matching case will run and case will not proceed further.

In your first example, the first case will always be matched since you are not providing any guards, and as such, struct will bind to nil. Your second approach solves the problem because you're pattern matching a specific case first, and then defaulting to a general case by binding the evaluation of case to struct.

Also note that you can use guards in your first case to make sure that the value of struct is a map as outlined here.

case Repo.get_by(User, %{email: "[email protected]"}) do
    struct when is_map(struct) ->
      struct
    nil ->
      params = Map.merge(%{email: "[email protected]"}, %{password: "password"})
      Repo.insert!(User.changeset(User.__struct__, params))
end
Spermous answered 14/3, 2017 at 1:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.