# ARQO ![ARQO](docs/images/logo.png) ARQO (Active Record Query Objects) is a minimal gem that let you use Query Objects in an easy and Rails friendly way. It leverages `ActiveRecord` features and tries to make query objects as intuitive as possible for developers. In combination with the documentation we hope `ARQO` helps people keep their projects well structured and healthy. ![CI](https://github.com/rootstrap/arqo/workflows/ci/badge.svg) [![Maintainability](https://api.codeclimate.com/v1/badges/5ed2b32bfdf09746bd82/maintainability)](https://codeclimate.com/github/rootstrap/arqo/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/5ed2b32bfdf09746bd82/test_coverage)](https://codeclimate.com/github/rootstrap/arqo/test_coverage) ## Table of Contents - [Motivation](#motivation) - [Why ARQO?](#why-arqo) - [Installation](#installation) - [Usage](#usage) - [Setting up a query object](#setting-up-a-query-object) - [Deriving the model](#deriving-the-model) - [Chaining scopes](#chaining-scopes) - [Development](#development) - [Contributing](#contributing) - [License](#license) - [Code of Conduct](#code-of-conduct) - [Credits](#credits) ## Motivation `ActiveRecord` provides us with an amazing abstraction of the database structure, allowing us to write queries in a simple way. Unfortunately, models can grow large for several reasons, one of them being adding a lot of scopes or placing querying logic in methods. For this reason is that we created `ARQO`, so that the query logic is placed into specific objects responsible for building queries while not losing any of the benefits that Rails gives us. ### Why ARQO? - It is really simple, but still enough to have the best of Rails & query objects. - It will dynamically add scopes to your `ActiveRecord::Relation` instances, clearly making a separation of concerns by not making them accessible through the model. - It supports chaining methods defined in the query object just like when using Rails `scope`s. - It centralizes the querying logic of your models in a single source of truth. ## Installation Add this line to your application's Gemfile: ```ruby gem 'arqo' ``` And then execute: $ bundle install Or install it yourself as: $ gem install arqo ## Usage In the following sections we explain some basic usage and the API provided by the gem. ### Setting up a query object In order to use an `ARQO` query object, you need to inherit from `ARQO::Query` and define the `Scope` module inside it. Methods should be defined within the `Scope` module like this: ```ruby # app/queries/user_query.rb class UserQuery < ARQO::Query module Scope def active_last_week where('last_active_at > ?', 1.week.ago) end end end ``` And then you can use it from anywhere in your code. ```ruby UserQuery.new.active_last_week ``` ## Deriving the model In this previous example, the model was derived from the query object name. In case it's not derivable you should provide the `ActiveRecord::Relation` when initializing the query object, for example if you have: ```ruby # app/queries/custom_named_query.rb class CustomNamedQuery < ARQO::Query module Scope def active_last_week where('last_active_at > ?', 1.week.ago) end end end ``` you can use it like this: ```ruby CustomNamedQuery.new(User.all).active_last_week ``` you can also set the model class or relation to query from by overriding a simple method, like: ```ruby class CustomNamedQuery < ARQO::Query module Scope # ... end private def associated_relation User # you can also do something like User.some_scope end end ``` ## Chaining scopes Of course you can chain everything together, methods defined in the query object and scopes defined in the model or by Rails. ```ruby # app/queries/user_query.rb class UserQuery < ARQO::Query module Scope def active_last_week where('last_active_at > ?', 1.week.ago) end def not_deleted where(deleted_at: nil) end end end ``` And then you chain everything together and it will just work :) ```ruby UserQuery.new.where.not(name: nil).active_last_week.not_deleted.order(:id) ``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/rootstrap/arqo. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/rootstrap/arqo/blob/master/CODE_OF_CONDUCT.md). ## 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 ARQO project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/rootstrap/arqo/blob/master/CODE_OF_CONDUCT.md). ## Logo attribution Logo made by [iconixar](https://www.flaticon.com/free-icon/archery_3080892) from [www.flaticon.com](https://www.flaticon.com/) ## Credits ARQO is maintained by [Rootstrap](http://www.rootstrap.com) with the help of our [contributors](https://github.com/rootstrap/arqo/contributors). [](http://www.rootstrap.com)