ExSieve is filttering solution for Phoenix/Ecto. It builds Ecto.Query
struct from ransack inspired query language.
- Add
ex_sieve
to your list of dependencies inmix.exs
:
def deps do
[
{:ex_sieve, "~> 0.1.0"},
]
end
or use this:
def deps do
[
{:ex_sieve, github: "valyukov/ex_sieve"},
]
end
if you want to stick to mainstream
This is a work in progress, here's what is done right now:
- [WIP] Phoenix search form helpers
- Add advanced search documentation
- Custom query function (fragments or custom query functions)
- Demo project
First, setup your application repo:
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app
use ExSieve
end
defmodule MyApp.Post do
use Ecto.Schema
schema "posts" do
has_many :comments, MyApp.Comment
field :title
field :body
field :published, :boolean
timestamps
end
end
defmodule MyApp.Comment do
use Ecto.Schema
schema "comments" do
belongs_to :post, MyApp.Post
field :body
timestamps
end
end
def index(conn, %{"q"=> params}) do
posts = MyApp.Post |> MyApp.Repo.filter(params)
render conn, :index, posts: posts
end
Simple query:
{
"m": "or",
"q": {
"id_in": [1,2],
"title_and_body_cont": "text",
"comments_body_eq": "body",
"sort": ["title desc", "inserted_at asc"]
}
this is how query translate to the next SQL:
SELECT posts.* FROM posts INNER JOIN comments ON posts.id = comments.post_id \
WHERE posts.id IN (1, 2) \
OR (posts.title ILIKE '%text%' AND posts.body ILIKE '%text%') \
OR comments.body == "body" \
ORDER BY posts.title DESC, posts.inserted_at ASC;
Full list of supported predicates:
eq
not_eq
cont
not_cont
lt
lteq
gt
gteq
in
not_in
matches
does_not_match
start
not_start
end
not_end
true
not_true
false
not_false
present
blank
null
not_null
eq
not_eq
cont
not_cont
lt
lteq
gt
gteq
in
not_in
matches
does_not_match
start
not_start
end
not_end
true
not_true
false
not_false
present
blank
null
not_null
eq_any
eq_all
not_eq_any
not_eq_all
cont_any
cont_all
not_cont_any
not_cont_all
lt_any
lt_all
lteq_any
lteq_all
gt_any
gt_all
gteq_any
gteq_all
in_any
in_all
not_in_any
not_in_all
matches_any
matches_all
does_not_match_any
does_not_match_all
start_any
start_all
not_start_any
not_start_all
end_any
end_all
not_end_any
not_end_all
true_any
true_all
not_true_any
not_true_all
false_any
false_all
not_false_any
not_false_all
present_any
present_all
blank_any
blank_all
null_any
null_all
not_null_any
not_null_all
or
and
Example query key value with combinator:
{
"q": {
"title_or_body_cont": "text",
"inserted_at_and_updated_at_gteq": "2016-09-16T21:32:06"
}
}
Also, you can read more about predicates on ransack wiki page
Documentating in progress.
First, you'll need to build the test database.
MIX_ENV=test mix ecto.reset
This task assumes you have postgres installed and that your current user can create / drop databases. If you'd prefer to use a different user, you can specify it with the environment variable DB_USER
.
When the database built, you can now run the tests.
mix test
and
mix credo