aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/TODO2
-rw-r--r--lib/arel/predicates.rb21
-rw-r--r--spec/arel/unit/predicates/binary_spec.rb27
-rw-r--r--spec/arel/unit/predicates/predicates_spec.rb33
4 files changed, 82 insertions, 1 deletions
diff --git a/doc/TODO b/doc/TODO
index 0f688bc258..65f9cfbca7 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -14,7 +14,6 @@ users.delete().where(
SELECT users.*, (SELECT count(id) FROM addresses WHERE
addresses.user_id=users.id) FROM users
-- and/or w/ predicates
- blocks for all operations
- result sets to attr correlation too
- cache expiry on write
@@ -23,6 +22,7 @@ users.delete().where(
- scoped writes
done:
+- and/or w/ predicates
- mock out database
. Relation <=> Relation -> InnerJoinOperation
. Relation << Relation -> LeftOuterJoinOperation
diff --git a/lib/arel/predicates.rb b/lib/arel/predicates.rb
index a83bad3c22..051f8abdad 100644
--- a/lib/arel/predicates.rb
+++ b/lib/arel/predicates.rb
@@ -1,5 +1,12 @@
module Arel
class Predicate
+ def or(other_predicate)
+ Or.new(self, other_predicate)
+ end
+
+ def and(other_predicate)
+ And.new(self, other_predicate)
+ end
end
class Binary < Predicate
@@ -21,6 +28,20 @@ module Arel
end
alias_method :to_s, :to_sql
end
+
+ class CompoundPredicate < Binary
+ def to_sql(formatter = nil)
+ "(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})"
+ end
+ end
+
+ class Or < CompoundPredicate
+ def predicate_sql; "OR" end
+ end
+
+ class And < CompoundPredicate
+ def predicate_sql; "AND" end
+ end
class Equality < Binary
def ==(other)
diff --git a/spec/arel/unit/predicates/binary_spec.rb b/spec/arel/unit/predicates/binary_spec.rb
index 5dee4833d4..56fcf2d8ad 100644
--- a/spec/arel/unit/predicates/binary_spec.rb
+++ b/spec/arel/unit/predicates/binary_spec.rb
@@ -13,6 +13,33 @@ module Arel
end
end
+ describe "with compound predicates" do
+ before do
+ @operand1 = ConcreteBinary.new(@attribute1, 1)
+ @operand2 = ConcreteBinary.new(@attribute2, "name")
+ end
+
+ describe Or do
+ describe "#to_sql" do
+ it "manufactures sql with an OR operation" do
+ Or.new(@operand1, @operand2).to_sql.should be_like("
+ (`users`.`id` <=> 1 OR `users`.`name` <=> 'name')
+ ")
+ end
+ end
+ end
+
+ describe And do
+ describe "#to_sql" do
+ it "manufactures sql with an AND operation" do
+ And.new(@operand1, @operand2).to_sql.should be_like("
+ (`users`.`id` <=> 1 AND `users`.`name` <=> 'name')
+ ")
+ end
+ end
+ end
+ end
+
describe '#to_sql' do
describe 'when relating two attributes' do
it 'manufactures sql with a binary operation' do
diff --git a/spec/arel/unit/predicates/predicates_spec.rb b/spec/arel/unit/predicates/predicates_spec.rb
new file mode 100644
index 0000000000..d11637cabe
--- /dev/null
+++ b/spec/arel/unit/predicates/predicates_spec.rb
@@ -0,0 +1,33 @@
+require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')
+
+module Arel
+ describe Predicate do
+ before do
+ @relation = Table.new(:users)
+ @attribute1 = @relation[:id]
+ @attribute2 = @relation[:name]
+ @operand1 = Equality.new(@attribute1, 1)
+ @operand2 = Equality.new(@attribute2, "name")
+ end
+
+ describe "when being combined with another predicate with AND logic" do
+ describe "#to_sql" do
+ it "manufactures sql with an AND operation" do
+ @operand1.and(@operand2).to_sql.should be_like("
+ (`users`.`id` = 1 AND `users`.`name` = 'name')
+ ")
+ end
+ end
+ end
+
+ describe "when being combined with another predicate with OR logic" do
+ describe "#to_sql" do
+ it "manufactures sql with an OR operation" do
+ @operand1.or(@operand2).to_sql.should be_like("
+ (`users`.`id` = 1 OR `users`.`name` = 'name')
+ ")
+ end
+ end
+ end
+ end
+end \ No newline at end of file