json_api_query_builder v1.0.2 JsonApiQueryBuilder.Filter View Source
Filter operations for JsonApiQueryBuilder.
Link to this section Summary
Functions
Applies filter conditions from a parsed JSON-API request to an Ecto.Queryable.t
Extract the first segment of a dotted relationship path
Tests if the given string is a join filter
Tests if the given string is a join preload filter
Tests if the given string is either a join filter or a preload filter
Removes the leading path segment from map keys after grouping has been applied
Link to this section Functions
filter(Ecto.Queryable.t(), map(), function(), [{:relationships, [String.t()]}]) :: Ecto.Queryable.t()
Applies filter conditions from a parsed JSON-API request to an Ecto.Queryable.t
.
Each filter condition will be cause the given callback to be invoked with the query, attribute and value.
Relationship Filters
There are two types of relationship filters: join filters and preload filters.
Join filters use a dotted notation, eg: "comments.author.articles"
, and will be used to filter the primary data using a SQL inner join.
Eg: %{"filter" => %{"author.has_bio" => 1}}
can be used to find all articles where the related author has a bio in the database.
Preload filters use a nested notation, eg: %{"author" => %{"has_bio" => 1}}
, and will only be used to filter the relationships specified in the include
parameter.
Eg: %{"include" => "author", "filter" => %{"author" => %{"has_bio" => 1}}}
can be used to find all articles, and include the related authors if they have a bio.
Example
JsonApiQueryBuilder.Filter.filter(
Article,
%{"filter" => %{"tag" => "animals", "author.has_bio" => "1", "author.has_image" => "1", "comments" => %{"body" => "Great"}}},
&apply_filter/3,
relationships: ["author", "comments"]
)
The example above will cause the apply_filter/3
callback to be invoked twice:
apply_filter(query, "tag", "animals")
apply_filter(query, "author", %{"filter" => %{"has_bio" => "1", "has_image" => "1"}})
Where
apply_filter
would be implemented like:
def apply_filter(query, "tag", val), do: from(article in query, where: ^val in article.tag_list)
def apply_filter(query, "author", params) do
user_query = from(User, select: [:id]) |> User.Query.filter(params)
from(article in query, join: user in ^subquery(user_query), on: article.user_id == user.id)
end
Extract the first segment of a dotted relationship path.
Example
iex> JsonApiQueryBuilder.Filter.first_relationship_segment("a.b.c")
"a"
Tests if the given string is a join filter.
Example
iex> JsonApiQueryBuilder.Filter.is_join_filter?(["articles", "comments"], "articles.comments.user")
true
iex> JsonApiQueryBuilder.Filter.is_join_filter?(["articles", "comments"], "comments")
false
iex> JsonApiQueryBuilder.Filter.is_join_filter?(["articles", "comments"], "email")
false
Tests if the given string is a join preload filter.
Example
iex> JsonApiQueryBuilder.Filter.is_preload_filter?(["articles", "comments"], "articles.comments.user")
false
iex> JsonApiQueryBuilder.Filter.is_preload_filter?(["articles", "comments"], "comments")
true
iex> JsonApiQueryBuilder.Filter.is_preload_filter?(["articles", "comments"], "email")
false
Tests if the given string is either a join filter or a preload filter
Example
iex> JsonApiQueryBuilder.Filter.is_relationship_filter?(["articles", "comments"], "articles.comments.user")
true
iex> JsonApiQueryBuilder.Filter.is_relationship_filter?(["articles", "comments"], "comments")
true
iex> JsonApiQueryBuilder.Filter.is_relationship_filter?(["articles", "comments"], "email")
false
Removes the leading path segment from map keys after grouping has been applied.
Example
iex> JsonApiQueryBuilder.Filter.trim_leading_relationship_from_keys("article", [{"article.tag", "animals"}, {"article.comments.user.name", "joe"}])
{"article", %{"comments.user.name" => "joe", "tag" => "animals"}}