Reputation: 6605
Is it possible to check if a string parameter being passed in is an integer? For example I need to retrieve a model based either on its id ("12345") or external_id ("eUv9wWzZ48bMZsuII6ivCle2NHgIEPoMLWC9ioDV"). Is this possible to achieve? I tried is_integer
but that returns false as it doesn't try to parse a string.
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
Upvotes: 5
Views: 11002
Reputation: 121000
This is an XY problem and I believe you are trying to solve inexistent issue in an incorrect way :)
According to what I can see from your input, external_id
is supposed to be the alphanumeric string of length 40. The keyword here is alphanumeric. That said, 40 times "1" might be an external_id
. And you know what? It is perfectly parsed by Integer.parse/2
:
iex|1 ▶ ["1"] |> List.duplicate(40) |> Enum.join |> Integer.parse
#⇒ {1111111111111111111111111111111111111111, ""}
That said, checking for integer is invalid in this context, because it might result in false positive.
What you do actually need to do, is to try to get the record by external_id
, possibly based on it’s length or something, and fallback to id
if not succeeded. Also, the length of binary might be indeed checked in guard (implicitly, by introducing an intermediate wrapper binary ⇒ bitstring.)
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
Upvotes: 7
Reputation: 222050
No, this can't be done in a guard. The functions you can call in a guard is limited and does not include any function to check whether a string contains only digits.
You can instead use Integer.parse/1
in the body:
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
Upvotes: 6