query v0.5.2 Query

Query aids the use of Ecto in web settings.

With it, we can add paging, sorting, and scoping with ease. At its heart, Query lets us build complex queries from our controller params.

Example

Functionality is conducted through one main function Query.run/4:

defmodule App.PostController do
  use App, :controller

  @options [
    sort_permitted: ["id", "title", "inserted_at"],
    scope_permitted: ["by_title"],
    scope: {App.Context, :query}
  ]

  def index(conn, params) do
    result = Query.run(Post, Repo, params, @options)
    render(conn, "index.json", posts: result)
  end
end

Given the controller above, we can now pass the following query options.

/posts?sort_by=inserted_at&direction=desc&by_title=test

Further documentation to come...

Link to this section Summary

Functions

Fetches data from the given repository based on the params and options given.

Link to this section Types

Link to this type

option()
option() ::
  {:page_default, non_neg_integer()}
  | {:page_param, binary()}
  | {:limit_default, non_neg_integer()}
  | {:limit_max, non_neg_integer()}
  | {:limit_param, binary()}
  | {:sort_default, binary()}
  | {:sort_param, binary()}
  | {:sort_permitted, [binary()]}
  | {:dir_default, binary()}
  | {:dir_param, binary()}
  | {:count, boolean()}
  | {:count_limit, :infinite | non_neg_integer()}
  | {:scoping, {module(), atom()}}
  | {:scopes, [{module(), binary()}]}
  | {:preloads, [atom()]}

Link to this type

options()
options() :: [option()]

Link to this type

params()
params() :: %{required(binary()) => binary()}

Link to this type

t()
t() :: %Query{
  count: term(),
  count_column: term(),
  count_limit: term(),
  limit: term(),
  offset: term(),
  page: term(),
  preloads: term(),
  queryable: term(),
  repo: term(),
  scoping: term(),
  sorting: term()
}

Link to this section Functions

Link to this function

run(queryable, repo, params \\ %{}, opts \\ [])
run(Ecto.Queryable.t(), Ecto.Repo.t(), params(), options()) :: Query.Result.t()

Fetches data from the given repository based on the params and options given.

This provides an easy way to performing paging, sorting, and scoping all from binary maps - typically given from controller params.

Options

  • :page_default - the default page if none is provided - defaults to 1
  • :page_param - the param key to use for the page - defaults to "page"
  • :limit_default - the default limit if none is provided - defaults to 20
  • :limit_param - the param key to use for the limit - defaults to "limit"
  • :limit_max - the maximum allowed limit - defaults to 50
  • :sort_default - the default sort attribute if none is provided - defaults to "id"
  • :sort_param - the param key to use for the sort - defaults to "sort_by"
  • :sort_permitted - a list of permitted attributes that we can sort on
  • :dir_default - the default direction - defaults to "asc"
  • :dir_param - the param key to use for the direction - defaults to "dir"
  • :count - whether or not to fetch the total number of records - defaults to true
  • :count_limit - the maximum number of records to count - defaults to :infinite
  • :count_column - the column used to perform the count on
  • :scope_permitted - a list of permitted params that we can scope on
  • :scope - a {module, function} with an arity of 2, that will be passed an Ecto.Query as well as a map of the permitted scopes. You can then perform custom queries with these params
  • :preloads - a list of preloads that will be applied to the result data

Examples

iex> Query.run(App.Post, App.Repo)
%Query.Result{data: ...results of query, meta: ...paging attributes}

iex> Query.run(App.Post, App.Repo, %{"page" => 2, "sort_by" => "some_attr"}, sort_permitted: ["some_attr"])
%Query.Result{data: ...results of query, meta: ...paging attributes}

iex> Query.run(App.Post, App.Repo, %{"published" => true}, scope: {App.Context, :with_scope}, scope_permitted: ["published"])
%Query.Result{data: ...results of query, meta: ...paging attributes}