Permalink
Browse files

Adds Any and All functions

  • Loading branch information...
1 parent a27761f commit c8721812e962ca58c8bfda6113ce56f56c20f24e @danmcclain danmcclain committed Feb 8, 2013
@@ -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)
@@ -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
@@ -1,39 +0,0 @@
-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
- describe '.where(:array_column => [])' do
- it 'returns an array string instead of IN ()' do
- query = OverlapArelArray.where(:tags => ['working']).to_sql
- query.should match /\"overlap_arel_arrays\"\.\"tags\" = '\{\"working\"\}'/
- 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_arel_arrays\"\.\"tag_ids\" && '\{1,2\}'/
- end
-
- it 'allows chaining' do
- query = OverlapArelArray.where.overlap(:tag_ids => [1,2]).where(:tags => ['working']).to_sql
-
- query.should match /\"overlap_arel_arrays\"\.\"tag_ids\" && '\{1,2\}'/
- query.should match /\"overlap_arel_arrays\"\.\"tags\" = '\{\"working\"\}'/
- end
- end
-end

0 comments on commit c872181

Please sign in to comment.