# AstSimpleFilter
When start working with Absinthe, I want to add the ability to filter a given model by any fields using `eq`, `lt`, `gt`, `in`,...
So I created this package, it does 2 things:
1. Allow to add `filters` and `pagination` parameters to GraphQL query.
2. Allow to filter a model using the above `filters` parameter
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/ast_simple_filter](https://hexdocs.pm/ast_simple_filter).
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `ast_simple_filter` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:ast_simple_filter, "~> 0.0.1"}
]
end
```
## Usage
### Add `filter`
#### Define some common types (Optional):
`use AstSimpleFilter.DefineCommonObjects`
This will define:
`:asf_datetime` scalar to use for datetime fields.
`:asf_date` scalar to use for date fields.
`:asf_pagination_info` object, which contains `total` entries, `page_number` and `per_page`.
`:ast_pagination_input` input, which allows to specify `page_number` and `per_page`.
#### Define output (Optional)
`use AstSimpleFilter.DefineTypes, base_name: :<base_name>, field_types: <field_types_list>, custom_datetime_type: :<custom_datetime_type>, :custom_date_type: :<custom_date_type>, custom_meta_type: :<custom_meta_type>`
Example of a `<field_types_list>` is: `[{id: :id}, {age: :integer}, {email: :string}]`. We can replace `field_types: [...]` by `kclass: <Model>`, in this case, it will include all fields of `<Model>` into `<base_name>_custom_fields`, If we omit `custom_datetime_type: :<custom_datetime_type>, :custom_date_type: <custom_date_type>, custom_meta_type: <custom_meta_type>`, then we need to define common types first (Step above).
This will define 2 objects:
`:<base_name>_custom_fields`
```
object :<base_name>_results do
field :data, list_of(:<base_name>_custom_fields)
field :meta, :asf_pagination_info (or :custom_meta_type)
end
```
#### Define filter input
`use AstSimpleFilter.DefineFilterInput, base_name: :<base_name>, field_types: <field_types_list>`
Example of a `<field_types_list>` is: `[{id: :id}, {age: :integer}, {email: :string}]`. Again, we can replace `field_types: [...]` by `kclass: <Model>`
This will define an input like this:
```
input_object user_filter_input do
field age_eq :integer
field age_neq :integer
field age_lt :integer
field age_lte :integer
field age_gt :integer
field age_gte :integer
field age_in list_of(:integer)
field age_nin list_of(:integer)
field age_nil :boolean
end
```
Then we can define query like this
```
query do
@desc "Get a list of users"
field :users, :user_results do
arg(:filters, :user_filter_input)
arg(:pagination, :asf_pagination_input)
resolve fn _parent, args, resolution ->
...
end
end
end
```
### Add `asf_filter` function
In `<model>` add:
```
import Ecto.Query
use AstSimpleFilter.DefineFilterFunctions, <Model>
```
This will define `asf_filter(%{})` function, which accept the `arg.filters` to filter `<Model>`
Note that because the `asf_filter` use `Ecto.Query`, so we need to import it first.
## Example
https://github.com/tranngocsam/absinthe-simple-filter