# QueryHelper [![TravisCI](https://travis-ci.org/iserve-products/query_helper.svg?branch=master)](https://travis-ci.org/iserve-products/query_helper) [![Gem Version](https://badge.fury.io/rb/query_helper.svg)](https://badge.fury.io/rb/query_helper) Ruby Gem developed and used at Pattern to paginate, sort, filter, and include associations on sql and active record queries. ## Installation Add this line to your application's Gemfile: ```ruby gem 'query_helper' ``` And then execute: $ bundle Or install it yourself as: $ gem install query_helper ## Use ### SQL Queries #### Initialize To create a new sql query object run ```ruby QueryHelper::Sql.new( model:, # required query:, # required query_params: , # optional column_mappings: , # optional filters: , # optional sorts: , # optional page: , # optional per_page: , # optional single_record: , # optional, default: false associations: , # optional as_json_options: , # optional run: # optional, default: true ) ``` The following arguments are accepted when creating a new objects
Argument Description Example
model the model to run the query against
Parent
query the custom sql string to be executed
'select * from parents'
query_params a hash of bind variables to be embedded into the sql query
{
  age: 20,
  name: 'John'
}
column_mappings A hash that translates aliases to sql expressions
{
  "age" => "parents.age"
  "children_count" => {
    sql_expression: "count(children.id)",
    aggregate: true
  }
}
filters a list of filters in the form of `{"comparate_alias"=>{"operator_code"=>"value"}}`
{
  "age" => { "lt" => 100 },
  "children_count" => { "gt" => 0 }
}
sorts a comma separated string with a list of sort values
"age:desc,name:asc:lowercase"
page the page you want returned
5
per_page the number of results per page
20
single_record whether or not you expect the record to return a single result, if toggled, only the first result will be returned
false
associations a list of activerecord associations you'd like included in the payload

as_json_options a list of as_json options you'd like run before returning the payload

run whether or not you'd like to run the query on initilization
false
### Active Record Queries To run an active record query execute ```ruby QueryHelper.run_active_record_query(active_record_call, query_helpers, valid_columns, single_record) ``` active_record_call: Valid active record syntax (i.e. ```Object.where(state: 'Active')```) query_helpers: See docs below valid_columns: Default is []. Pass in an array of columns you want to allow sorting and filtering on. single_record: Default is false. Pass in true to format payload as a single object instead of a list of objects model: A valid ActiveRecord model query: A string containing your custom SQL query query_params: a symbolized hash of binds to be included in your SQL query query_helpers: See docs below valid_columns: Default is []. Pass in an array of columns you want to allow sorting and filtering on. single_record: Default is false. Pass in true to format payload as a single object instead of a list of objects ## Query Helpers query_helpers is a symbolized hash passed in with information about pagination, associations, filtering and sorting. ### Pagination There are two pagination keys you can pass in as part of the query_helpers objects ```ruby { page: 1, per_page: 20 } ``` If at least one of these keys is present, paginated results will be returned. ### Sorting Sorting is controlled by the `sort` key in the query_helpers object ```ruby { sort: "column_name:sort_direction" } ``` Sort direction can be either asc or desc. If you wish to lowercase string before sorting include the following: ```ruby { sort: "name:desc:lowercase" } ``` ### Filtering Filtering is controlled by the `filter` object in the query_helpers hash ```ruby { filter: { "column_1" => { "gte" => 20, "lt" => 40 }, "column_2" => { "eql" => "my_string" }, "column_3" => { "like" => "my_string%" }, "column_4" => { "in" => "item1,item2,item3" } } ``` The following operator codes are valid ``` “gte”: >= “lte”: <= “gt”: > “lt”: < “eql”: = “noteql”: != "like": like “in”: in “notin” not in “null”: “is null” or “is not null” (pass in true or false as the value) ``` ### Associations To include associated objects in the payload, pass in the following as part of the query_helpers hash: ```ruby { include: ['associated_object_1', 'associated_object_2'] } ``` ### Example The following is an example of a query_helpers object that can be passed into the sql and active record methods ```ruby query_helpers = { page: 1, per_page: 20, sort: "name:desc" include: ["child"] filter: { "id" => { "gte" => 20, "lt" => 40 } } ``` ## Payload Formats The QueryHelper gem will return results in one of three formats ### Paginated List Payload ```json { "pagination": { "count": 18, "current_page": 1, "next_page": 2, "previous_page": null, "total_pages": 6, "per_page": 3, "first_page": true, "last_page": false, "out_of_range": false }, "data": [ { "id": 1, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 }, { "id": 2, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 }, { "id": 3, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 }, ] } ``` ### List Payload ```json { "data": [ { "id": 1, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 }, { "id": 2, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 }, { "id": 3, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 }, ] } ``` ### Single Record Payload ```json { "data": { "id": 1, "attribute_1": "string_attribute", "attribute_2": 12345, "attribute_3": 0.3423212 } } ``` ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/query_helper. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. ## License The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). ## Code of Conduct Everyone interacting in the QueryHelper project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/query_helper/blob/master/CODE_OF_CONDUCT.md).