store_base_sti_class_for_3_0 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/README.rdoc +4 -0
- data/VERSION +1 -1
- data/polymorphic_and_sti_fix_for_rails_2.3-1.diff +436 -0
- data/polymorphic_and_sti_fix_for_rails_2.3-2.diff +13 -0
- data/store_base_sti_class_for_3_0.gemspec +5 -3
- metadata +7 -5
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -58,6 +58,10 @@ Currently, it works with Rails ~> 3.0.5.
|
|
58
58
|
|
59
59
|
This gem will not work with Rails 3.1 as much of its ActiveRecord internals have been replaced with Arel. Similar but different changes need to be applied to Rails 3.1. Those changes will come.
|
60
60
|
|
61
|
+
== Still using Rails 2.3?
|
62
|
+
|
63
|
+
A patch for Rails 2.3 existed which I used until I switched to Rails 3 (sorry, I don't know the original author of that Rails 2.3 patch). I've attached that patch in form of two diffs to this repo. See polymorphic_and_sti_fix_for_rails_2.3-1.diff and polymorphic_and_sti_fix_for_rails_2.3-2.diff. Note, I was using Rails 2.3.4 so YMMV with 2.3.11.
|
64
|
+
|
61
65
|
== Copyright
|
62
66
|
|
63
67
|
Copyright (c) 2011 Paul Kmiec. See LICENSE.txt for
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
@@ -0,0 +1,436 @@
|
|
1
|
+
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
|
2
|
+
index af80a57..c8618f9 100644
|
3
|
+
--- a/activerecord/lib/active_record/association_preload.rb
|
4
|
+
+++ b/activerecord/lib/active_record/association_preload.rb
|
5
|
+
@@ -350,10 +350,10 @@ module ActiveRecord
|
6
|
+
table_name = reflection.klass.quoted_table_name
|
7
|
+
|
8
|
+
if interface = reflection.options[:as]
|
9
|
+
- conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.sti_name}'"
|
10
|
+
+ conditions = "#{table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.sti_name}'"
|
11
|
+
else
|
12
|
+
foreign_key = reflection.primary_key_name
|
13
|
+
- conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
|
14
|
+
+ conditions = "#{table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
|
15
|
+
end
|
16
|
+
|
17
|
+
conditions << append_conditions(reflection, preload_options)
|
18
|
+
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
|
19
|
+
index 157716a..5769573 100755
|
20
|
+
--- a/activerecord/lib/active_record/associations.rb
|
21
|
+
+++ b/activerecord/lib/active_record/associations.rb
|
22
|
+
@@ -1380,7 +1380,7 @@ module ActiveRecord
|
23
|
+
# Add polymorphic type if the :as option is present
|
24
|
+
dependent_conditions = []
|
25
|
+
dependent_conditions << "#{reflection.primary_key_name} = \#{record.quoted_id}"
|
26
|
+
- dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
|
27
|
+
+ dependent_conditions << "#{reflection.options[:as]}_type = '#{sti_name}'" if reflection.options[:as]
|
28
|
+
dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.quoted_table_name) if reflection.options[:conditions]
|
29
|
+
dependent_conditions << extra_conditions if extra_conditions
|
30
|
+
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
|
31
|
+
@@ -2053,7 +2053,7 @@ module ActiveRecord
|
32
|
+
jt_as_extra = " AND %s.%s = %s" % [
|
33
|
+
connection.quote_table_name(aliased_join_table_name),
|
34
|
+
connection.quote_column_name(through_reflection.options[:as].to_s + '_type'),
|
35
|
+
- klass.quote_value(parent.active_record.base_class.name)
|
36
|
+
+ klass.quote_value(parent.active_record.sti_name)
|
37
|
+
]
|
38
|
+
else
|
39
|
+
jt_foreign_key = through_reflection.primary_key_name
|
40
|
+
@@ -2067,7 +2067,7 @@ module ActiveRecord
|
41
|
+
as_extra = " AND %s.%s = %s" % [
|
42
|
+
connection.quote_table_name(aliased_table_name),
|
43
|
+
connection.quote_column_name("#{source_reflection.options[:as]}_type"),
|
44
|
+
- klass.quote_value(source_reflection.active_record.base_class.name)
|
45
|
+
+ klass.quote_value(source_reflection.active_record.sti_name)
|
46
|
+
]
|
47
|
+
else
|
48
|
+
first_key = through_reflection.klass.base_class.to_s.foreign_key
|
49
|
+
@@ -2120,7 +2120,7 @@ module ActiveRecord
|
50
|
+
parent.primary_key,
|
51
|
+
connection.quote_table_name(aliased_table_name),
|
52
|
+
"#{reflection.options[:as]}_type",
|
53
|
+
- klass.quote_value(parent.active_record.base_class.name)
|
54
|
+
+ klass.quote_value(parent.active_record.sti_name)
|
55
|
+
]
|
56
|
+
else
|
57
|
+
foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
|
58
|
+
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
|
59
|
+
index e36b04e..74694ec 100644
|
60
|
+
--- a/activerecord/lib/active_record/associations/association_proxy.rb
|
61
|
+
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
|
62
|
+
@@ -179,7 +179,7 @@ module ActiveRecord
|
63
|
+
def set_belongs_to_association_for(record)
|
64
|
+
if @reflection.options[:as]
|
65
|
+
record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
|
66
|
+
- record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
|
67
|
+
+ record["#{@reflection.options[:as]}_type"] = @owner.class.sti_name.to_s
|
68
|
+
else
|
69
|
+
unless @owner.new_record?
|
70
|
+
primary_key = @reflection.options[:primary_key] || :id
|
71
|
+
diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
|
72
|
+
index d8146da..360d57e 100644
|
73
|
+
--- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
|
74
|
+
+++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
|
75
|
+
@@ -8,7 +8,7 @@ module ActiveRecord
|
76
|
+
@target = (AssociationProxy === record ? record.target : record)
|
77
|
+
|
78
|
+
@owner[@reflection.primary_key_name] = record.id
|
79
|
+
- @owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s
|
80
|
+
+ @owner[@reflection.options[:foreign_type]] = record.class.sti_name.to_s
|
81
|
+
|
82
|
+
@updated = true
|
83
|
+
end
|
84
|
+
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
|
85
|
+
index 73dd50d..1bccf26 100644
|
86
|
+
--- a/activerecord/lib/active_record/associations/has_many_association.rb
|
87
|
+
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
|
88
|
+
@@ -89,9 +89,9 @@ module ActiveRecord
|
89
|
+
when @reflection.options[:as]
|
90
|
+
@finder_sql =
|
91
|
+
"#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
|
92
|
+
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
|
93
|
+
+ "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.sti_name.to_s)}"
|
94
|
+
@finder_sql << " AND (#{conditions})" if conditions
|
95
|
+
-
|
96
|
+
+
|
97
|
+
else
|
98
|
+
@finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
|
99
|
+
@finder_sql << " AND (#{conditions})" if conditions
|
100
|
+
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
|
101
|
+
index e8dbae9..34f17d1 100644
|
102
|
+
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
|
103
|
+
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
|
104
|
+
@@ -89,7 +89,7 @@ module ActiveRecord
|
105
|
+
def construct_owner_attributes(reflection)
|
106
|
+
if as = reflection.options[:as]
|
107
|
+
{ "#{as}_id" => @owner.id,
|
108
|
+
- "#{as}_type" => @owner.class.base_class.name.to_s }
|
109
|
+
+ "#{as}_type" => @owner.class.sti_name.to_s }
|
110
|
+
else
|
111
|
+
{ reflection.primary_key_name => @owner.id }
|
112
|
+
end
|
113
|
+
@@ -101,7 +101,7 @@ module ActiveRecord
|
114
|
+
raise ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection.new(@owner, @reflection) if @reflection.source_reflection.macro == :has_many
|
115
|
+
join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id)
|
116
|
+
if @reflection.options[:source_type]
|
117
|
+
- join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s)
|
118
|
+
+ join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.sti_name.to_s)
|
119
|
+
end
|
120
|
+
join_attributes
|
121
|
+
end
|
122
|
+
@@ -111,7 +111,7 @@ module ActiveRecord
|
123
|
+
if as = reflection.options[:as]
|
124
|
+
{ "#{as}_id" => owner_quoted_id,
|
125
|
+
"#{as}_type" => reflection.klass.quote_value(
|
126
|
+
- @owner.class.base_class.name.to_s,
|
127
|
+
+ @owner.class.sti_name.to_s,
|
128
|
+
reflection.klass.columns_hash["#{as}_type"]) }
|
129
|
+
elsif reflection.macro == :belongs_to
|
130
|
+
{ reflection.klass.primary_key => @owner[reflection.primary_key_name] }
|
131
|
+
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
|
132
|
+
index b72b843..9dde2a8 100644
|
133
|
+
--- a/activerecord/lib/active_record/associations/has_one_association.rb
|
134
|
+
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
|
135
|
+
@@ -90,7 +90,7 @@ module ActiveRecord
|
136
|
+
when @reflection.options[:as]
|
137
|
+
@finder_sql =
|
138
|
+
"#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{owner_quoted_id} AND " +
|
139
|
+
- "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
|
140
|
+
+ "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.sti_name.to_s)}"
|
141
|
+
else
|
142
|
+
@finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{owner_quoted_id}"
|
143
|
+
end
|
144
|
+
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
|
145
|
+
index a540570..e8b3ac2 100644
|
146
|
+
--- a/activerecord/lib/active_record/autosave_association.rb
|
147
|
+
+++ b/activerecord/lib/active_record/autosave_association.rb
|
148
|
+
@@ -342,7 +342,7 @@ module ActiveRecord
|
149
|
+
self[reflection.primary_key_name] = association.id
|
150
|
+
# TODO: Removing this code doesn't seem to matter…
|
151
|
+
if reflection.options[:polymorphic]
|
152
|
+
- self[reflection.options[:foreign_type]] = association.class.base_class.name.to_s
|
153
|
+
+ self[reflection.options[:foreign_type]] = association.class.sti_name.to_s
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
diff --git a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
|
158
|
+
index 7c47061..094e127 100644
|
159
|
+
--- a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
|
160
|
+
+++ b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
|
161
|
+
@@ -25,11 +25,12 @@ class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase
|
162
|
+
|
163
|
+
ActiveRecord::Base.store_full_sti_class = false
|
164
|
+
post = Namespaced::Post.find_by_title( 'Great stuff', :include => :tagging )
|
165
|
+
- assert_nil post.tagging
|
166
|
+
+ assert_equal 'Post', post.tagging.taggable_type
|
167
|
+
+ assert_equal 'Tagging', post.tagging.class.name
|
168
|
+
|
169
|
+
ActiveRecord::Base.store_full_sti_class = true
|
170
|
+
post = Namespaced::Post.find_by_title( 'Great stuff', :include => :tagging )
|
171
|
+
- assert_equal 'Tagging', post.tagging.class.name
|
172
|
+
+ assert_nil post.tagging
|
173
|
+
ensure
|
174
|
+
ActiveRecord::Base.store_full_sti_class = old
|
175
|
+
end
|
176
|
+
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
|
177
|
+
index 4cf49be..c2946bb 100644
|
178
|
+
--- a/activerecord/test/cases/associations/eager_test.rb
|
179
|
+
+++ b/activerecord/test/cases/associations/eager_test.rb
|
180
|
+
@@ -599,7 +599,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
181
|
+
|
182
|
+
def test_polymorphic_type_condition
|
183
|
+
post = Post.find(posts(:thinking).id, :include => :taggings)
|
184
|
+
- assert post.taggings.include?(taggings(:thinking_general))
|
185
|
+
+ assert !post.taggings.include?(taggings(:thinking_general))
|
186
|
+
post = SpecialPost.find(posts(:thinking).id, :include => :taggings)
|
187
|
+
assert post.taggings.include?(taggings(:thinking_general))
|
188
|
+
end
|
189
|
+
@@ -747,12 +747,12 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
190
|
+
posts = assert_queries(2) do
|
191
|
+
Post.find(:all, :include => :author, :joins => {:taggings => :tag}, :conditions => "tags.name = 'General'", :order => 'posts.id')
|
192
|
+
end
|
193
|
+
- assert_equal posts(:welcome, :thinking), posts
|
194
|
+
+ assert_equal [posts(:welcome)], posts
|
195
|
+
|
196
|
+
posts = assert_queries(2) do
|
197
|
+
Post.find(:all, :include => :author, :joins => {:taggings => {:tag => :taggings}}, :conditions => "taggings_tags.super_tag_id=2", :order => 'posts.id')
|
198
|
+
end
|
199
|
+
- assert_equal posts(:welcome, :thinking), posts
|
200
|
+
+ assert_equal [posts(:welcome)], posts
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
|
205
|
+
index 7140de7..18d6630 100644
|
206
|
+
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
|
207
|
+
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
|
208
|
+
@@ -2,9 +2,11 @@ require "cases/helper"
|
209
|
+
require 'models/developer'
|
210
|
+
require 'models/project'
|
211
|
+
require 'models/company'
|
212
|
+
+require 'models/organization'
|
213
|
+
+require 'models/sponsor'
|
214
|
+
|
215
|
+
class HasOneAssociationsTest < ActiveRecord::TestCase
|
216
|
+
- fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
217
|
+
+ fixtures :accounts, :companies, :developers, :projects, :developers_projects, :organizations, :sponsors
|
218
|
+
|
219
|
+
def setup
|
220
|
+
Account.destroyed_account_ids.clear
|
221
|
+
@@ -306,4 +308,12 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
222
|
+
Firm.find(@firm.id, :include => :account).save!
|
223
|
+
end
|
224
|
+
end
|
225
|
+
+
|
226
|
+
+ def test_sti_has_one_to_polymorphic
|
227
|
+
+ assert_equal sponsors(:generous_sponsor), organizations(:needy).sponsor
|
228
|
+
+ end
|
229
|
+
+
|
230
|
+
+ def test_polymorphic_to_sti_has_one
|
231
|
+
+ assert_equal organizations(:needy), sponsors(:generous_sponsor).sponsorable
|
232
|
+
+ end
|
233
|
+
end
|
234
|
+
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
|
235
|
+
index b1060d0..c870085 100644
|
236
|
+
--- a/activerecord/test/cases/associations/join_model_test.rb
|
237
|
+
+++ b/activerecord/test/cases/associations/join_model_test.rb
|
238
|
+
@@ -121,10 +121,12 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_polymorphic_has_many_going_through_join_model_with_inheritance
|
242
|
+
+ posts(:thinking).taggings << tags(:general).taggings.create
|
243
|
+
assert_equal tags(:general), posts(:thinking).tags.first
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_polymorphic_has_many_going_through_join_model_with_inheritance_with_custom_class_name
|
247
|
+
+ posts(:thinking).taggings << tags(:general).taggings.create
|
248
|
+
assert_equal tags(:general), posts(:thinking).funky_tags.first
|
249
|
+
end
|
250
|
+
|
251
|
+
@@ -133,26 +135,38 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
252
|
+
assert_instance_of SpecialPost, post
|
253
|
+
|
254
|
+
tagging = tags(:misc).taggings.create(:taggable => post)
|
255
|
+
- assert_equal "Post", tagging.taggable_type
|
256
|
+
+ assert_equal "SpecialPost", tagging.taggable_type
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_polymorphic_has_one_create_model_with_inheritance
|
260
|
+
tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
|
261
|
+
- assert_equal "Post", tagging.taggable_type
|
262
|
+
+ assert_equal "SpecialPost", tagging.taggable_type
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_set_polymorphic_has_many
|
266
|
+
tagging = tags(:misc).taggings.create
|
267
|
+
- posts(:thinking).taggings << tagging
|
268
|
+
+ posts(:welcome).taggings << tagging
|
269
|
+
assert_equal "Post", tagging.taggable_type
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_set_polymorphic_has_one
|
273
|
+
tagging = tags(:misc).taggings.create
|
274
|
+
- posts(:thinking).tagging = tagging
|
275
|
+
+ posts(:welcome).tagging = tagging
|
276
|
+
assert_equal "Post", tagging.taggable_type
|
277
|
+
end
|
278
|
+
|
279
|
+
+ def test_set_polymorphic_has_many_with_sti_owner
|
280
|
+
+ tagging = tags(:misc).taggings.create
|
281
|
+
+ posts(:thinking).taggings << tagging
|
282
|
+
+ assert_equal "SpecialPost", tagging.taggable_type
|
283
|
+
+ end
|
284
|
+
+
|
285
|
+
+ def test_set_polymorphic_has_one_with_sti_owner
|
286
|
+
+ tagging = tags(:misc).taggings.create
|
287
|
+
+ posts(:thinking).tagging = tagging
|
288
|
+
+ assert_equal "SpecialPost", tagging.taggable_type
|
289
|
+
+ end
|
290
|
+
+
|
291
|
+
def test_create_polymorphic_has_many_with_scope
|
292
|
+
old_count = posts(:welcome).taggings.count
|
293
|
+
tagging = posts(:welcome).taggings.create(:tag => tags(:misc))
|
294
|
+
@@ -259,8 +273,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_include_polymorphic_has_many_through
|
298
|
+
- posts = Post.find(:all, :order => 'posts.id')
|
299
|
+
- posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
|
300
|
+
+ posts = Post.find(:all, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
301
|
+
+ posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
302
|
+
assert_equal posts.length, posts_with_tags.length
|
303
|
+
posts.length.times do |i|
|
304
|
+
assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
|
305
|
+
@@ -268,8 +282,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_include_polymorphic_has_many
|
309
|
+
- posts = Post.find(:all, :order => 'posts.id')
|
310
|
+
- posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
|
311
|
+
+ posts = Post.find(:all, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
312
|
+
+ posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
313
|
+
assert_equal posts.length, posts_with_taggings.length
|
314
|
+
posts.length.times do |i|
|
315
|
+
assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
|
316
|
+
@@ -343,12 +357,12 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_has_many_polymorphic_with_source_type
|
320
|
+
- assert_equal posts(:welcome, :thinking), tags(:general).tagged_posts
|
321
|
+
+ assert_equal [posts(:welcome)], tags(:general).tagged_posts
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_eager_has_many_polymorphic_with_source_type
|
325
|
+
tag_with_include = Tag.find(tags(:general).id, :include => :tagged_posts)
|
326
|
+
- desired = posts(:welcome, :thinking)
|
327
|
+
+ desired = [posts(:welcome)]
|
328
|
+
assert_no_queries do
|
329
|
+
assert_equal desired, tag_with_include.tagged_posts
|
330
|
+
end
|
331
|
+
@@ -381,12 +395,12 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_has_many_through_polymorphic_has_many
|
335
|
+
- assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.uniq.sort_by { |t| t.id }
|
336
|
+
+ assert_equal [taggings(:welcome_general)], authors(:david).taggings.uniq.sort_by { |t| t.id }
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_include_has_many_through_polymorphic_has_many
|
340
|
+
author = Author.find_by_id(authors(:david).id, :include => :taggings)
|
341
|
+
- expected_taggings = taggings(:welcome_general, :thinking_general)
|
342
|
+
+ expected_taggings = [taggings(:welcome_general)]
|
343
|
+
assert_no_queries do
|
344
|
+
assert_equal expected_taggings, author.taggings.uniq.sort_by { |t| t.id }
|
345
|
+
end
|
346
|
+
@@ -618,8 +632,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_preload_polymorphic_has_many_through
|
350
|
+
- posts = Post.find(:all, :order => 'posts.id')
|
351
|
+
- posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
|
352
|
+
+ posts = Post.find(:all, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
353
|
+
+ posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
354
|
+
assert_equal posts.length, posts_with_tags.length
|
355
|
+
posts.length.times do |i|
|
356
|
+
assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
|
357
|
+
@@ -645,8 +659,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_preload_polymorphic_has_many
|
361
|
+
- posts = Post.find(:all, :order => 'posts.id')
|
362
|
+
- posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
|
363
|
+
+ posts = Post.find(:all, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
364
|
+
+ posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id', :conditions => ['type = ?', 'Post'])
|
365
|
+
assert_equal posts.length, posts_with_taggings.length
|
366
|
+
posts.length.times do |i|
|
367
|
+
assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
|
368
|
+
diff --git a/activerecord/test/fixtures/organizations.yml b/activerecord/test/fixtures/organizations.yml
|
369
|
+
index 25295bf..7498a33 100644
|
370
|
+
--- a/activerecord/test/fixtures/organizations.yml
|
371
|
+
+++ b/activerecord/test/fixtures/organizations.yml
|
372
|
+
@@ -2,4 +2,6 @@ nsa:
|
373
|
+
name: No Such Agency
|
374
|
+
discordians:
|
375
|
+
name: Discordians
|
376
|
+
-
|
377
|
+
+needy:
|
378
|
+
+ name: We Need Money
|
379
|
+
+ type: SponsorableOrganization
|
380
|
+
|
381
|
+
diff --git a/activerecord/test/fixtures/sponsors.yml b/activerecord/test/fixtures/sponsors.yml
|
382
|
+
index 42df895..64aea4d 100644
|
383
|
+
--- a/activerecord/test/fixtures/sponsors.yml
|
384
|
+
+++ b/activerecord/test/fixtures/sponsors.yml
|
385
|
+
@@ -6,4 +6,6 @@ boring_club_sponsor_for_groucho:
|
386
|
+
sponsorable: some_other_guy (Member)
|
387
|
+
crazy_club_sponsor_for_groucho:
|
388
|
+
sponsor_club: crazy_club
|
389
|
+
- sponsorable: some_other_guy (Member)
|
390
|
+
|
391
|
+
+ sponsorable: some_other_guy (Member)
|
392
|
+
+generous_sponsor:
|
393
|
+
+ sponsorable: needy (SponsorableOrganization)
|
394
|
+
|
395
|
+
diff --git a/activerecord/test/fixtures/taggings.yml b/activerecord/test/fixtures/taggings.yml
|
396
|
+
index 1e3d596..01fd16a 100644
|
397
|
+
--- a/activerecord/test/fixtures/taggings.yml
|
398
|
+
+++ b/activerecord/test/fixtures/taggings.yml
|
399
|
+
@@ -9,7 +9,7 @@ thinking_general:
|
400
|
+
id: 2
|
401
|
+
tag_id: 1
|
402
|
+
taggable_id: 2
|
403
|
+
- taggable_type: Post
|
404
|
+
+ taggable_type: SpecialPost
|
405
|
+
|
406
|
+
fake:
|
407
|
+
id: 3
|
408
|
+
diff --git a/activerecord/test/models/organization.rb b/activerecord/test/models/organization.rb
|
409
|
+
index d79d503..c537cd2 100644
|
410
|
+
--- a/activerecord/test/models/organization.rb
|
411
|
+
+++ b/activerecord/test/models/organization.rb
|
412
|
+
@@ -1,4 +1,8 @@
|
413
|
+
class Organization < ActiveRecord::Base
|
414
|
+
has_many :member_details
|
415
|
+
has_many :members, :through => :member_details
|
416
|
+
+end
|
417
|
+
+
|
418
|
+
+class SponsorableOrganization < Organization
|
419
|
+
+ has_one :sponsor, :as => :sponsorable
|
420
|
+
end
|
421
|
+
|
422
|
+
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
|
423
|
+
index b2aaccb..8d8b04f 100644
|
424
|
+
--- a/activerecord/test/schema/schema.rb
|
425
|
+
+++ b/activerecord/test/schema/schema.rb
|
426
|
+
@@ -284,6 +284,7 @@ ActiveRecord::Schema.define do
|
427
|
+
|
428
|
+
create_table :organizations, :force => true do |t|
|
429
|
+
t.string :name
|
430
|
+
+ t.string :type
|
431
|
+
end
|
432
|
+
|
433
|
+
create_table :owners, :primary_key => :owner_id ,:force => true do |t|
|
434
|
+
--
|
435
|
+
1.6.2.1
|
436
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Index: activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
|
2
|
+
===================================================================
|
3
|
+
--- activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb (revision 1320)
|
4
|
+
+++ activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb (working copy)
|
5
|
+
@@ -8,7 +8,7 @@
|
6
|
+
@target = (AssociationProxy === record ? record.target : record)
|
7
|
+
|
8
|
+
@owner[@reflection.primary_key_name] = record_id(record)
|
9
|
+
- @owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s
|
10
|
+
+ @owner[@reflection.options[:foreign_type]] = record.class.sti_name.to_s
|
11
|
+
|
12
|
+
@updated = true
|
13
|
+
end
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{store_base_sti_class_for_3_0}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Paul Kmiec"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-26}
|
13
13
|
s.description = %q{
|
14
14
|
ActiveRecord has always stored the base class in polymorphic _type columns when using STI. This can have non-trivial
|
15
15
|
performance implications in certain cases. This gem adds 'store_base_sti_class' configuration options which controls
|
@@ -30,6 +30,8 @@ Gem::Specification.new do |s|
|
|
30
30
|
"Rakefile",
|
31
31
|
"VERSION",
|
32
32
|
"lib/store_base_sti_class_for_3_0.rb",
|
33
|
+
"polymorphic_and_sti_fix_for_rails_2.3-1.diff",
|
34
|
+
"polymorphic_and_sti_fix_for_rails_2.3-2.diff",
|
33
35
|
"store_base_sti_class_for_3_0.gemspec",
|
34
36
|
"test/connection.rb",
|
35
37
|
"test/helper.rb",
|
@@ -56,7 +58,7 @@ Gem::Specification.new do |s|
|
|
56
58
|
|
57
59
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
58
60
|
s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.5"])
|
59
|
-
s.
|
61
|
+
s.add_development_dependency(%q<mysql2>, [">= 0"])
|
60
62
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
61
63
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
62
64
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: store_base_sti_class_for_3_0
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Paul Kmiec
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-26 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirement: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
prerelease: false
|
39
|
-
type: :
|
39
|
+
type: :development
|
40
40
|
name: mysql2
|
41
41
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
@@ -113,6 +113,8 @@ files:
|
|
113
113
|
- Rakefile
|
114
114
|
- VERSION
|
115
115
|
- lib/store_base_sti_class_for_3_0.rb
|
116
|
+
- polymorphic_and_sti_fix_for_rails_2.3-1.diff
|
117
|
+
- polymorphic_and_sti_fix_for_rails_2.3-2.diff
|
116
118
|
- store_base_sti_class_for_3_0.gemspec
|
117
119
|
- test/connection.rb
|
118
120
|
- test/helper.rb
|