public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Fix column collision with named_scope and :joins.  [#46 state:resolved]
markcatley (author)
Sat Jun 21 04:41:30 -0700 2008
jeremy (committer)
Sun Jun 22 19:21:32 -0700 2008
commit  3558a50a1cb31dd207cc1932aaee5025a7dc7c1b
tree    33547f94b70cafaf8aaf876e1d49d840c087760c
parent  0304bb182acaaf73e501a39fbf71d78dd28d0815
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 *2.1.1 (next release)*
0
 
0
+* Fix column collision with named_scope and :joins.  #46 [Duncan Beevers, Mark Catley]
0
+
0
 * db:migrate:down and :up update schema_migrations.  #369 [Michael Raidel, RaceCondition]
0
 
0
 * PostgreSQL: support :conditions => [':foo::integer', { :foo => 1 }] without treating the ::integer typecast as a bind variable.  [Tarmo Tänav]
...
1465
1466
1467
1468
 
1469
1470
1471
...
1465
1466
1467
 
1468
1469
1470
1471
0
@@ -1465,7 +1465,7 @@ module ActiveRecord #:nodoc:
0
 
0
         def construct_finder_sql(options)
0
           scope = scope(:find)
0
-          sql  = "SELECT #{options[:select] || (scope && scope[:select]) || (options[:joins] && quoted_table_name + '.*') || '*'} "
0
+          sql  = "SELECT #{options[:select] || (scope && scope[:select]) || ((options[:joins] || (scope && scope[:joins])) && quoted_table_name + '.*') || '*'} "
0
           sql << "FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} "
0
 
0
           add_joins!(sql, options, scope)
...
87
88
89
 
 
 
 
 
 
 
 
 
 
90
91
92
...
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
0
@@ -87,6 +87,16 @@ class MethodScopingTest < ActiveRecord::TestCase
0
     assert_equal 1, scoped_developers.size
0
   end
0
 
0
+  def test_scoped_find_joins
0
+    scoped_developers = Developer.with_scope(:find => { :joins => 'JOIN developers_projects ON id = developer_id' } ) do
0
+      Developer.find(:all, :conditions => 'developers_projects.project_id = 2')
0
+    end
0
+    assert scoped_developers.include?(developers(:david))
0
+    assert !scoped_developers.include?(developers(:jamis))
0
+    assert_equal 1, scoped_developers.size
0
+    assert_equal developers(:david).attributes, scoped_developers.first.attributes
0
+  end
0
+
0
   def test_scoped_count_include
0
     # with the include, will retrieve only developers for the given project
0
     Developer.with_scope(:find => { :include => :projects }) do
...
6
7
8
9
 
10
11
12
...
83
84
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
87
88
...
6
7
8
 
9
10
11
12
...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
0
@@ -6,7 +6,7 @@ require 'models/reply'
0
 require 'models/author'
0
 
0
 class NamedScopeTest < ActiveRecord::TestCase
0
-  fixtures :posts, :authors, :topics, :comments
0
+  fixtures :posts, :authors, :topics, :comments, :author_addresses
0
 
0
   def test_implements_enumerable
0
     assert !Topic.find(:all).empty?
0
@@ -83,6 +83,25 @@ class NamedScopeTest < ActiveRecord::TestCase
0
     assert_equal topics_written_before_the_second, Topic.written_before(topics(:second).written_on)
0
   end
0
 
0
+  def test_scopes_with_joins
0
+    address = author_addresses(:david_address)
0
+    posts_with_authors_at_address = Post.find(
0
+      :all, :joins => 'JOIN authors ON authors.id = posts.author_id',
0
+      :conditions => [ 'authors.author_address_id = ?', address.id ]
0
+    )
0
+    assert_equal posts_with_authors_at_address, Post.with_authors_at_address(address)
0
+  end
0
+
0
+  def test_scopes_with_joins_respects_custom_select
0
+    address = author_addresses(:david_address)
0
+    posts_with_authors_at_address_titles = Post.find(:all,
0
+      :select => 'title',
0
+      :joins => 'JOIN authors ON authors.id = posts.author_id',
0
+      :conditions => [ 'authors.author_address_id = ?', address.id ]
0
+    )
0
+    assert_equal posts_with_authors_at_address_titles, Post.with_authors_at_address(address).find(:all, :select => 'title')
0
+  end
0
+
0
   def test_extensions
0
     assert_equal 1, Topic.anonymous_extension.one
0
     assert_equal 2, Topic.named_extension.two
...
1
2
3
 
 
 
 
 
 
4
5
6
...
1
2
 
3
4
5
6
7
8
9
10
11
0
@@ -1,6 +1,11 @@
0
 class Post < ActiveRecord::Base
0
   named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
0
-  
0
+  named_scope :with_authors_at_address, lambda { |address| {
0
+      :conditions => [ 'authors.author_address_id = ?', address.id ],
0
+      :joins => 'JOIN authors ON authors.id = posts.author_id'
0
+    }
0
+  }
0
+
0
   belongs_to :author do
0
     def greeting
0
       "hello"

Comments