public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Ensure table names are quoted by the association preloading code.

[#45 state:resolved]

Signed-off-by: Michael Koziarski <michael@koziarski.com>
fcheung (author)
Fri Apr 25 15:23:48 -0700 2008
NZKoz (committer)
Fri Apr 25 17:14:50 -0700 2008
commit  44d214235271cb6d2af1c327d592a3010e1ced3e
tree    5db346cc10ff1dab291e62545a2480a819271f74
parent  a37546517dad9f6d9a7de6e1dba4d960909d71e8
...
85
86
87
88
89
90
 
91
92
93
...
97
98
99
100
 
101
102
103
...
157
158
159
160
 
161
162
163
...
216
217
218
219
 
220
221
222
...
229
230
231
232
233
234
235
 
236
237
238
 
239
240
241
 
242
243
244
...
85
86
87
 
88
 
89
90
91
92
...
96
97
98
 
99
100
101
102
...
156
157
158
 
159
160
161
162
...
215
216
217
 
218
219
220
221
...
228
229
230
 
231
232
 
233
234
235
 
236
237
238
 
239
240
241
242
0
@@ -85,9 +85,8 @@ module ActiveRecord
0
         return id_to_record_map, ids
0
       end
0
 
0
-      # FIXME: quoting
0
       def preload_has_and_belongs_to_many_association(records, reflection, preload_options={})
0
-        table_name = reflection.klass.table_name
0
+        table_name = reflection.klass.quoted_table_name
0
         id_to_record_map, ids = construct_id_map(records)
0
         records.each {|record| record.send(reflection.name).loaded}
0
         options = reflection.options
0
@@ -97,7 +96,7 @@ module ActiveRecord
0
 
0
         associated_records = reflection.klass.find(:all, :conditions => [conditions, ids],
0
         :include => options[:include],
0
-        :joins => "INNER JOIN #{options[:join_table]} as t0 ON #{reflection.klass.table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
0
+        :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} as t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}",
0
         :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as _parent_record_id",
0
         :order => options[:order])
0
 
0
@@ -157,7 +156,7 @@ module ActiveRecord
0
 
0
         if reflection.options[:source_type]
0
           interface = reflection.source_reflection.options[:foreign_type]
0
-          preload_options = {:conditions => ["#{interface} = ?", reflection.options[:source_type]]}
0
+          preload_options = {:conditions => ["#{connection.quote_column_name interface} = ?", reflection.options[:source_type]]}
0
 
0
           records.compact!
0
           records.first.class.preload_associations(records, through_association, preload_options)
0
@@ -216,7 +215,7 @@ module ActiveRecord
0
           klass_name, id_map = *klass_and_id
0
           klass = klass_name.constantize
0
 
0
-          table_name = klass.table_name
0
+          table_name = klass.quoted_table_name
0
           primary_key = klass.primary_key
0
           conditions = "#{table_name}.#{primary_key} IN (?)"
0
           conditions << append_conditions(options, preload_options)
0
@@ -229,16 +228,15 @@ module ActiveRecord
0
         end
0
       end
0
 
0
-      # FIXME: quoting
0
       def find_associated_records(ids, reflection, preload_options)
0
         options = reflection.options
0
-        table_name = reflection.klass.table_name
0
+        table_name = reflection.klass.quoted_table_name
0
 
0
         if interface = reflection.options[:as]
0
-          conditions = "#{reflection.klass.table_name}.#{interface}_id IN (?) and #{reflection.klass.table_name}.#{interface}_type = '#{self.base_class.name.demodulize}'"
0
+          conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} IN (?) and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.name.demodulize}'"
0
         else
0
           foreign_key = reflection.primary_key_name
0
-          conditions = "#{reflection.klass.table_name}.#{foreign_key} IN (?)"
0
+          conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} IN (?)"
0
         end
0
 
0
         conditions << append_conditions(options, preload_options)
...
9
10
11
 
 
12
13
14
15
16
 
17
18
19
...
194
195
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
198
199
...
9
10
11
12
13
14
15
16
17
 
18
19
20
21
...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
0
@@ -9,11 +9,13 @@ require 'models/person'
0
 require 'models/reader'
0
 require 'models/owner'
0
 require 'models/pet'
0
+require 'models/reference'
0
+require 'models/job'
0
 
0
 class EagerAssociationTest < ActiveRecord::TestCase
0
   fixtures :posts, :comments, :authors, :categories, :categories_posts,
0
             :companies, :accounts, :tags, :taggings, :people, :readers,
0
-            :owners, :pets, :author_favorites
0
+            :owners, :pets, :author_favorites, :jobs, :references
0
 
0
   def test_loading_with_one_association
0
     posts = Post.find(:all, :include => :comments)
0
@@ -194,6 +196,30 @@ class EagerAssociationTest < ActiveRecord::TestCase
0
     assert_equal authors(:mary), assert_no_queries { author_favorite.favorite_author }
0
   end
0
 
0
+  def test_eager_load_belongs_to_quotes_table_and_column_names
0
+    job = Job.find jobs(:unicyclist).id, :include => :ideal_reference
0
+    references(:michael_unicyclist)
0
+    assert_no_queries{ assert_equal references(:michael_unicyclist), job.ideal_reference}
0
+  end
0
+
0
+  def test_eager_load_has_one_quotes_table_and_column_names
0
+    michael = Person.find(people(:michael), :include => :favourite_reference)
0
+    references(:michael_unicyclist)
0
+    assert_no_queries{ assert_equal references(:michael_unicyclist), michael.favourite_reference}
0
+  end
0
+
0
+  def test_eager_load_has_many_quotes_table_and_column_names
0
+    michael = Person.find(people(:michael), :include => :references)
0
+    references(:michael_magician,:michael_unicyclist)
0
+    assert_no_queries{ assert_equal references(:michael_magician,:michael_unicyclist), michael.references.sort_by(&:id) }
0
+  end
0
+
0
+  def test_eager_load_has_many_through_quotes_table_and_column_names
0
+    michael = Person.find(people(:michael), :include => :jobs)
0
+    jobs(:magician, :unicyclist)
0
+    assert_no_queries{ assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) }
0
+  end
0
+
0
   def test_eager_association_loading_with_explicit_join
0
     posts = Post.find(:all, :include => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id')
0
     assert_equal 1, posts.length
...
2
3
4
 
 
 
 
 
5
...
2
3
4
5
6
7
8
9
10
0
@@ -2,4 +2,9 @@ class Person < ActiveRecord::Base
0
   has_many :readers
0
   has_many :posts, :through => :readers
0
   has_many :posts_with_no_comments, :through => :readers, :source => :post, :include => :comments, :conditions => 'comments.id is null'
0
+
0
+  has_many :references
0
+  has_many :jobs, :through => :references
0
+  has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true]
0
+
0
 end
...
162
163
164
 
 
 
 
 
165
166
167
...
197
198
199
 
 
 
 
 
 
200
201
202
...
162
163
164
165
166
167
168
169
170
171
172
...
202
203
204
205
206
207
208
209
210
211
212
213
0
@@ -162,6 +162,11 @@ ActiveRecord::Schema.define do
0
     t.column :type, :string
0
   end
0
 
0
+
0
+  create_table :jobs, :force => true do |t|
0
+    t.integer :ideal_reference_id
0
+  end
0
+
0
   create_table :keyboards, :force => true, :id  => false do |t|
0
     t.primary_key :key_number
0
     t.string      :name
0
@@ -197,6 +202,12 @@ ActiveRecord::Schema.define do
0
     t.string :type
0
   end
0
 
0
+  create_table :references, :force => true do |t|
0
+    t.integer :person_id
0
+    t.integer :job_id
0
+    t.boolean :favourite
0
+  end
0
+
0
   create_table :minimalistics, :force => true do |t|
0
   end
0
 

Comments