#
View Source Ash.Filter (ash v2.14.2)

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

## Types

t()

## Functions

add_to_filter!(base, addition, op \\ :and, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
add_to_filter(base, addition, op \\ :and, aggregates \\ %{}, calculations \\ %{}, context \\ %{})
build_filter_from_template(template, actor \\ nil, args \\ %{}, context \\ %{})

Replace any actor value references in a template with the values from a given actor

builtin_functions()
builtin_operators()
builtin_predicate_operators()
builtins()
do_hydrate_refs(ref, context)
find(expr, pred, ors? \\ true, ands? \\ true)

Find an expression inside of a filter that matches the provided predicate

find_simple_equality_predicate(expression, attribute)

Can be used to find a simple equality predicate on an attribute

find_value(expr, pred)
flat_map(expression, func)
get_filter(resource, id)

Returns a filter statement that would find a single record based on the input.

get_function(key, resource, public?)
get_operator(key)
hydrate_refs(value, context)
list_predicates(expression)
list_refs(expression, no_longer_simple? \\ false, in_an_eq? \\ false)
map(filter, func)
move_exprs_to_relationship_path(refs, path)
move_to_relationship_path(expression, relationship_path)
parse!(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

Parses a filter statement

parse(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

Parses a filter statement

parse_input!(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

Parses a filter statement, accepting only public attributes/relationships, raising on errors.

parse_input(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

Parses a filter statement, accepting only public attributes/relationships

prefix_refs(expr, path)
put_at_path(value, list)
read_requests(api, filter, request_path, actor, tenant)
relationship_paths(filter_or_expression, include_exists? \\ false, with_reference? \\ false)
run_other_data_layer_filters(api, resource, filter, data)
strict_subset_of(filter, candidate)

Returns true if the second argument is a strict subset (always returns the same or less data) of the first

strict_subset_of?(filter, candidate)
template_references_actor?(list)

Whether or not a given template contains an actor reference

to_simple_filter(map, opts \\ [])

Transform an expression based filter to a simple filter, which is just a list of predicates

update_aggregates(filter, mapper)
used_aggregates(filter, relationship_path \\ [], return_refs? \\ false)
used_calculations(filter, resource, relationship_path \\ [], calculations \\ %{}, aggregates \\ %{})

# Link to this section Types

Link to this type

# t()

View Source

    @type t() :: %Ash.Filter{expression: term(), resource: term()}

# Link to this section Functions

Link to this function

# add_to_filter!(base, addition, op \\ :and, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

View Source
Link to this function

# add_to_filter(base, addition, op \\ :and, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

View Source
Link to this function

# build_filter_from_template(template, actor \\ nil, args \\ %{}, context \\ %{})

View Source

Replace any actor value references in a template with the values from a given actor

Link to this function

# builtin_functions()

View Source
Link to this function

# builtin_operators()

View Source
Link to this function

# builtin_predicate_operators()

View Source
Link to this function

# builtins()

View Source
Link to this function

# do_hydrate_refs(ref, context)

View Source
Link to this function

# find(expr, pred, ors? \\ true, ands? \\ true)

View Source

Find an expression inside of a filter that matches the provided predicate

Link to this function

# find_simple_equality_predicate(expression, attribute)

View Source

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).

Link to this function

# find_value(expr, pred)

View Source
Link to this function

# flat_map(expression, func)

View Source
Link to this function

# get_filter(resource, id)

View Source

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

Link to this function

# get_function(key, resource, public?)

View Source
Link to this function

# get_operator(key)

View Source
Link to this function

# hydrate_refs(value, context)

View Source
Link to this function

# list_predicates(expression)

View Source
Link to this function

# list_refs(expression, no_longer_simple? \\ false, in_an_eq? \\ false)

View Source
Link to this function

# map(filter, func)

View Source
Link to this function

# move_exprs_to_relationship_path(refs, path)

View Source
Link to this function

# move_to_relationship_path(expression, relationship_path)

View Source
Link to this function

# parse!(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

View Source

Parses a filter statement

See `parse/2` for more

Link to this function

# parse(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

View Source

Parses 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)

Link to this function

# parse_input!(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

View Source

Parses a filter statement, accepting only public attributes/relationships, raising on errors.

See `parse_input/2` for more

Link to this function

# parse_input(resource, statement, aggregates \\ %{}, calculations \\ %{}, context \\ %{})

View Source

Parses a filter statement, accepting only public attributes/relationships

See `parse/2` for more

Link to this function

# prefix_refs(expr, path)

View Source
Link to this function

# put_at_path(value, list)

View Source
Link to this function

# read_requests(api, filter, request_path, actor, tenant)

View Source
Link to this function

# relationship_paths(filter_or_expression, include_exists? \\ false, with_reference? \\ false)

View Source
Link to this function

# run_other_data_layer_filters(api, resource, filter, data)

View Source
Link to this function

# strict_subset_of(filter, candidate)

View Source

Returns true if the second argument is a strict subset (always returns the same or less data) of the first

Link to this function

# strict_subset_of?(filter, candidate)

View Source
Link to this function

# template_references_actor?(list)

View Source

Whether or not a given template contains an actor reference

Link to this function

# to_simple_filter(map, opts \\ [])

View Source

Transform an expression based filter to a simple filter, which is just a list of predicates

Options:

- skip_invalid?:

Link to this function

# update_aggregates(filter, mapper)

View Source
Link to this function

# used_aggregates(filter, relationship_path \\ [], return_refs? \\ false)

View Source
Link to this function

# used_calculations(filter, resource, relationship_path \\ [], calculations \\ %{}, aggregates \\ %{})

View Source