Last active
April 11, 2019 14:32
-
-
Save brianberlin/112ba5589f3dc30e91e6174d5c098ca9 to your computer and use it in GitHub Desktop.
Ecto Filter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Filters do | |
import Ecto.{Query}, warn: false | |
defmacro __using__(_opts) do | |
quote do | |
defp apply_filters(original_query, params) do | |
filters = create_filters(params) | |
query = | |
try do | |
Enum.reduce(filters, original_query, &filter/2) | |
rescue | |
_ -> original_query | |
end | |
maybe_apply_defaults(query, original_query, filters) | |
end | |
defp maybe_apply_defaults(query, original_query, filters) when query == original_query, | |
do: Enum.reduce(filters, query, &defaults/2) | |
defp maybe_apply_defaults(query, _, _), do: query | |
defp condition_bools(filters) do | |
Enum.map(filters, fn | |
{key, "true"} -> {key, true} | |
{key, "false"} -> {key, false} | |
{key, value} -> {key, value} | |
end) | |
end | |
defp filter_parameters(filters) do | |
Enum.filter(filters, fn | |
{_, nil} -> false | |
{_, ""} -> false | |
{key, value} -> true | |
_ -> false | |
end) | |
end | |
defp convert_string_keys(filters) do | |
Enum.map(filters, fn | |
{key, value} when is_binary(key) -> {String.to_existing_atom(key), value} | |
{key, value} -> {key, value} | |
end) | |
end | |
defp create_filters(%{"q" => parameters}) do | |
parameters | |
|> filter_parameters() | |
|> condition_bools() | |
|> convert_string_keys() | |
end | |
defp create_filters(_), do: [] | |
defp defaults({key, value}, query) do | |
from( | |
[c] in query, | |
where: field(c, ^key) == ^value | |
) | |
end | |
defp defaults(_, query), do: query | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment