Organize complex queries
Encapsulate query logic in dedicated, testable classes with a clean, fluent API.
Composable, testable, and reusable query objects for Ruby on Rails.
Encapsulate query logic in dedicated, testable classes with a clean, fluent API.
Combine multiple query objects using the + operator at both the instance and class level.
Built on the Literal gem for typed properties with validation.
Automatic pagination for both database and collection queries.
Works with ActiveRecord relations and plain Ruby collections.
Chain methods just like ActiveRecord.
quo is a Ruby gem that helps you organize database and collection queries into reusable, composable, and testable objects with a clean, fluent API.
# Define query objects to encapsulate query logic
class RecentPostsQuery < Quo::RelationBackedQuery
# Type-safe properties with defaults
prop :days_ago, Integer, default: -> { 7 }
def query
Post.where(Post.arel_table[:created_at].gt(days_ago.days.ago))
.order(created_at: :desc)
end
end
# Use queries with pagination
posts_query = RecentPostsQuery.new(days_ago: 30, page: 1, page_size: 10)
page1 = posts_query.results
# => Returns first 10 posts from the last 30 days
# Navigate between pages
page2_query = posts_query.next_page_query
page2 = page2_query.results
# => Returns next 10 posts
# Compose queries
class CommentNotSpamQuery < Quo::RelationBackedQuery
prop :spam_score_threshold, _Float(0..1.0)
def query
comments = Comment.arel_table
Comment.where(
comments[:spam_score].eq(nil).or(comments[:spam_score].lt(spam_score_threshold))
)
end
end
# Get recent posts (last 10 days) which have comments that are not spam
posts_last_10_days = RecentPostsQuery.new(days_ago: 10).joins(:comments)
query = posts_last_10_days + CommentNotSpamQuery.new(spam_score_threshold: 0.5)
# Transform results
transformed_query = query.transform { |post| PostPresenter.new(post) }
# Work with result sets
transformed_query.results.each do |presenter|
puts presenter.formatted_title
end
Explore the documentation to learn more:
Add to your Gemfile:
gem "quo"
Then execute:
$ bundle install
Bug reports and pull requests are welcome on GitHub at https://github.com/stevegeek/quo.
The gem is available as open source under the terms of the MIT License.
This implementation is inspired by the Rectify gem by Andy Pike. Thanks for the inspiration!
Key differences to Quo:
| operator directly inspired Quo’s composable designQuo as an alternative?
Quo can be seen as a successor to Rectify’s query object concepts.