【问题标题】:How to query on binary_id field or string?如何查询 binary_id 字段或字符串?
【发布时间】:2021-08-18 21:30:24
【问题描述】:

我正在尝试编写一个 Ecto 查询,其中参数可以是 ID 或其他字段,在本例中是用户名。例如,像这样:

from(u in User, where: (u.id == ^id_or_username or u.username == ^id_or_username) and is_nil(u.deleted_at))

问题是当字符串id_or_username不是有效的binary_id时,Ecto会报错:

     ** (Ecto.Query.CastError) lib/myproject/accounts.ex:55: value `"user1@email.com"` cannot be dumped to type :binary_id in query:
                                                                                                                       
     from u0 in MyProject.Accounts.User,                                                                                                                                                                                                          
       where: (u0.id == ^"user1@email.com" or u0.username == ^"user1@email.com") and is_nil(u0.deleted_at),
       select: u0                                                                                                                                                                                                                             
                

我怎样才能做到这一点?

我想到的一个解决方案是检查字符串是否为 binary_id 并以不同方式查询,但这不是最优雅的方法。尽管如此,Ecto 中是否有一个功能可以做这样的事情?如何确定字符串是否为 Ecto binary_id?我可以正则表达式检查它,但宁愿不这样做。

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    检查二进制文件是否有效Ecto.UUID 的最简单方法是使用Ecto.UUID.cast/1

    iex|1 ▸ Ecto.UUID.generate() |> Ecto.UUID.cast()
    {:ok, "a9f44567-e031-44f1-aae6-972d7aabbb45"}
    iex|2 ▸ "foo" |> Ecto.UUID.cast()
    :error
    

    对于您遇到的问题,可以使用宏。

    defmacrop id_eq?(u, value) do
      case Ecto.UUID.cast(value) do
        {:ok, _} -> quote(do: fragment("u.id == ?", unquote(value)))
        :error -> quote(do: fragment("u.username == ?", unquote(value)))
      end
    end
    
    from(u in User, where: id_eq?(u, ^id_or_username))
    

    更多关于custom macros的信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-03
      • 1970-01-01
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      相关资源
      最近更新 更多