Arels in your Wharels in your Queries, oh my!
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin
certs
lib
spec
.gitignore
.rspec
.travis.yml
Gemfile
LICENSE.txt
README.md
Rakefile
wharel.gemspec

README.md

Wharel

Build Status

Wharel helps you write concise Arel queries with ActiveRecord using Virtual Rows inspired by Sequel.

Although similar in spirit to gems like Squeel and BabySqueel, which provide sophisticated block-based interfaces for querying with Arel, Wharel is much much smaller. In fact, the core of the gem is only 30 lines long! It uses a single BasicObject as a clean room to evaluate the query block. That's really all there is to it.

For a more detailed explanation of the implementation, see this blog post.

Installation

Add this line to your application's Gemfile:

gem 'wharel', '~> 0.2.0'

And then execute:

$ bundle

Or install it yourself as:

$ gem install wharel

Usage

Suppose we have a model Post:

class Post < ApplicationRecord
  has_many :comments
end

And let's assume our Post has columns title and content.

Now, if we wanted to find all the posts with a title which matched the string "foo" and content which matched the string "bar", we'd have to resort to something like this:

title = Post.arel_table[:title]
content = Post.arel_table[:content]
Post.where(title.matches("foo").and(content.matches("bar")))

With Wharel, you can drop the boilerplate and just use a block:

Post.where { title.matches("foo").and(content.matches("bar")) }

Wharel will map title and content in the block to the appropriate Arel attribute for the column.

Works with where.not too:

Post.where.not { title.eq("foo") }

Now suppose we have another model Comment with a column content, and a Post has_many :comments:

class Post < ApplicationRecord
  has_many :comments
end

class Comment < ApplicationRecord
  belongs_to :post
end

Now we want to find all comments which match the title of the comment's post. With standard Arel, you could do this with:

posts = Post.arel_table
comments = Comment.arel_table
Comment.joins(:post).where(comments[:content].matches(posts[:title]))

Using Wharel, you can pass an argument to blocks to handle this case:

Comment.joins(:post).where { |c| Post.where { |p| c.content.matches(p.title) } }

Much better!

Contributing

Notice something wrong or a feature missing? Post an issue or create a pull request.

License

The gem is available as open source under the terms of the MIT License.