是否可以检查传入的字符串参数是否为整数?例如,我需要根据其id(“12345”)或external_id(“eUv9wWzZ48bMZsuII6ivCle2NHgIEPoMLWC9ioDV”)检索模型。这有可能实现吗?我尝试了is_integer
但是它返回false,因为它没有尝试解析字符串。
def call(%{params: %{"id" => id}} = conn, module) when is_atom(module) and is_integer(id) do
ZB.Repo.get!(module, id)
|> check(conn)
end
def call(%{params: %{"id" => id}} = conn, module) when is_atom(module) do
ZB.Repo.get_by!(module, external_id: id)
end
答案 0 :(得分:5)
这是一个XY problem我相信你正试图以不正确的方式解决不存在的问题:)
根据我从输入中看到的内容,external_id
应该是长度为40的字母数字字符串。此处的关键字是字母数字。也就是说,40次" 1"可能是extenral_id
。你知道吗?它由Integer.parse/2
完美解析:
iex|1 ▶ ["1"] |> List.duplicate(40) |> Enum.join |> Integer.parse
#⇒ {1111111111111111111111111111111111111111, ""}
也就是说,在此上下文中检查整数无效,因为它可能导致误报。
您实际需要做的是尝试按external_id
获取记录,可能是基于它的长度等等,如果没有,则回退到id
成功了。此外,二进制的长度可能确实在保护中检查(隐式地,通过引入中间包装二进制⇒比特串。)
def call(%{params: %{"id" => id}} = conn, module) when is_atom(module) do
case ZB.Repo.get_by(module, external_id: id) do
{:ok, record} -> record
_ -> ZB.Repo.get!(module, id) |> check(conn)
end
end
答案 1 :(得分:3)
不,这不能在警卫中完成。您可以在防护中调用的函数是有限的,不包括任何检查字符串是否只包含数字的函数。
您可以在正文中使用Integer.parse/1
:
def call(%{params: %{"id" => id}} = conn, module) when is_atom(module) do
case Integer.parse(id) do
{_, ""} -> ZB.Repo.get!(module, id) |> check(conn)
_ -> ZB.Repo.get_by!(module, external_id: id)
end
end