aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kallen <nkallen@nick-kallens-computer-2.local>2008-05-05 11:22:48 -0700
committerNick Kallen <nkallen@nick-kallens-computer-2.local>2008-05-05 11:22:48 -0700
commitb9e90e4e55290172d7c5918319fd5fe35aa6a10e (patch)
treeef63a7974dd97012fc72dc3d33ec25f0884620e7
parentcd428ee66498146d3dc14f58c6534d79ab124b45 (diff)
downloadrails-b9e90e4e55290172d7c5918319fd5fe35aa6a10e.tar.gz
rails-b9e90e4e55290172d7c5918319fd5fe35aa6a10e.tar.bz2
rails-b9e90e4e55290172d7c5918319fd5fe35aa6a10e.zip
better column disambiguation
-rw-r--r--lib/arel/primitives/attribute.rb8
-rw-r--r--lib/arel/relations/join.rb9
-rw-r--r--lib/arel/relations/nil.rb1
-rw-r--r--lib/arel/relations/relation.rb4
-rw-r--r--spec/arel/unit/primitives/attribute_spec.rb29
-rw-r--r--spec/arel/unit/relations/join_spec.rb17
6 files changed, 60 insertions, 8 deletions
diff --git a/lib/arel/primitives/attribute.rb b/lib/arel/primitives/attribute.rb
index 14b8c18cb2..5895f7e9b9 100644
--- a/lib/arel/primitives/attribute.rb
+++ b/lib/arel/primitives/attribute.rb
@@ -1,3 +1,5 @@
+require 'set'
+
module Arel
class Attribute
attr_reader :relation, :name, :alias, :ancestor
@@ -67,9 +69,9 @@ module Arel
!(history & other.history).empty?
end
- def %(other)
- if other then (history - other.history) + (other.history - history)
- else history
+ def /(other)
+ if other then (history & other.history).size.to_f / Set.new(history + other.history).size
+ else 0
end
end
end
diff --git a/lib/arel/relations/join.rb b/lib/arel/relations/join.rb
index 4269731092..5356e57394 100644
--- a/lib/arel/relations/join.rb
+++ b/lib/arel/relations/join.rb
@@ -44,9 +44,12 @@ module Arel
end
def relation_for(attribute)
- externalize([relation1[attribute], relation2[attribute]].select { |a| a =~ attribute }.min do |a1, a2|
- (attribute % a1).size <=> (attribute % a2).size
- end.relation).relation_for(attribute)
+ x = [externalize(relation1), externalize(relation2)].max do |r1, r2|
+ o1, o2 = r1.relation_for(attribute), r2.relation_for(attribute)
+ a1, a2 = o1 && o1[attribute], o2 && o2[attribute]
+
+ attribute / a1 <=> attribute / a2
+ end.relation_for(attribute)
end
private
diff --git a/lib/arel/relations/nil.rb b/lib/arel/relations/nil.rb
index 258f60f478..b0d97dd174 100644
--- a/lib/arel/relations/nil.rb
+++ b/lib/arel/relations/nil.rb
@@ -2,6 +2,7 @@ module Arel
class Nil < Relation
def table; self end
def table_sql(formatter = nil); '' end
+ def relation_for(attribute); nil end
def name; '' end
def to_s; '' end
diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb
index cc0f40ea17..8c56a0cdcc 100644
--- a/lib/arel/relations/relation.rb
+++ b/lib/arel/relations/relation.rb
@@ -140,8 +140,8 @@ module Arel
end
def attribute_for_attribute(attribute)
- attributes.select { |a| a =~ attribute }.min do |a1, a2|
- (attribute % a1).size <=> (attribute % a2).size
+ attributes.select { |a| a =~ attribute }.max do |a1, a2|
+ (attribute / a1) <=> (attribute / a2)
end
end
end
diff --git a/spec/arel/unit/primitives/attribute_spec.rb b/spec/arel/unit/primitives/attribute_spec.rb
index 561c47da16..b253892b58 100644
--- a/spec/arel/unit/primitives/attribute_spec.rb
+++ b/spec/arel/unit/primitives/attribute_spec.rb
@@ -57,6 +57,35 @@ module Arel
end
end
+ describe '/' do
+ before do
+ @aliased_relation = @relation.alias
+ @doubly_aliased_relation = @aliased_relation.alias.alias.alias.alias
+ end
+
+ describe 'when dividing two identical attributes' do
+ it "returns 1.0" do
+ (@relation[:id] / @relation[:id]).should == 1.0
+ (@aliased_relation[:id] / @aliased_relation[:id]).should == 1.0
+ end
+ end
+
+ describe 'when dividing two unrelated attributes' do
+ it "returns 0.0" do
+ (@relation[:id] / @relation[:name]).should == 0.0
+ end
+ end
+
+ describe 'when dividing two similar attributes' do
+ it 'returns a the highest score for the most similar attributes' do
+ (@aliased_relation[:id] / @relation[:id]) \
+ .should == (@aliased_relation[:id] / @relation[:id])
+ (@aliased_relation[:id] / @relation[:id]) \
+ .should < (@aliased_relation[:id] / @aliased_relation[:id])
+ end
+ end
+ end
+
describe 'hashing' do
it "implements hash equality" do
Attribute.new(@relation, 'name').should hash_the_same_as(Attribute.new(@relation, 'name'))
diff --git a/spec/arel/unit/relations/join_spec.rb b/spec/arel/unit/relations/join_spec.rb
index d517da8c1f..a538c8af68 100644
--- a/spec/arel/unit/relations/join_spec.rb
+++ b/spec/arel/unit/relations/join_spec.rb
@@ -203,6 +203,23 @@ module Arel
end
end
end
+
+ describe 'something really really complex' do
+ it '' do
+ users = @relation1
+ photos = @relation2
+ users_2 = users.alias
+ photos_2 = photos.alias
+ r = users \
+ .join(photos) \
+ .on(photos[:user_id].eq users[:id]) \
+ .join(users_2) \
+ .on(users_2[:id].eq photos[:user_id]) \
+ .join(photos_2) \
+ .on(users_2[:id].eq photos_2[:user_id])
+ r.relation_for(photos[:user_id]).should == photos
+ end
+ end
describe '[]' do
describe 'when given an attribute belonging to both sub-relations' do