# Rummage.Ecto
[![Build Status](https://travis-ci.org/Excipients/rummage_ecto.svg?branch=master)](https://travis-ci.org/Excipients/rummage_ecto)
[![Coverage Status](https://coveralls.io/repos/github/Excipients/rummage_ecto/badge.svg?branch=master)](https://coveralls.io/github/Excipients/rummage_ecto?branch=master)
[![Hex Version](http://img.shields.io/hexpm/v/rummage_ecto.svg?style=flat)](https://hex.pm/packages/rummage_ecto)
[![hex.pm downloads](https://img.shields.io/hexpm/dt/rummage_ecto.svg)](https://hex.pm/packages/rummage_ecto)
[![Hex docs](http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat)](https://hexdocs.pm/rummage_ecto)
[![docs](https://inch-ci.org/github/Excipients/rummage_ecto.svg)](http://inch-ci.org/github/Excipients/rummage_ecto)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/Excipients/rummage_ecto/master/LICENSE)
**If you're looking for full `Phoenix` support, `Rummage.Phoenix` uses `Rumamge.Ecto` and adds `HTML` and `Controller` support
to it. You can check `Rummage.Phoenix` out by clicking [here](https://github.com/Excipients/rummage_phoenix)**
**Please refer for [CHANGELOG](CHANGELOG.md) for version specific changes**
`Rummage.Ecto` is a 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 `Rumamge.Ecto.Hook` behavior.
Each operation: `Search`, `Sort` and `Paginate` have their hooks defined in `Rummage`. By doing this, `Rummage` is 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.
**NOTE: `Rummage` is not like `Ransack`, and doesn't intend to be. It doesn't define functions based on search params.
If you'd like to have that for a model, you can always configure `Rummage` to use your `Search` module for that model. This
is why Rummage has been made configurable.**
## Installation
This package is [available in Hex](https://hexdocs.pm/rummage_ecto/), and can be installed as:
- Add `rummage_ecto` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[{:rummage_ecto, "~> 1.0.0"}]
end
```
## Configuration (Optional, If no configuration is provided `Rummage` will use default hooks)
- If you want to override any of the `Rummage` default hooks,
add `rummage_ecto` config to your list of configs in `dev.exs`:
```elixir
config :rummage_ecto,
Rummage.Ecto,
default_search: MyApp.SearchModule
```
- Other config options are: `default_repo`, `default_sort`, `default_paginate`, `default_per_page`
- `Rumamge.Ecto` can be configured globally with a `default_per_page` value (which can be overridden for a model).
This is **NOT** the preferred way to set `per_page` as it might lead to conflicts. It is recommended to
do it per model as show below in the [Initial Setup](#initial-setup) section, as it gives the developer more
flexibility. If you want to set per_page for all the models, add it to `model` function in `web.ex`.
## Usage
`Rummage.Ecto` comes with a lot of powerful features which are available right away, without writing a bunch of code.
Below are the ways `Rummage.Ecto` can be used:
### Basic Usage:
- Add the `Repo` of your app and the desired `per_page` (if using Rumamge's Pagination) to the `rummage_ecto` configuration in `config.exs`:
```elixir
config :rummage_ecto, Rummage.Ecto,
default_repo: MyApp.Repo,
default_per_page: 10
```
- Use `Rummage.Ecto` in the models or ecto_structs:
```elixir
defmodule MyApp.Product do
use MyApp.Web, :model
use Rummage.Ecto
# More code below....
end
```
- And you should be able to use `Rummage.Ecto` with `Product` model.
### Advanced Usage:
- Coming soon...
### Usage ( not after 0.6.0 )
- Setting up the application above will allow us to do the following:
```elixir
rummage = %{
"search" => %{"name" => "value1", "category" => "value2"},
"sort" => "name.desc",
"paginate" => %{"per_page" => "5", "page" => "1"}
}
{queryable, rummage} = queryable
|> Product.rummage(rummage)
products = queryable
|> Product.another_operation # <-- Since `Rummage` is Ecto, we can pipe the result queryable into another queryable operation.
|> Repo.all
```
- Rummage responds to `params` with keys: `search`, `sort` and/or `paginate`. It doesn't need to have all the keys, or any keys for that matter.
If invalid keys are passed, they won't alter any operations in rummage. Here's an example of `Rummage` params:
```elixir
%{
"search" => %{"name" => "value1", "category" => "value2"},
"sort" => "name.desc",
"paginate" => %{"per_page" => "5", "page" => "1"}
}
```