Project

criterion

0.0
No commit activity in last 3 years
No release in over 3 years
Criterion is a small, simple library for searching Ruby arrays and collections with a chainable, Active Record style query interface.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.8
>= 0
~> 10.0
 Project Readme

Criterion

Gem Version Build Status Code Climate Test Coverage Dependency Status

Criterion is a small, simple library for searching Ruby arrays and collections with a chainable, Active Record style query interface.

Installation

Add this line to your application's Gemfile:

gem 'criterion'

And then execute:

$ bundle

Or install it yourself as:

$ gem install criterion

Usage

Consider the following example:

require 'hashie'
require 'criterion'

matt = Hashie::Mash.new(name: 'Matt', age: 30) 
mark = Hashie::Mash.new(name: 'Mark', age: 45) 
john = Hashie::Mash.new(name: 'John', age: 50) 

collection = [ matt, mark, john ].extend(Criterion)

By extending the collection with the Criterion module, you can perform chainable queries with #where, #not, #order, #limit, #offset/#skip, and calculations with #sum, #maximum, #minimum, #average.

Where

Where is the primary method for searching a Criterion collection. All query values must match in order for a result to be returned.

Calling any query method without a value will return a Criterion::Criteria:

collection.where
#=> #<Criterion::Criteria...

Searching by exact value:

collection.where(name: 'Matt').first
#=> {"name"=>"Matt", "age"=>30}

Searching by regular expression:

collection.where(name: /J/).first
#=> {"name"=>"John", "age"=>50}

Searching by proc:

collection.where(age: ->(age){ age.odd? }).first
#=> {"name"=>"Mark", "age"=>45}

Searching by class:

collection.where(age: Integer).all
#=> [{"name"=>"Matt", "age"=>30}, {"name"=>"Mark", "age"=>45}, {"name"=>"John", "age"=>50}]

Searching by range:

collection.where(age: 42..48).all
#=> [{"name"=>"Mark", "age"=>45}]

Searching with multiple arguments or #where calls:

collection.where(name: 'Matt', age: 28...32)
# is equivalent to 
collection.where(name: 'Matt').where(age: 28...32)

All criteria must match to return a result:

collection.where(name: 'Matt', age: 40).empty?
#=> true

Or

As #where calls must match all query values, calling #or allows for an alternative query that will return results if either the #where or #or arguments match.

collection.where(name: 'Matt').or(name: 'John').to_a
#=> [{"name"=>"Matt", "age"=>30}, {"name"=>"John", "age"=>50}]

For #or to work, a #where query must also be performed.

Not

The #not method negates the query, returning matches that do not match all of the specified values. Like #where, #not can search by exact value, regular expression, class, proc, and range.

collection.not(name: 'Matt').all 
#=> [{"name"=>"Mark", "age"=>45}, {"name"=>"John", "age"=>50}]

All values must match for result to be excluded:

collection.not(name: 'Matt', age: 40).empty?
#=> true 

Limit

Limit the number of results returned:

collection.where(age: 0..100).limit(2).count
#=> 2 

Offset

Skip the specified number of records before returning a result:

collection.where(age: 0..100).offset(1).first
#=> {"name"=>"Mark", "age"=>45}

Order

Specify the field or fields with which to order the results:

collection.order(:name).first
#=> {"name"=>"John", "age"=>50}

Ascending order is assumed by default, but descending can be specified:

collection.order(age: :desc).first
#=> {"name"=>"John", "age"=>50}

Calculations

A calculation method can be called end of the criteria chain to perform on operation on one of the collection's attributes.

# Sum / total for a field: 
collection.where(age: 35..55).sum(:age)
#=> 95

# Maximum value for a field: 
collection.maximum(:age)
#=> 50 

# Minimum value for a field:
collection.minimum(:age)
#=> 30 

# Average value for a field:
collection.average(:age)
#=> 41.666666666666664

# When there are no values in the collection, nil is returned:
collection.where(age: 0..1).average(:age)
#=> nil 

Development

After checking out the repo, run bin/setup to install dependencies. Then, 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 to create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

  1. Fork it ( https://github.com/[my-github-username]/criterion/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request