View Source EctoJuno

A simple query sorting library

installation

Installation

Add :ecto_juno to the list of dependencies in mix.exs

def deps do
  [
    {:ecto_juno, "~> 0.2.0"}
  ]
end

configuration

Configuration

You can specify default sorting field and mode in your config.exs:

  config :ecto_juno, sort_by: :id, sort_direction: :desc

The default sorting is by inserted_at field with asc mode

usage

Usage

Lets assume you have Accounts context with User schema and Repo module. To sort users pass your query, schema module and params into EctoJuno.Query.Sorting.sort_query/3

  alias EctoJuno.Query.Sorting

  def list_sorted_users(params) do
    User
    |> Sorting.sort_query(User, params)
    |> Repo.all()
  end

Where params structure is

  %{"sort_by" => "id", "sort_direction" => "desc"}

You can also pass sorting parameters keys as atoms:

  Sorting.sort_query(query, User, %{sort_by: "id", sort_direction: "desc"})

Moreover, instead of the User schema module, you can pass a list of which elements are atoms:

  Sorting.sort_query(query, [:id, :age, :name, :inserted_at], %{sort_by: "id", sort_direction: "desc"})

If you not specify any of sorting parameters, than the default ones will be used:

  # The default sort_direction will be used
  Sorting.sort_query(query, User, %{sort_by: "id"})

  # The default sort_by will be used
  Sorting.sort_query(query, User, %{sort_direction: "desc"})

  # The default sorting which configurable will be used
  Sorting.sort_query(query, User)

If you'll pass invalid sorting parameters, than default sorting ones will be used for your query:

  Sorting.sort_query(query, User, %{sort_by: "invalid_field", sort_direction: "invalid_mode"})

by default will sort query by inserted_at field with asc mode

sorting-by-joint-query

Sorting by joint query

To apply sorting by joint query use EctoJuno.Query.Sorting.sort_query/4 which accepts the same arguments as EctoJuno.Query.Sorting.sort_query/3 except new fourth argument - joint query binding name.

Let's assume that you also have a posts table that related to users table as many to one. And posts have title column. Than your sorting function will be something like:

  alias EctoJuno.Query.Sorting

  def sort_users_by_posts do
    params = %{"sort_by" => "title", "sort_direction" => "desc"}

    User
    |> join(:left, [u], p in assoc(u, :posts), as: :posts)
    |> Sorting.sort_query(Post, params, :posts)
    |> Repo.all()
  end

If you provide binding that query doesn't have than sorting by base query in default mode will be applied

be-aware-of

Be aware of

  • Sorting with modes different from asc and desc is not supported
  • No custom validators for parameters supported
  • If you pass sort_by and sort_direction values not as strings you'll get exception

testing

Testing

  1. Clone repo: git clone https://github.com/senconscious/ecto_juno
  2. Set DATABASE_URL environment variable before running tests locally
  3. Run mix test --cov