Skip to content

Commit

Permalink
Adds Any and All functions
Browse files Browse the repository at this point in the history
  • Loading branch information
danmcclain committed Feb 8, 2013
1 parent a27761f commit c872181
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 40 deletions.
24 changes: 23 additions & 1 deletion lib/postgres_ext/active_record/relation/query_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,34 @@ def initialize(scope)
end

def overlap(opts)
arel_table = @scope.engine.arel_table
opts.each do |key, value|
arel_table = @scope.engine.arel_table
@scope = @scope.where(arel_table[key].array_overlap(value))
end
@scope
end

def any(opts)
equality_to_function('ANY', opts)
end

def all(opts)
equality_to_function('ALL', opts)
end

private

def equality_to_function(function_name, opts)
arel_table = @scope.engine.arel_table

opts.each do |key, value|
any_function = Arel::Nodes::NamedFunction.new(function_name, [arel_table[key]])
predicate = Arel::Nodes::Equality.new(value, any_function)
@scope = @scope.where(predicate)
end

@scope
end
end

def where_with_chaining(opts = :chaining, *rest)
Expand Down
72 changes: 72 additions & 0 deletions spec/queries/array_queries_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require 'spec_helper'

describe 'where array clauses' do
let!(:adapter) { ActiveRecord::Base.connection }

before do
adapter.create_table :overlap_arel_arrays, :force => true do |t|
t.string :tags, :array => true
t.integer :tag_ids, :array => true
end

class OverlapArelArray < ActiveRecord::Base
attr_accessible :tags, :tags_ids
end
end
after do
adapter.drop_table :overlap_arel_arrays
end
let(:equality_regex) { %r{\"overlap_arel_arrays\"\.\"tags\" = '\{\"working\"\}'} }
let(:overlap_regex) { %r{\"overlap_arel_arrays\"\.\"tag_ids\" && '\{1,2\}'} }
let(:any_regex) { %r{2 = ANY\(\"overlap_arel_arrays\"\.\"tag_ids\"\)} }
let(:all_regex) { %r{2 = ALL\(\"overlap_arel_arrays\"\.\"tag_ids\"\)} }

describe '.where(:array_column => [])' do
it 'returns an array string instead of IN ()' do
query = OverlapArelArray.where(:tags => ['working']).to_sql
query.should match equality_regex
end
end

describe '.where.overlap(:column => value)' do
it 'generates the appropriate where clause' do
query = OverlapArelArray.where.overlap(:tag_ids => [1,2])
query.to_sql.should match overlap_regex
end

it 'allows chaining' do
query = OverlapArelArray.where.overlap(:tag_ids => [1,2]).where(:tags => ['working']).to_sql

query.should match overlap_regex
query.should match equality_regex
end
end

describe '.where.any(:column => value)' do
it 'generates the appropriate where clause' do
query = OverlapArelArray.where.any(:tag_ids => 2)
query.to_sql.should match any_regex
end

it 'allows chaining' do
query = OverlapArelArray.where.any(:tag_ids => 2).where(:tags => ['working']).to_sql

query.should match any_regex
query.should match equality_regex
end
end

describe '.where.all(:column => value)' do
it 'generates the appropriate where clause' do
query = OverlapArelArray.where.all(:tag_ids => 2)
query.to_sql.should match all_regex
end

it 'allows chaining' do
query = OverlapArelArray.where.all(:tag_ids => 2).where(:tags => ['working']).to_sql

query.should match all_regex
query.should match equality_regex
end
end
end
39 changes: 0 additions & 39 deletions spec/queries/overlap_spec.rb

This file was deleted.

0 comments on commit c872181

Please sign in to comment.