Elixir,Ecto 模式匹配条件与数据库查询不符合预期
Elixir, Ecto pattern matching conditional with db query not behaving as expected
如果记录不存在,我希望这个条件可以创建它,但它没有....返回 nil。
case Repo.get_by(User, %{email: "hulk@hogan.com"}) do
struct ->
struct
nil ->
params = Map.merge(%{email: "hulk@hogan.com"}, %{password: "password"})
Repo.insert!(User.changeset(User.__struct__, params))
end
# returns nil.... huwutt???
但是,如果我更改条件的顺序,它就会起作用。我在这里错过了什么?
case Repo.get_by(User, %{email: "hulk@hogan.com"}) do
nil ->
params = Map.merge(%{email: "hulk@hogan.com"}, %{password: "password"})
Repo.insert!(User.changeset(User.__struct__, params))
struct ->
struct
end
# returns a set of 24" pythons, brother.... huzah!
case
allows us to compare a value against many patterns until we
find a matching one:
换句话说,第一个匹配的案例将运行和case
不会继续进行。
在您的第一个示例中,第一种情况将始终匹配,因为您没有提供任何守卫,因此,struct
将绑定到 nil
。您的第二种方法解决了这个问题,因为您首先对特定案例进行模式匹配,然后通过将 case
的评估绑定到 struct
.
默认为一般案例
另请注意,您可以在第一种情况下使用守卫来确保 struct
的值是 map
,如 here 所述。
case Repo.get_by(User, %{email: "hulk@hogan.com"}) do
struct when is_map(struct) ->
struct
nil ->
params = Map.merge(%{email: "hulk@hogan.com"}, %{password: "password"})
Repo.insert!(User.changeset(User.__struct__, params))
end
如果记录不存在,我希望这个条件可以创建它,但它没有....返回 nil。
case Repo.get_by(User, %{email: "hulk@hogan.com"}) do
struct ->
struct
nil ->
params = Map.merge(%{email: "hulk@hogan.com"}, %{password: "password"})
Repo.insert!(User.changeset(User.__struct__, params))
end
# returns nil.... huwutt???
但是,如果我更改条件的顺序,它就会起作用。我在这里错过了什么?
case Repo.get_by(User, %{email: "hulk@hogan.com"}) do
nil ->
params = Map.merge(%{email: "hulk@hogan.com"}, %{password: "password"})
Repo.insert!(User.changeset(User.__struct__, params))
struct ->
struct
end
# returns a set of 24" pythons, brother.... huzah!
case
allows us to compare a value against many patterns until we find a matching one:
换句话说,第一个匹配的案例将运行和case
不会继续进行。
在您的第一个示例中,第一种情况将始终匹配,因为您没有提供任何守卫,因此,struct
将绑定到 nil
。您的第二种方法解决了这个问题,因为您首先对特定案例进行模式匹配,然后通过将 case
的评估绑定到 struct
.
另请注意,您可以在第一种情况下使用守卫来确保 struct
的值是 map
,如 here 所述。
case Repo.get_by(User, %{email: "hulk@hogan.com"}) do
struct when is_map(struct) ->
struct
nil ->
params = Map.merge(%{email: "hulk@hogan.com"}, %{password: "password"})
Repo.insert!(User.changeset(User.__struct__, params))
end