Query Builder
Query Builder allows you to build and compose Ecto queries based on data.
Its primary goal is to allow Context functions to receive filters and options to avoid having to create many different functions for every combination of filters and options:
Blog.list_articles(preload: [:comments], order_by: [title: :asc])
Blog.list_articles(preload: [:category, comments: :user])
The calling code (e.g. the Controllers), can now retrieve the list of articles with different options. In some part of the application, the category is needed; in other parts it is not, however the articles must be sorted based on their title, etc.
See QueryBuilder.from_list/2
below.
Examples
User
|> QueryBuilder.where(firstname: "John")
|> QueryBuilder.where([{:age, :gt, 30}, city: "Anytown"])
|> QueryBuilder.order_by(lastname: :asc)
|> QueryBuilder.preload([:role, authored_articles: :comments])
|> Repo.all()
Filtering on associations is supported:
User
|> QueryBuilder.where(:role, name@role: "admin")
|> Repo.all()
User
|> QueryBuilder.where([role: :permission], name@permission: "delete")
|> Repo.all()
Article
|> QueryBuilder.where(:author, id@author: author_id)
|> QueryBuilder.where([:author, :comments], {:logged_at@author, :lt, :inserted_at@comments})
|> QueryBuilder.preload(:comments)
|> Repo.all()
Usage
Add use QueryBuilder
in your schema:
defmodule MyApp.User do
use Ecto.Schema
use QueryBuilder
schema "users" do
# code
end
# code
end
You may also specify the schema's associations to QueryBuilder
in order to remedy
some limitations when building queries:
defmodule MyApp.User do
use Ecto.Schema
use QueryBuilder, assoc_fields: [:role, :articles]
schema "users" do
# code
belongs_to :role, MyApp.Role
has_many :articles, MyApp.Article
end
# code
end
Currently supported operations are:
QueryBuilder.where(query, firstname: "John")
QueryBuilder.where(query, [role: :permissions], name@permissions: :write)
QueryBuilder.order_by(query, lastname: :asc, firstname: :asc)
QueryBuilder.order_by(query, :articles, title@articles: :asc)
QueryBuilder.preload(query, [role: :permissions, articles: [:stars, comments: :user]])
QueryBuilder.join(query, :articles, :left)
QueryBuilder.from_list(query, [
where: [name: "John", city: "Anytown"],
preload: [articles: :comments]
])
Installation
Add query_builder
for Elixir as a dependency in your mix.exs
file:
def deps do
[
{:query_builder, "~> 0.2.0"}
]
end
HexDocs
HexDocs documentation can be found at https://hexdocs.pm/query_builder.