From 9b188c5bfe04349aa8ee0eeb2b53456601b8c3fc Mon Sep 17 00:00:00 2001
From: Steven Fenigstein <steve@navigatingcancer.com>
Date: Fri, 11 Feb 2011 00:39:58 -0800
Subject: removed an unnecessary second query when passing an
 ActiveRecord::Relation to a where clause.  And added ability to use
 subselects in where clauses.

---
 .../active_record/relation/predicate_builder.rb    |  5 +++-
 activerecord/test/cases/relations_test.rb          | 29 +++++++++++++++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 61d9974570..80b5495569 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -18,7 +18,10 @@ module ActiveRecord
           attribute = table[column.to_sym]
 
           case value
-          when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation
+          when ActiveRecord::Relation
+            value.select_values = Array.wrap("#{value.klass.quoted_table_name}.id") if value.select_values.empty?
+            attribute.in(value.arel.ast)
+          when Array, ActiveRecord::Associations::AssociationCollection
             values = value.to_a.map { |x|
               x.is_a?(ActiveRecord::Base) ? x.id : x
             }
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 184e7a2b9e..843c3d2d96 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -467,7 +467,7 @@ class RelationTest < ActiveRecord::TestCase
     authors = Author.find_by_id([author])
     assert_equal author, authors
   end
-
+  
   def test_find_all_using_where_twice_should_or_the_relation
     david = authors(:david)
     relation = Author.unscoped
@@ -488,6 +488,33 @@ class RelationTest < ActiveRecord::TestCase
     end
     assert_equal [david], relation.all
   end
+  
+  def test_find_all_using_where_with_relation
+    david = authors(:david)
+    # switching the lines below would succeed in current rails
+    # assert_queries(2) {
+    assert_queries(1) {
+      relation = Author.where(:id => Author.where(:id => david.id))
+      assert_equal [david], relation.all
+    }
+  end
+
+  def test_find_all_using_where_with_relation_with_joins
+    david = authors(:david)
+    assert_queries(1) {
+      relation = Author.where(:id => Author.joins(:posts).where(:id => david.id))
+      assert_equal [david], relation.all
+    }
+  end
+
+  
+  def test_find_all_using_where_with_relation_with_select_to_build_subquery
+    david = authors(:david)
+    assert_queries(1) {
+      relation = Author.where(:name => Author.where(:id => david.id).select(:name))
+      assert_equal [david], relation.all
+    }
+  end
 
   def test_exists
     davids = Author.where(:name => 'David')
-- 
cgit v1.2.3