Rummage.Ecto v2.0.0 Rummage.Ecto View Source
Rummage.Ecto is a light weight, but powerful framework that can be used to alter Ecto queries with Search, Sort and Paginate operations.
It accomplishes the above operations by using Hooks
, which are modules that
implement Rummage.Ecto.Hook
behavior. Each operation: Search, Sort and Paginate
have their hooks defined in Rummage. By doing this, we have made rummage completely
configurable. For example, if you don't like one of the implementations of Rummage,
but like the other two, you can configure Rummage to not use it.
If you want to check a sample application that uses Rummage, please check this link.
Usage:
defmodule Rummage.Ecto.Category do
use Ecto.Schema
use Rummage.Ecto
schema "categories" do
field :name, :string
end
end
This allows you to do:
iex> rummage = %{search: %{name: %{assoc: [], search_type: :ilike, search_term: "field_!"}}}
iex> {queryable, rummage} = Rummage.Ecto.Category.rummageq(Rummage.Ecto.Category, rummage)
iex> queryable
#Ecto.Query<from c0 in subquery(from c0 in Rummage.Ecto.Category), where: ilike(c0.name, ^"%field_!%")>
iex> rummage
%{search: %{name: %{assoc: [], search_expr: :where,
search_term: "field_!", search_type: :ilike}}}
This also allows you to do call rummage/2
without a queryable
which defaults
to the module calling rummage
, which is Rummage.Ecto.Category
in this case:
iex> rummage = %{search: %{name: %{assoc: [], search_type: :ilike, search_term: "field_!"}}}
iex> {queryable, rummage} = Rummage.Ecto.Category.rummage(rummage)
iex> queryable
#Ecto.Query<from c0 in subquery(from c0 in Rummage.Ecto.Category), where: ilike(c0.name, ^"%field_!%")>
iex> rummage
%{search: %{name: %{assoc: [], search_expr: :where,
search_term: "field_!", search_type: :ilike}}}
Link to this section Summary
Functions
This macro allows an Ecto.Schema
to leverage rummage's features with
ease. This macro defines a function rummage/2
which can be called on
the Module using
this which delegates to Rummage.Ecto.rummage/3
, but
before doing that it resolves the options with default values for repo
,
search
hook, sort
hook and paginate
hook. If rummage/2
is called with
those options in form of keys given to the last argument opts
, then it
sets those keys to what's given else it delegates it to the defaults
specficied by __using__
macro. If no defaults are specified, then it
further delegates it to configurations.
This is the function which calls to the Rummage
hooks
.
It is the entry-point to Rummage.Ecto
.
Link to this section Functions
This macro allows an Ecto.Schema
to leverage rummage's features with
ease. This macro defines a function rummage/2
which can be called on
the Module using
this which delegates to Rummage.Ecto.rummage/3
, but
before doing that it resolves the options with default values for repo
,
search
hook, sort
hook and paginate
hook. If rummage/2
is called with
those options in form of keys given to the last argument opts
, then it
sets those keys to what's given else it delegates it to the defaults
specficied by __using__
macro. If no defaults are specified, then it
further delegates it to configurations.
The function rummage/2
takes in rummage params
and opts
and calls
Rummage.Ecto.rummage/3
with whatever schema is calling it as the
queryable
.
This macro also defines a function rummageq/3
where q implies queryable
.
Therefore this function can take a queryable
as the first argument.
In this way this macro makes it very easy to use Rummage.Ecto
.
Usage:
Basic Usage where a default repo is specified as options to the macro.
defmodule MyApp.MySchema do
use Ecto.Schema
use Rummage.Ecto, repo: MyApp.Repo, per_page: 10
end
Advanced Usage where search and sort hooks are overrident for this module.
defmodule MyApp.MySchema do
use Ecto.Schema
use Rummage.Ecto, repo: MyApp.Repo, per_page: 10,
search: CustomSearchModule,
sort: CustomSortModule
end
This allows you do just do `MyApp.Schema.rummage(rummage_params)` with specific
`rummage_params` and add `Rummage.Ecto`'s power to your schema.
Specs
rummage(Ecto.Query.t(), map(), Keyword.t()) :: {Ecto.Query.t(), map()}
This is the function which calls to the Rummage
hooks
.
It is the entry-point to Rummage.Ecto
.
This function takes in a queryable
, a rummage
map and an opts
keyword.
Recognized opts
keys are:
repo
: If you haven't set up arepo
at the config level or__using__
level, this a way of passing `repo` to `rummage`. If you have already configured your app to use a default `repo` and/or specified the `repo` at `__using__` level, this is a way of overriding those defaults.
per_page
: If you haven't set up aper_page
at the config level or__using__
level, this a way of passing `per_page` to `rummage`. If you have already configured your app to use a default `per_page` and/or specified the `per_page` at `__using__` level, this is a way of overriding those defaults.
search
: If you haven't set up asearch
at the config level or__using__
level, this a way of passing `search` to `rummage`. If you have already configured your app to use a default `search` and/or specified the `search` at `__using__` level, this is a way of overriding those defaults. This can be used to override native `Rummage.Ecto.Hook.Search` to a custom hook.
sort
: If you haven't set up asort
at the config level or__using__
level, this a way of passing `sort` to `rummage`. If you have already configured your app to use a default `sort` and/or specified the `sort` at `__using__` level, this is a way of overriding those defaults. This can be used to override native `Rummage.Ecto.Hook.Sort` to a custom hook.
paginate
: If you haven't set up apaginate
at the config level or__using__
level, this a way of passing `paginate` to `rummage`. If you have already configured your app to use a default `paginate` and/or specified the `paginate` at `__using__` level, this is a way of overriding those defaults. This can be used to override native `Rummage.Ecto.Hook.Paginate` to a custom hook.
Examples
When no hook params are given, it just returns the queryable and the params:
iex> import Rummage.Ecto
iex> alias Rummage.Ecto.Product
iex> rummage = %{}
iex> {queryable, rummage} = rummage(Product, rummage)
iex> rummage
%{}
iex> queryable
Rummage.Ecto.Product
When nil
hook module is given, it just returns the queryable and the params:
iex> import Rummage.Ecto
iex> alias Rummage.Ecto.Product
iex> rummage = %{paginate: %{page: 1}}
iex> {queryable, rummage} = rummage(Product, rummage, paginate: nil)
iex> rummage
%{paginate: %{page: 1}}
iex> queryable
Rummage.Ecto.Product
When a hook param is given, with hook module it just returns the
queryable
and the params
:
iex> import Rummage.Ecto
iex> alias Rummage.Ecto.Product
iex> rummage = %{paginate: %{page: 1}}
iex> repo = Rummage.Ecto.Repo
iex> Ecto.Adapters.SQL.Sandbox.checkout(repo)
iex> opts = [paginate: Rummage.Ecto.Hook.Paginate, repo: repo]
iex> {queryable, rummage} = rummage(Product, rummage, opts)
iex> rummage
%{paginate: %{max_page: 0, page: 1, per_page: 10, total_count: 0}}
iex> queryable
#Ecto.Query<from p0 in Rummage.Ecto.Product, limit: ^10, offset: ^0>
When a hook is given, with correspondng params, it updates and returns the
queryable
and the params
accordingly:
iex> import Rummage.Ecto
iex> alias Rummage.Ecto.Product
iex> rummage = %{paginate: %{per_page: 1, page: 1}}
iex> repo = Rummage.Ecto.Repo
iex> Ecto.Adapters.SQL.Sandbox.checkout(repo)
iex> repo.insert!(%Product{name: "name", internal_code: "100"})
iex> repo.insert!(%Product{name: "name2", internal_code: "101"})
iex> opts = [paginate: Rummage.Ecto.Hook.Paginate,
...> repo: repo]
iex> {queryable, rummage} = rummage(Product, rummage, opts)
iex> rummage
%{paginate: %{max_page: 2, page: 1, per_page: 1, total_count: 2}}
iex> queryable
#Ecto.Query<from p0 in Rummage.Ecto.Product, limit: ^1, offset: ^0>