So I'm trying to implement a query function for a Collection table. And that table HAS to be filtered by :id, but it CAN be also filtered by :rating and :accessibility.
Right now I have a function that is something like this:
def find_collection(args) do...
Where args can be one of: %{id: id}
, %{id: id, rating: rating}
, %{id: id, accessibility: accessibility}
or %{id: id, rating: rating, accessibility: accessibility}
. And I need to make these in to ecto queries: [id: id]
, [id: id, rating: rating]
, etc...
I know I can make 4 different functions that expect different args
, but that seems very non-reusable. Maybe someone could give me a hit a better way to do composable "if map has key a do this and key b do this"?
You might simply pass the argument as is to Ecto.Query.where/3
. The safest way would be somewhat like:
def find_collection(%{id: _} = args) do
where_clause =
args
|> Map.take(~w|id rating accessibility|a)
|> Map.to_list()
from(t in Table, where: ^where_clause)
end