Vla*_*sky 5 postgresql uuid elixir phoenix-framework
def show(conn, %{"id" => id}) do
with {:ok, user} <- UserAction.get_user(id)
|> put_status(200)
|> render("show.json", %{user: user})
else
{:error, :not_found} -> {:error, :not_found, %User{id: id}}
end
end
Run Code Online (Sandbox Code Playgroud)
当 id 无效时,Ecto引发:
Ecto.Query.CastError - cannot be dumped to type :binary_id in query.
Run Code Online (Sandbox Code Playgroud)
我的get_user功能:
query = from(u in User, where u.id == ^id)
case Repo.all(query) do
[%User{} = user] -> {:ok, user}
_ -> {:error, :not_found}
end
Run Code Online (Sandbox Code Playgroud)
是否有任何方便的方法来处理此错误以防止 500 个响应?
这是UUID、Binary和其他需要符合特定标准的ecto类型的已知问题(这是一个功能,而不是 bug\xe2\x84\xa2\xef\xb8\x8f)。就像@TheAnh提到的,你可以用来Ecto.UUID.dump/1检查是否id有效,但我更喜欢直接拯救它:
def get_user(id) do\n Repo.get(User, id)\nrescue\n Ecto.Query.CastError -> nil\nend\nRun Code Online (Sandbox Code Playgroud)\n\nRepo上面的示例可能会变得乏味,因为您必须在rescue任何地方调用get。所以我重写了get/3以下函数MyApp.Repo:
# lib/my_app/repo.ex\ndefoverridable [get: 2, get: 3]\ndef get(query, id, opts \\\\ []) do\n super(query, id, opts)\nrescue\n Ecto.Query.CastError -> nil\nend\nRun Code Online (Sandbox Code Playgroud)\n\nfetch元组格式您应该使用fetch_*方法名称而不是get_*按格式返回值tuple(以避免与默认Repo方法混淆):
# lib/my_app/repo.ex\ndef fetch(query, id, opts \\\\ []) do\n case get(query, id, opts) do\n nil -> {:error, :not_found}\n schema -> {:ok, schema}\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n\n并在你的 main 函数中这样调用它:
\n\ndef fetch_user(id) do\n Repo.fetch(User, id)\nend\nRun Code Online (Sandbox Code Playgroud)\n
我最终得到了守卫宏
defmacro is_uuid(value) do
quote do
is_binary(unquote(value)) and byte_size(unquote(value)) == 36 and
binary_part(unquote(value), 8, 1) == "-" and binary_part(unquote(value), 13, 1) == "-" and
binary_part(unquote(value), 18, 1) == "-" and binary_part(unquote(value), 23, 1) == "-"
end
end
Run Code Online (Sandbox Code Playgroud)
用法:
def get_user(id) when is_uuid(id) do
Repo.get(User, id)
end
def get_user(_id), do: {:error, :not_found}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1513 次 |
| 最近记录: |