View Source Ash.Filter (ash v2.9.24)
The representation of a filter in Ash.
filter-templates
Filter Templates
To see the available templates, see Ash.Filter.TemplateHelpers
.
You can pass a filter template to build_filter_from_template/2
with an actor, and it will return the new result
Additionally, you can ask if the filter template contains an actor reference via template_references_actor?/1
writing-a-filter
Writing a filter
built-in-predicates
Built In Predicates
is_nil
==
!=
in
<
>
<=
>=
&&
||
<>
/
-
*
+
equals
(alias for==
)not_equals
(alias for!=
)gt
(alias for>
)lt
(alias for<
)gte
(alias for>=
)lte
(alias for<=
)eq
(alias for==
)not_eq
(alias for!=
)less_than
(alias for<
)greater_than
(alias for>
)less_than_or_equal
(alias for<=
)greater_than_or_equal
(alias for>=
)and
(alias for&&
)or
(alias for||
)concat
(alias for<>
)div
(alias for/
)minus
(alias for-
)times
(alias for*
)plus
(alias for+
)
booleanexpression-syntax
BooleanExpression syntax
The expression syntax ultimately just builds the keyword list style filter, but with lots of conveniences that would be very annoying to do manually.
Examples
Ash.Query.filter(resource, name == "Zardoz")
Ash.Query.filter(resource, first_name == "Zar" and last_name == "Doz")
Ash.Query.filter(resource, first_name == "Zar" and last_name in ["Doz", "Daz"] and high_score > 10)
Ash.Query.filter(resource, first_name == "Zar" or last_name == "Doz" or (high_score > 10 and high_score < -10))
keyword-list-syntax
Keyword list syntax
A filter is a nested keyword list (with some exceptions, like true
for everything and false
for nothing).
The key is the "predicate" (or "condition") and the value is the parameter. You can use and
and or
to create
nested filters. Data layers can expose custom predicates. Eventually, you will be able to define your own custom
predicates, which will be a mechanism for you to attach complex filters supported by the data layer to your queries.
Important
In a given keyword list, all predicates are considered to be "ands". So [or: [first_name: "Tom", last_name: "Bombadil"]]
doesn't
mean 'First name == "tom" or last_name == "bombadil"'. To say that, you want to provide a list of filters,
like so: [or: [[first_name: "Tom"], [last_name: "Bombadil"]]]
Some example filters:
Ash.Query.filter(resource, [name: "Zardoz"]))
Ash.Query.filter(resource, [first_name: "Zar", last_name: "Doz"])
Ash.Query.filter(resource, [first_name: "Zar", last_name: [in: ["Doz", "Daz"]], high_score: [greater_than: 10]])
Ash.Query.filter(resource, [or: [
[first_name: "Zar"],
[last_name: "Doz"],
[or: [
[high_score: [greater_than: 10]]],
[high_score: [less_than: -10]]
]
]])
other-formats
Other formats
Maps are also accepted, as are maps with string keys. Technically, a list of [{"string_key", value}]
would also work.
If you are using a map with string keys, it is likely that you are parsing input. It is important to note that, before
passing a filter supplied from an external source directly to Ash.Query.filter/2
, you should first call Ash.Filter.parse_input/2
(or Ash.Filter.parse_input/4
if your query has aggregates/calculations in it). This ensures that the filter only uses public attributes,
relationships, aggregates and calculations. You may additionally wish to pass in the query context, in the case that you have calculations
that use the provided context.
Link to this section Summary
Functions
Replace any actor value references in a template with the values from a given actor
Find an expression inside of a filter that matches the provided predicate
Can be used to find a simple equality predicate on an attribute
Returns a filter statement that would find a single record based on the input.
Parses a filter statement
Parses a filter statement
Parses a filter statement, accepting only public attributes/relationships, raising on errors.
Parses a filter statement, accepting only public attributes/relationships
Returns true if the second argument is a strict subset (always returns the same or less data) of the first
Whether or not a given template contains an actor reference
Transform an expression based filter to a simple filter, which is just a list of predicates
Link to this section Types
Link to this section Functions
add_to_filter!(base, addition, op \\ :and, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
View Sourceadd_to_filter(base, addition, op \\ :and, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
View Sourcebuild_filter_from_template(template, actor \\ nil, args \\ %{}, context \\ %{})
View SourceReplace any actor value references in a template with the values from a given actor
Find an expression inside of a filter that matches the provided predicate
Can be used to find a simple equality predicate on an attribute
Use this when your attribute is configured with filterable? :simple_equality
, and you want to
to find the value that it is being filtered on with (if any).
Returns a filter statement that would find a single record based on the input.
For example:
iex> get_filter(MyApp.Post, 1)
{:ok, %{id: 1}} #using primary key
iex> get_filter(MyApp.Post, id: 1)
{:ok, %{id: 1}} #using primary key
iex> get_filter(MyApp.Post, author_id: 1, publication_id: 2, first_name: "fred")
{:ok, %{author_id: 1, publication_id: 1}} # using a unique identity
iex> get_filter(MyApp.Post, first_name: "fred")
:error # not enough information
list_refs(expression, no_longer_simple? \\ false, in_an_eq? \\ false)
View Sourceparse!(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
View SourceParses a filter statement
See parse/2
for more
parse(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
View SourceParses a filter statement
See the module documentation for more information on the supported formats for filter statements.
important
Important
If you are trying to validate a filter supplied from an external/untrusted source,
be sure to use parse_input/2
instead! The only difference is that it only accepts
filters over public attributes/relationships.
aggregates-and-calculations
Aggregates and calculations
Since custom aggregates/calculations can be added to a query, and they must be explicitly loaded into
a query, the filter parser does not parse them by default. If you wish to support parsing filters
over aggregates/calculations, provide them as the third argument. The best way to do this is to build a query
with them added/loaded, and then use the aggregates
and calculations
keys on the query.
note
NOTE
A change was made recently that will automatically load any aggregates/calculations that are used in a filter, but if you are using this function you still need to pass them in.
Ash.Filter.parse(MyResource, [id: 1], query.aggregates, query.calculations)
parse_input!(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
View SourceParses a filter statement, accepting only public attributes/relationships, raising on errors.
See parse_input/2
for more
parse_input(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
View SourceParses a filter statement, accepting only public attributes/relationships
See parse/2
for more
relationship_paths(filter_or_expression, include_exists? \\ false, with_reference? \\ false)
View SourceReturns true if the second argument is a strict subset (always returns the same or less data) of the first
Whether or not a given template contains an actor reference
Transform an expression based filter to a simple filter, which is just a list of predicates
Options:
- skip_invalid?: