Ash.Query (ash v1.37.2) View Source
Utilties around constructing/manipulating ash queries.
Ash queries are used for read actions and side loads, and ultimately map to queries to a resource's data layer.
Queries are run by calling read
on an API that contains the resource in question
Examples:
MyApp.Post
|> Query.filter(likes > 10)
|> Query.sort([:title])
|> MyApp.Api.read!()
MyApp.Author
|> Query.aggregate(:published_post_count, :posts, filter: [published: true])
|> Query.sort(published_post_count: :desc)
|> Query.limit(10)
|> MyApp.Api.read!()
MyApp.Author
|> Query.load([:post_count, :comment_count])
|> Query.load(posts: [:comments])
|> MyApp.Api.read!()
Link to this section Summary
Functions
Adds an aggregation to the query.
Builds a query from a keyword list.
Adds a calculation to the query.
Return the underlying data layer query for an ash query
Remove an argument from the query
Ensure the the specified attributes are nil
in the query results.
fetches the value of an argument provided to the query or :error
Attach a filter statement to the query.
Creates a query for a given read action and prepares it.
Gets the value of an argument provided to the query
Limit the results returned from the query
Loads relationships, calculations, or aggregates on the resource.
Create a new query
Skip the first n records
Sets a specific context key to a specific value
Ensure that only the specified attributes are present in the results.
Set the query's api, and any side loaded query's api
Add an argument to the query, which can be used in filter templates on actions
Merge a map of arguments to the arguments list
Merge a map of values into the query context
Sort the results based on attributes or aggregates (calculations are not yet supported)
Removes a field from the list of fields to load
Link to this section Types
Specs
t() :: %Ash.Query{ __validated_for_action__: term(), action: term(), action_failed?: term(), after_action: term(), aggregates: term(), api: term(), arguments: term(), before_action: term(), calculations: term(), context: term(), errors: term(), filter: term(), limit: term(), offset: term(), params: term(), resource: term(), select: term(), side_load: term(), sort: term(), tenant: term(), valid?: term() }
Link to this section Functions
Specs
after_action( t(), (t(), [Ash.Resource.record()] -> {:ok, [Ash.Resource.record()]} | {:ok, [Ash.Resource.record()]} | {:error, term()}) ) :: t()
Specs
aggregate( t() | Ash.Resource.t(), atom(), Ash.Query.Aggregate.kind(), atom() | [atom()], Keyword.t() | nil ) :: t()
Adds an aggregation to the query.
Aggregations are made available on the aggregates
field of the records returned
The filter option accepts either a filter or a keyword list of options to supply to build a limiting query for that aggregate.
See the DSL docs for each aggregate type in Ash.Resource.Dsl
for more information.
Specs
Specs
build(Ash.Resource.t(), Ash.Api.t() | nil, Keyword.t()) :: t()
Builds a query from a keyword list.
This is used by certain query constructs like aggregates. It can also be used to manipulate a data structure before passing it to an ash query. It allows for building an entire query struct using only a keyword list.
For example:
Ash.Query.build(MyResource, filter: [name: "fred"], sort: [name: :asc], load: [:foo, :bar], offset: 10)
If you want to use the expression style filters, you can use expr/1
. Be sure to require Ash.Query
first,
or import it. Consider importing only the expr/1
macro if you do that
For example:
import Ash.Query, only: [expr: 1]
Ash.Query.build(Myresource, filter: expr(name == "marge"))
Supported keys:
filter
- filter keyword/expr or%Ash.Filter{}
sort
- sort keywordlimit
- integer limitoffset
- integer offsetload
- keyword/list of atoms to loadaggregate
-{name, type, relationship}
aggregate
-{name, type, relationship, query_in_build_format}
calculate
-{name, module_and_opts}
calculate
-{name, module_and_opts, context}
context: %{key: value}
Adds a calculation to the query.
Calculations are made available on the calculations
field of the records returned
The module_and_opts
argument accepts either a module
or a {module, opts}
. For more information
on what that module should look like, see Ash.Calculation
.
More features for calculations, like passing anonymous functions, will be supported in the future.
Return the underlying data layer query for an ash query
Remove an argument from the query
Ensure the the specified attributes are nil
in the query results.
Specs
fetches the value of an argument provided to the query or :error
Attach a filter statement to the query.
The filter is applied as an "and" to any filters currently on the query.
For more information on writing filters, see: Ash.Filter
.
Creates a query for a given read action and prepares it.
Multitenancy is not validated until an action is called. This allows you to avoid specifying a tenant until just before calling the api action.
Arguments
Provide a map or keyword list of arguments for the read action
Opts
:actor
- set the actor, which can be used in anyAsh.Resource.Change
s configured on the action. (in thecontext
argument):tenant
- set the tenant on the query
Specs
Gets the value of an argument provided to the query
Specs
limit(t() | Ash.Resource.t(), nil | integer()) :: t()
Limit the results returned from the query
Specs
Loads relationships, calculations, or aggregates on the resource.
Currently, loading attributes has no effects, as all attributes are returned.
Before long, we will have the default list to load as the attributes, but if you say
load(query, [:attribute1])
, that will be the only field filled in. This will let
data layers make more intelligent "select" statements as well.
# Loading nested relationships
Ash.Query.load(query, [comments: [:author, :ratings]])
# Loading relationships with a query
Ash.Query.load(query, [comments: [author: author_query]])
Create a new query
Specs
offset(t() | Ash.Resource.t(), nil | integer()) :: t()
Skip the first n records
Specs
put_context(t() | Ash.Resource.t(), atom(), term()) :: t()
Sets a specific context key to a specific value
See set_context/2
for more information.
Ensure that only the specified attributes are present in the results.
The first call to select/2
will replace the default behavior of selecting
all attributes. Subsequent calls to select/2
will combine the provided
fields unless the replace?
option is provided with a value of true
.
If a field has been deselected, selecting it again will override that (because a single list of fields is tracked for selection)
Primary key attributes and private attributes are always selected and cannot be deselected.
When attempting to load a relationship (or manage it with Ash.Changeset.manage_relationship/3
),
if the source field is not selected on the query/provided data an error will be produced. If loading
a relationship with a query, an error is produced if the query does not select the destination field
of the relationship.
Set the query's api, and any side loaded query's api
Add an argument to the query, which can be used in filter templates on actions
Merge a map of arguments to the arguments list
Specs
set_context(t() | Ash.Resource.t(), map() | nil) :: t()
Merge a map of values into the query context
Not much uses this currently.
Specs
set_tenant(t() | Ash.Resource.t(), String.t()) :: t()
Specs
sort(t() | Ash.Resource.t(), Ash.Sort.t()) :: t()
Sort the results based on attributes or aggregates (calculations are not yet supported)
Takes a list of fields to sort on, or a keyword list/mixed keyword list of fields and sort directions.
The default sort direction is :asc
.
Examples:
Ash.Query.sort(query, [:foo, :bar])
Ash.Query.sort(query, [:foo, bar: :desc])
Ash.Query.sort(query, [foo: :desc, bar: :asc])
Specs
Removes a field from the list of fields to load
Specs
unset(Ash.Resource.t() | t(), atom() | [atom()]) :: t()