Filterable
Filterable allows to map incoming controller parameters to filter functions.
Installation
Add filterable
to your mix.exs.
{:filterable, "~> 0.0.2"}
Then use
Filterable module inside controller or make it available for all application controllers by adding it to web.ex
:
def controller do
quote do
use Phoenix.Controller
use Filterable
...
end
end
Usage
Common usage:
defmodule Application.PostController do
use MyApp.Web, :controller
use Filterable
alias MyApp.Post
defmodule Filterable do
def title(_conn, query, value) do
query |> where(title: ^value)
end
end
def index(conn, params) do
posts = Post |> apply_filters(conn) |> Repo.all
render(conn, "index.html", posts: posts)
end
end
By default apply_filters
uses filter functions defined in ControllerModule.Filterable
module.
Lets define some complex filters in separate module:
defmodule AvailableFilters do
def title(_, query, value) do
query |> where(title: ^value)
end
def condition(_, query, value) when value in ~w(published archived) do
query |> where(condition: ^value)
end
def author(conn, query, value) when value == "current_user" do
query |> where(author_id: ^current_user(conn).id)
end
def author(_, query, value) do
query |> where(author_name: ^value)
end
end
Then we can link filter functions from this module by calling filterable
macro inside controller:
defmodule Application.PostController do
...
filterable AvailableFilters
def index(conn, params) do
posts = Post |> apply_filters(conn) |> Repo.all
render(conn, "index.html", posts: posts)
end
end
Also we can specify top level filters query param with filterable
marco:
filterable AvailableFilters, param: "filter"
This could be useful for working with json-api filters query.
Contribution
Feel free to send your PR with proposals, improvements or corrections!