Module: IndexQueryBuilder

Defined in:
lib/index_query_builder.rb,
lib/index_query_builder/version.rb,
lib/index_query_builder/query_builder.rb,
lib/index_query_builder/query_definition.rb

Overview

Simple DSL for building queries using filters.

This module makes it easy to fetch records from the database, specially for showing and filtering records in an index page

Defined Under Namespace

Classes: QueryBuilder, QueryDefinition, UnknownOperator

Constant Summary collapse

VERSION =
"0.0.2"

Class Method Summary collapse

Class Method Details

.query(base_scope, options = {}) {|QueryDefinition| ... } ⇒ Arel

Builds a query by calling arel methods on base_scope

Example

posts = IndexQueryBuilder.query Post.where(:user_id => user.id), with: { title: 'DSLs are awesome' } do |query|
  query.filter_field :posted
  query.filter_field :title, contains: :title
  query.filter_field :posted_date,
    greater_than_or_equal_to: :from_posted_date, less_than: :to_posted_date
  query.filter_field [:comments, :author, :name], equal_to: :comment_author_name

  query.order_by "posted_date DESC, posts.created_at DESC"
end

Parameters:

  • base_scope (Arel)

    used to build query on top of this scope

  • options (Hash) (defaults to: {})
  • :with (Hash)

    a customizable set of options

Yields:

  • (QueryDefinition)

    Gives a QueryDefinition object that implements a DSL to define how to apply filters

Returns:

  • (Arel)

    returns arel object to make it easy to extend query (e.g. add pagination, etc)



33
34
35
36
37
38
# File 'lib/index_query_builder.rb', line 33

def self.query(base_scope, options={}, &block)
  query_definition = QueryDefinition.new
  block.call(query_definition)

  QueryBuilder.apply(base_scope, query_definition, filters(options))
end

.query_children(child_association, base_scope, options = {}) {|QueryDefinition| ... } ⇒ Arel

Builds a query by calling arel methods on base_scope, but it returns children of base scope. Use this method when using same filters as when querying the parent, but want to get back all children instead. This way, you can reuse same query definition you used for IndexQueryBuilder.query.

Example

comments = IndexQueryBuilder.query_children :comments, Comments, with: { title: 'DSLs are awesome' } do |query|
  query.filter_field :posted
  query.filter_field :title, contains: :title
  query.filter_field :posted_date,
    greater_than_or_equal_to: :from_posted_date, less_than: :to_posted_date
  query.filter_field [:comments, :author, :name], equal_to: :comment_author_name

  query.order_by "comment_date DESC"
end

Parameters:

  • child_association (Symbol)

    children’s association name

  • base_scope (Arel)

    used to build query on top of this scope

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :with (Hash)

    filters used to build query. Key is filter name, value is value for the filter

Yields:

  • (QueryDefinition)

    Gives a QueryDefinition object that implements a DSL to define how to apply filters

Returns:

  • (Arel)

    returns arel object to make it easy to extend query (e.g. add pagination, etc)



62
63
64
65
66
# File 'lib/index_query_builder.rb', line 62

def self.query_children(child_association, base_scope, options={}, &block)
  parents = query(base_scope.eager_load(child_association), options, &block)

  children_of(parents, child_association, base_scope)
end