diff options
-rw-r--r-- | lib/arel/predicates.rb | 2 | ||||
-rw-r--r-- | lib/arel/primitives/attribute.rb | 12 | ||||
-rw-r--r-- | lib/arel/relations/aggregation.rb | 2 | ||||
-rw-r--r-- | lib/arel/relations/compound.rb | 6 | ||||
-rw-r--r-- | lib/arel/relations/join.rb | 28 | ||||
-rw-r--r-- | lib/arel/relations/nil.rb | 1 | ||||
-rw-r--r-- | lib/arel/relations/recursion.rb | 4 | ||||
-rw-r--r-- | spec/arel/integration/joins/with_aggregations_spec.rb | 6 | ||||
-rw-r--r-- | spec/arel/unit/predicates/binary_spec.rb | 17 | ||||
-rw-r--r-- | spec/arel/unit/primitives/attribute_spec.rb | 11 | ||||
-rw-r--r-- | spec/arel/unit/relations/join_spec.rb | 10 |
11 files changed, 34 insertions, 65 deletions
diff --git a/lib/arel/predicates.rb b/lib/arel/predicates.rb index 93c7ed0099..3d01d5872f 100644 --- a/lib/arel/predicates.rb +++ b/lib/arel/predicates.rb @@ -17,7 +17,7 @@ module Arel end def bind(relation) - self.class.new(operand1.bind(relation), operand2.bind(relation)) + self.class.new(relation[operand1] || operand1, relation[operand2] || operand2) end def to_sql(formatter = nil) diff --git a/lib/arel/primitives/attribute.rb b/lib/arel/primitives/attribute.rb index 5e769ac0eb..cb564c1587 100644 --- a/lib/arel/primitives/attribute.rb +++ b/lib/arel/primitives/attribute.rb @@ -38,16 +38,14 @@ module Arel end def original_relation - @original_relation ||= relation.relation_for(self) + original_attribute.relation end def original_attribute - @original_attribute ||= original_relation[self] + @original_attribute ||= history.detect { |a| !a.join? } end - module Transformations - delegate :size, :to => :history - + module Transformations def self.included(klass) klass.send :alias_method, :eql?, :== end @@ -75,8 +73,8 @@ module Arel @history ||= [self] + (ancestor ? ancestor.history : []) end - def match?(other) - history.last == other.history.last + def join? + relation.join? end def root diff --git a/lib/arel/relations/aggregation.rb b/lib/arel/relations/aggregation.rb index d409c34284..a6f40be786 100644 --- a/lib/arel/relations/aggregation.rb +++ b/lib/arel/relations/aggregation.rb @@ -15,7 +15,7 @@ module Arel end def attributes - @attributes ||= relation.attributes.collect(&:to_attribute) + @attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) } end def ==(other) diff --git a/lib/arel/relations/compound.rb b/lib/arel/relations/compound.rb index abc5838805..9921568157 100644 --- a/lib/arel/relations/compound.rb +++ b/lib/arel/relations/compound.rb @@ -10,9 +10,9 @@ module Arel def attributes @attributes ||= relation.attributes.collect { |a| a.bind(self) } end - - def relation_for(attribute) - join? && relation.relation_for(attribute) || has_attribute?(attribute) && self + + def selects + @selects || relation.selects.collect { |s| s.bind(self) } end end end
\ No newline at end of file diff --git a/lib/arel/relations/join.rb b/lib/arel/relations/join.rb index abd4eae4f6..9cc9f95c81 100644 --- a/lib/arel/relations/join.rb +++ b/lib/arel/relations/join.rb @@ -7,14 +7,6 @@ module Arel def initialize(join_sql, relation1, relation2 = Nil.new, *predicates) @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates end - - def ==(other) - Join == other.class and - predicates == other.predicates and ( - (relation1 == other.relation1 and relation2 == other.relation2) or - (relation2 == other.relation1 and relation1 == other.relation2) - ) - end def table_sql(formatter = Sql::TableReference.new(self)) relation1.externalize.table_sql(formatter) @@ -25,7 +17,7 @@ module Arel join_sql, relation2.externalize.table_sql(formatter), ("ON" unless predicates.blank?), - (predicates + relation2.externalize.selects).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ') + (ons + relation2.externalize.selects).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ') ].compact.join(" ") [relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ") end @@ -39,14 +31,8 @@ module Arel relation1.externalize.selects end - def relation_for(attribute) - [ - relation1.externalize.relation_for(attribute), - relation2.externalize.relation_for(attribute) - ].max do |r1, r2| - a1, a2 = r1 && r1[attribute], r2 && r2[attribute] - attribute / a1 <=> attribute / a2 - end + def ons + @ons ||= @predicates.collect { |p| p.bind(self) } end # TESTME @@ -57,6 +43,14 @@ module Arel def join? true end + + def ==(other) + Join == other.class and + predicates == other.predicates and ( + (relation1 == other.relation1 and relation2 == other.relation2) or + (relation2 == other.relation1 and relation1 == other.relation2) + ) + end end class Relation diff --git a/lib/arel/relations/nil.rb b/lib/arel/relations/nil.rb index e8d4cbc481..c34fe71473 100644 --- a/lib/arel/relations/nil.rb +++ b/lib/arel/relations/nil.rb @@ -1,7 +1,6 @@ module Arel class Nil < Relation def table_sql(formatter = nil); '' end - def relation_for(attribute); nil end def name; '' end def ==(other) diff --git a/lib/arel/relations/recursion.rb b/lib/arel/relations/recursion.rb index c2fcf1bd21..848b059507 100644 --- a/lib/arel/relations/recursion.rb +++ b/lib/arel/relations/recursion.rb @@ -8,10 +8,6 @@ module Arel def table_sql(formatter = Sql::TableReference.new(self)) formatter.table self end - - def relation_for(attribute) - has_attribute?(attribute) && self - end end end end
\ No newline at end of file diff --git a/spec/arel/integration/joins/with_aggregations_spec.rb b/spec/arel/integration/joins/with_aggregations_spec.rb index b9cb4acc31..655250f4f9 100644 --- a/spec/arel/integration/joins/with_aggregations_spec.rb +++ b/spec/arel/integration/joins/with_aggregations_spec.rb @@ -19,12 +19,6 @@ module Arel it '' do @relation1.join(@aggregation).on(@predicate)[@relation2[:user_id]].should_not be_nil end - - it 'it transforms aggregate expressions into attributes' do - join_with_aggregation = Join.new("INNER JOIN", @relation1, @aggregation, @predicate) - join_with_aggregation.attributes.should == - (@relation1.attributes + @aggregation.attributes).collect(&:to_attribute).collect { |a| a.bind(join_with_aggregation) } - end end describe '#to_sql' do diff --git a/spec/arel/unit/predicates/binary_spec.rb b/spec/arel/unit/predicates/binary_spec.rb index f39b37d913..2d6ef5d7e3 100644 --- a/spec/arel/unit/predicates/binary_spec.rb +++ b/spec/arel/unit/predicates/binary_spec.rb @@ -59,12 +59,21 @@ module Arel describe '#bind' do before do - @another_relation = Table.new(:photos) + @another_relation = @relation.alias end - it "descends" do - ConcreteBinary.new(@attribute1, @attribute2).bind(@another_relation). \ - should == ConcreteBinary.new(@attribute1.bind(@another_relation), @attribute2.bind(@another_relation)) + describe 'when both operands are attributes' do + it "manufactures an expression with the attributes bound to the relation" do + ConcreteBinary.new(@attribute1, @attribute2).bind(@another_relation). \ + should == ConcreteBinary.new(@another_relation[@attribute1], @another_relation[@attribute2]) + end + end + + describe 'when an operand is a value' do + it "manufactures an expression with unmodified values" do + ConcreteBinary.new(@attribute1, "asdf").bind(@another_relation). \ + should == ConcreteBinary.new(@another_relation[@attribute1], "asdf") + end end end end diff --git a/spec/arel/unit/primitives/attribute_spec.rb b/spec/arel/unit/primitives/attribute_spec.rb index 34665b5adf..890ac0e813 100644 --- a/spec/arel/unit/primitives/attribute_spec.rb +++ b/spec/arel/unit/primitives/attribute_spec.rb @@ -45,17 +45,6 @@ module Arel end describe Attribute::Congruence do - describe '#match?' do - it "obtains if the attributes are identical" do - @attribute.should be_match(@attribute) - end - - it "obtains if the attributes have an overlapping history" do - Attribute.new(@relation, :id, :ancestor => @attribute).should be_match(@attribute) - @attribute.should be_match(Attribute.new(@relation, :id, :ancestor => @attribute)) - end - end - describe '/' do before do @aliased_relation = @relation.alias diff --git a/spec/arel/unit/relations/join_spec.rb b/spec/arel/unit/relations/join_spec.rb index 347566e6ea..d128dd0560 100644 --- a/spec/arel/unit/relations/join_spec.rb +++ b/spec/arel/unit/relations/join_spec.rb @@ -55,16 +55,6 @@ module Arel INNER JOIN `photos` ON `users`.`id` = `photos`.`user_id` ") end - - it 'manufactures sql joining the two tables, with selects from the right table in the ON clause' do - Join.new("INNER JOIN", @relation1.select(@relation1[:id].eq(1)), - @relation2.select(@relation2[:id].eq(2)), @predicate).to_sql.should be_like(" - SELECT `users`.`id`, `users`.`name`, `photos`.`id`, `photos`.`user_id`, `photos`.`camera_id` - FROM `users` - INNER JOIN `photos` ON `users`.`id` = `photos`.`user_id` AND `photos`.`id` = 2 - WHERE `users`.`id` = 1 - ") - end end describe 'when joining with a string' do |