View Source EctoSparkles (bonfire v0.3.5-classic-beta.4)

query_filter brings convenience and shortens the boilterplate of ecto queries

Common filters available include:

  • preload - Preloads fields onto the query results
  • start_date - Query for items inserted after this date
  • end_date - Query for items inserted before this date
  • before - Get items with IDs before this value
  • after - Get items with IDs after this value
  • ids - Get items with a list of ids
  • first - Gets the first n items
  • last - Gets the last n items
  • limit - Gets the first n items
  • offset - Offsets limit by n items
  • search - Warning: This requires schemas using this to have a &by_search(query, val) function

You are also able to filter on any natural field of a model, as well as use

  • gte/gt
  • lte/lt
  • like/ilike
  • is_nil/not(is_nil)
query_filter(User, %{name: %{ilike: "steve"}})
query_filter(User, %{name: %{ilike: "steve"}}, :last_name, :asc)
query_filter(User, %{name: %{age: %{gte: 18, lte: 30}}})
query_filter(User, %{name: %{is_banned: %{!=: nil}}})
query_filter(User, %{name: %{is_banned: %{==: nil}}})

my_query = query_filter(User, %{name: "Billy"})
query_filter(my_query, %{last_name: "Joe"})

Link to this section Summary

Functions

join_preload is a helper for preloading associations using joins.

AKA join_preload++. It's more powerful, but it does it with more (and different!) syntax.

reusable_join is similar to Ecto.Query.join/{4,5}, but can be called multiple times with the same alias.

Link to this section Functions

Link to this macro

join_preload(query, associations)

View Source (macro)

join_preload is a helper for preloading associations using joins.

By default, Ecto preloads associations using a separate query for each association, which can degrade performance. You could make it run faster by using a combination of join/preload, but that requires a bit of boilerplate (see example below).

With EctoSparkles, you can accomplish this with just one line of code.

example-using-just-ecto

Example using just Ecto

import Ecto.Query
Invoice
|> join(:left, [i], assoc(i, :customer), as: :customer)
|> join(:left, [i, c], assoc(c, :account), as: :account)
|> join(:left, [i], assoc(i, :lines), as: :lines)
|> preload([lines: v, customers: c, account: a], lines: v, customer: {c, [a: account]})
|> Repo.all()

example-using-join_preload

Example using join_preload

import EctoSparkles
Invoice
|> join_preload([:customer, :account])
|> join_preload([:lines])
|> Repo.all()
Link to this macro

proload(query, qual \\ :left, associations)

View Source (macro)

AKA join_preload++. It's more powerful, but it does it with more (and different!) syntax.

e.g.

proload(query, activity: [
  :verb, :boost_count, :like_count, :replied,
  # relations under object will have their aliases prefixed with object_, i.e.
  # :object_message, :object_post, :object_post_content
  # the original names will still be used for the associations.
  object: {"object_", [:message, :post, :post_content]}
])
Link to this function

query_filter(module_or_query, filters, order_by_prop \\ :id, order_direction \\ :desc)

View Source
Link to this macro

reusable_join(query, qual \\ :left, bindings, expr, opts)

View Source (macro)

reusable_join is similar to Ecto.Query.join/{4,5}, but can be called multiple times with the same alias.

Note that only the first join operation is performed, the subsequent ones that use the same alias are just ignored. Also note that because of this behaviour, it is mandatory to specify an alias when using this function.

This is helpful when you need to perform a join while building queries one filter at a time, because the same filter could be used multiple times or you could have multiple filters that require the same join, which poses a problem with how the filter/3 callback work, as you need to return a dynamic with the filtering, which means that the join must have an alias, and by default Ecto raises an error when you add multiple joins with the same alias.

To solve this, it is recommended to use this macro instead of the default Ecto.Query.join/{4,5}, in which case there will be only one join in the query that can be reused by multiple filters.