I have created some basic query to load data from the database:
page =
Policy
|> join(:left, [p], c in Client, p.client_id == c.id)
|> where([p, c], c.user_id == ^conn.assigns.current_user.id)
|> where([p, c], p.client_id in ^params["policy"]["client_id"])
|> preload([p, c], [client: c])
|> Repo.paginate(params)
The nil problem arises when the GET parameter ["policy"]["client_id"]
is missing (not set in the request). My question, how to handle that? How to prevent this error? Basically I want that particular where sentence to be ignored if ["policy"]["client_id"]
is empty.
I would encapsulate this query in a separate function and pattern match on the parameter
def foo(params["policy"]["client_id"] = client_id) when is_binary(client_id) do
# query the db
end
def foo(_) do
# return some thing useful
end
1 Like
@schaary
Thank you. I understand that the use of multiple function definitions with various guards can cover all parameters’ possibilities. However, if I will be filtering by say 5 parameters then the list of possible combinations of those parameters will be big and that means I will have to write multiple function/guard definitions to catch all possibilities. I hope there is a simpler approach to run that Ecto query.
You could also use query composition, pushing out the client_id filtering to a separate function… should look something like this:
def filter_policy_client_id(query, nil), do: query
def filter_policy_client_id(query, client_id) do
query |> where([p], p.client_id in ^client_id)
end
# ...
page =
Policy
|> join(:left, [p], c in Client, p.client_id == c.id)
|> where([p, c], c.user_id == ^conn.assigns.current_user.id)
|> filter_policy_client_id(params["policy"]["client_id"])
|> preload([p, c], [client: c])
|> Repo.paginate(query, params)
Is client_id supposed to be a list? If it’s not, I suspect you should use equality comparison instead of in
.
1 Like
@schaary, @jwarlander
Thank you… I have learned new things in Elixir today inspecting the answers you have provided…