/ecto_filters

Primary LanguageElixirMIT LicenseMIT

Hex.pm Hex.pm Hex.pm Hex.pm

Travis

Ecto.Filters

Provides a consistent way to compose ecto query expressions.

Installation

def deps do
  [
    {:ecto_filters, "~> 0.3.0"}
  ]
end

Usage

defmodule Posts do
  use Ecto.Filters
  alias MyProject.{Post, Repo}

  filter(:comment_body, fn query, value ->
    query
    |> join(:left, [p], c in assoc(p, :comments), as: :comments)
    |> where([comments: comments], ilike(comments.body, ^value))
  end)

  @doc """
  Returns the list of posts

  ## Examples

      iex> list_posts(%{"search" => %{"comment_body" => "ecto_filters"}})
      [%Post{}, ...]

      iex> list_posts(%{search: %{comment_body: "ecto_filters"}})
      [%Post{}, ...]

      iex> list_posts(search: [comment_body: "ecto_filters"])
      [%Post{}, ...]

  """
  def list_posts(params) do
    Post
    |> apply_filters(params)
    |> Repo.all()
  end
end

When defining a new filter, Ecto.Filters writes a new public function to your context.

So the two examples below are equivalent to each other

  filter(:title, &where(&1, title: ^&2))

  def filter_by(query, :title, value) do
    where(query, title: ^value)
  end

Knowing that allows the reuse of filters defined by the filter macro in custom functions. For example...

  filter(:published, &where(&1, published: ^&2))

  def get_published_post!(id) do
    Post
    |> filter_by(:published, true)
    |> Repo.get!(id)
  end

Options for apply_filters/2

  • :key - The key to use for passing filters. The default is filters.
  • :ignore_bad_filters - Whether or not an exception should be raised when using a filter that has not been defined.

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ecto_filters.