ibm_db 2.5.27-x86-mingw32 → 2.6.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +5 -0
- data/MANIFEST +14 -14
- data/README +225 -225
- data/ext/Makefile.nt32 +181 -181
- data/ext/Makefile.nt32.191 +212 -212
- data/ext/extconf.rb +264 -264
- data/ext/extconf_MacOS.rb +269 -0
- data/ext/ibm_db.c +1 -1
- data/ext/ruby_ibm_db.h +241 -241
- data/init.rb +41 -41
- data/lib/IBM_DB.rb +27 -3
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3290 -3290
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
- data/lib/mswin32/ibm_db.rb +104 -20
- data/lib/mswin32/rb19x/ibm_db.so +0 -0
- data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
- data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
- data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
- data/test/cases/adapter_test.rb +207 -207
- data/test/cases/associations/belongs_to_associations_test.rb +711 -711
- data/test/cases/associations/cascaded_eager_loading_test.rb +181 -181
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +851 -851
- data/test/cases/associations/join_model_test.rb +743 -743
- data/test/cases/attribute_methods_test.rb +822 -822
- data/test/cases/base_test.rb +2133 -2133
- data/test/cases/calculations_test.rb +482 -482
- data/test/cases/migration_test.rb +2408 -2408
- data/test/cases/persistence_test.rb +642 -642
- data/test/cases/query_cache_test.rb +257 -257
- data/test/cases/relations_test.rb +1182 -1182
- data/test/cases/schema_dumper_test.rb +256 -256
- data/test/cases/transaction_callbacks_test.rb +300 -300
- data/test/cases/validations/uniqueness_validation_test.rb +299 -299
- data/test/cases/xml_serialization_test.rb +408 -408
- data/test/config.yml +154 -154
- data/test/connections/native_ibm_db/connection.rb +43 -43
- data/test/ibm_db_test.rb +24 -24
- data/test/models/warehouse_thing.rb +4 -4
- data/test/schema/schema.rb +751 -751
- metadata +31 -16
@@ -1,743 +1,743 @@
|
|
1
|
-
require "cases/helper"
|
2
|
-
require 'active_support/core_ext/object/inclusion'
|
3
|
-
require 'models/tag'
|
4
|
-
require 'models/tagging'
|
5
|
-
require 'models/post'
|
6
|
-
require 'models/rating'
|
7
|
-
require 'models/item'
|
8
|
-
require 'models/comment'
|
9
|
-
require 'models/author'
|
10
|
-
require 'models/category'
|
11
|
-
require 'models/categorization'
|
12
|
-
require 'models/vertex'
|
13
|
-
require 'models/edge'
|
14
|
-
require 'models/book'
|
15
|
-
require 'models/citation'
|
16
|
-
require 'models/aircraft'
|
17
|
-
require 'models/engine'
|
18
|
-
require 'models/car'
|
19
|
-
|
20
|
-
class AssociationsJoinModelTest < ActiveRecord::TestCase
|
21
|
-
self.use_transactional_fixtures = false unless supports_savepoints?
|
22
|
-
|
23
|
-
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
|
24
|
-
# Reload edges table from fixtures as otherwise repeated test was failing
|
25
|
-
:edges
|
26
|
-
|
27
|
-
def test_has_many
|
28
|
-
assert authors(:david).categories.include?(categories(:general))
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_has_many_inherited
|
32
|
-
assert authors(:mary).categories.include?(categories(:sti_test))
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_inherited_has_many
|
36
|
-
assert categories(:sti_test).authors.include?(authors(:mary))
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_has_many_uniq_through_join_model
|
40
|
-
assert_equal 2, authors(:mary).categorized_posts.size
|
41
|
-
assert_equal 1, authors(:mary).unique_categorized_posts.size
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_has_many_uniq_through_count
|
45
|
-
author = authors(:mary)
|
46
|
-
assert !authors(:mary).unique_categorized_posts.loaded?
|
47
|
-
assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count }
|
48
|
-
assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count(:title) }
|
49
|
-
assert_queries(1) { assert_equal 0, author.unique_categorized_posts.count(:title, :conditions => "title is NULL") }
|
50
|
-
assert !authors(:mary).unique_categorized_posts.loaded?
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_has_many_uniq_through_find
|
54
|
-
assert_equal 1, authors(:mary).unique_categorized_posts.find(:all).size
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_has_many_uniq_through_dynamic_find
|
58
|
-
assert_equal 1, authors(:mary).unique_categorized_posts.find_all_by_title("So I was thinking").size
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_polymorphic_has_many_going_through_join_model
|
62
|
-
assert_equal tags(:general), tag = posts(:welcome).tags.first
|
63
|
-
assert_no_queries do
|
64
|
-
tag.tagging
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_count_polymorphic_has_many
|
69
|
-
assert_equal 1, posts(:welcome).taggings.count
|
70
|
-
assert_equal 1, posts(:welcome).tags.count
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_polymorphic_has_many_going_through_join_model_with_find
|
74
|
-
assert_equal tags(:general), tag = posts(:welcome).tags.find(:first)
|
75
|
-
assert_no_queries do
|
76
|
-
tag.tagging
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection
|
81
|
-
assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
|
82
|
-
assert_no_queries do
|
83
|
-
tag.tagging
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection_with_find
|
88
|
-
assert_equal tags(:general), tag = posts(:welcome).funky_tags.find(:first)
|
89
|
-
assert_no_queries do
|
90
|
-
tag.tagging
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
|
95
|
-
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
|
96
|
-
assert_nothing_raised(NoMethodError) { tag.author_id }
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
|
100
|
-
assert_equal tags(:misc), taggings(:welcome_general).super_tag
|
101
|
-
assert_equal tags(:misc), posts(:welcome).super_tags.first
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
|
105
|
-
post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
|
106
|
-
assert_instance_of SubStiPost, post
|
107
|
-
|
108
|
-
tagging = tags(:misc).taggings.create(:taggable => post)
|
109
|
-
assert_equal "SubStiPost", tagging.taggable_type
|
110
|
-
end
|
111
|
-
|
112
|
-
def test_polymorphic_has_many_going_through_join_model_with_inheritance
|
113
|
-
assert_equal tags(:general), posts(:thinking).tags.first
|
114
|
-
end
|
115
|
-
|
116
|
-
def test_polymorphic_has_many_going_through_join_model_with_inheritance_with_custom_class_name
|
117
|
-
assert_equal tags(:general), posts(:thinking).funky_tags.first
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_polymorphic_has_many_create_model_with_inheritance
|
121
|
-
post = posts(:thinking)
|
122
|
-
assert_instance_of SpecialPost, post
|
123
|
-
|
124
|
-
tagging = tags(:misc).taggings.create(:taggable => post)
|
125
|
-
assert_equal "Post", tagging.taggable_type
|
126
|
-
end
|
127
|
-
|
128
|
-
def test_polymorphic_has_one_create_model_with_inheritance
|
129
|
-
tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
|
130
|
-
assert_equal "Post", tagging.taggable_type
|
131
|
-
end
|
132
|
-
|
133
|
-
def test_set_polymorphic_has_many
|
134
|
-
tagging = tags(:misc).taggings.create
|
135
|
-
posts(:thinking).taggings << tagging
|
136
|
-
assert_equal "Post", tagging.taggable_type
|
137
|
-
end
|
138
|
-
|
139
|
-
def test_set_polymorphic_has_one
|
140
|
-
tagging = tags(:misc).taggings.create
|
141
|
-
posts(:thinking).tagging = tagging
|
142
|
-
|
143
|
-
assert_equal "Post", tagging.taggable_type
|
144
|
-
assert_equal posts(:thinking).id, tagging.taggable_id
|
145
|
-
assert_equal posts(:thinking), tagging.taggable
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_set_polymorphic_has_one_on_new_record
|
149
|
-
tagging = tags(:misc).taggings.create
|
150
|
-
post = Post.new :title => "foo", :body => "bar"
|
151
|
-
post.tagging = tagging
|
152
|
-
post.save!
|
153
|
-
|
154
|
-
assert_equal "Post", tagging.taggable_type
|
155
|
-
assert_equal post.id, tagging.taggable_id
|
156
|
-
assert_equal post, tagging.taggable
|
157
|
-
end
|
158
|
-
|
159
|
-
def test_create_polymorphic_has_many_with_scope
|
160
|
-
old_count = posts(:welcome).taggings.count
|
161
|
-
tagging = posts(:welcome).taggings.create(:tag => tags(:misc))
|
162
|
-
assert_equal "Post", tagging.taggable_type
|
163
|
-
assert_equal old_count+1, posts(:welcome).taggings.count
|
164
|
-
end
|
165
|
-
|
166
|
-
def test_create_bang_polymorphic_with_has_many_scope
|
167
|
-
old_count = posts(:welcome).taggings.count
|
168
|
-
tagging = posts(:welcome).taggings.create!(:tag => tags(:misc))
|
169
|
-
assert_equal "Post", tagging.taggable_type
|
170
|
-
assert_equal old_count+1, posts(:welcome).taggings.count
|
171
|
-
end
|
172
|
-
|
173
|
-
def test_create_polymorphic_has_one_with_scope
|
174
|
-
old_count = Tagging.count
|
175
|
-
tagging = posts(:welcome).create_tagging(:tag => tags(:misc))
|
176
|
-
assert_equal "Post", tagging.taggable_type
|
177
|
-
assert_equal old_count+1, Tagging.count
|
178
|
-
end
|
179
|
-
|
180
|
-
def test_delete_polymorphic_has_many_with_delete_all
|
181
|
-
assert_equal 1, posts(:welcome).taggings.count
|
182
|
-
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyDeleteAll'
|
183
|
-
post = find_post_with_dependency(1, :has_many, :taggings, :delete_all)
|
184
|
-
|
185
|
-
old_count = Tagging.count
|
186
|
-
post.destroy
|
187
|
-
assert_equal old_count-1, Tagging.count
|
188
|
-
assert_equal 0, posts(:welcome).taggings.count
|
189
|
-
end
|
190
|
-
|
191
|
-
def test_delete_polymorphic_has_many_with_destroy
|
192
|
-
assert_equal 1, posts(:welcome).taggings.count
|
193
|
-
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyDestroy'
|
194
|
-
post = find_post_with_dependency(1, :has_many, :taggings, :destroy)
|
195
|
-
|
196
|
-
old_count = Tagging.count
|
197
|
-
post.destroy
|
198
|
-
assert_equal old_count-1, Tagging.count
|
199
|
-
assert_equal 0, posts(:welcome).taggings.count
|
200
|
-
end
|
201
|
-
|
202
|
-
def test_delete_polymorphic_has_many_with_nullify
|
203
|
-
assert_equal 1, posts(:welcome).taggings.count
|
204
|
-
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyNullify'
|
205
|
-
post = find_post_with_dependency(1, :has_many, :taggings, :nullify)
|
206
|
-
|
207
|
-
old_count = Tagging.count
|
208
|
-
post.destroy
|
209
|
-
assert_equal old_count, Tagging.count
|
210
|
-
assert_equal 0, posts(:welcome).taggings.count
|
211
|
-
end
|
212
|
-
|
213
|
-
def test_delete_polymorphic_has_one_with_destroy
|
214
|
-
assert posts(:welcome).tagging
|
215
|
-
posts(:welcome).tagging.update_column :taggable_type, 'PostWithHasOneDestroy'
|
216
|
-
post = find_post_with_dependency(1, :has_one, :tagging, :destroy)
|
217
|
-
|
218
|
-
old_count = Tagging.count
|
219
|
-
post.destroy
|
220
|
-
assert_equal old_count-1, Tagging.count
|
221
|
-
assert_nil posts(:welcome).tagging(true)
|
222
|
-
end
|
223
|
-
|
224
|
-
def test_delete_polymorphic_has_one_with_nullify
|
225
|
-
assert posts(:welcome).tagging
|
226
|
-
posts(:welcome).tagging.update_column :taggable_type, 'PostWithHasOneNullify'
|
227
|
-
post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
|
228
|
-
|
229
|
-
old_count = Tagging.count
|
230
|
-
post.destroy
|
231
|
-
assert_equal old_count, Tagging.count
|
232
|
-
assert_nil posts(:welcome).tagging(true)
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_has_many_with_piggyback
|
236
|
-
assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
|
237
|
-
end
|
238
|
-
|
239
|
-
def test_include_has_many_through
|
240
|
-
posts = Post.find(:all, :order => 'posts.id')
|
241
|
-
posts_with_authors = Post.find(:all, :include => :authors, :order => 'posts.id')
|
242
|
-
assert_equal posts.length, posts_with_authors.length
|
243
|
-
posts.length.times do |i|
|
244
|
-
assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
def test_include_polymorphic_has_one
|
249
|
-
post = Post.find_by_id(posts(:welcome).id, :include => :tagging)
|
250
|
-
tagging = taggings(:welcome_general)
|
251
|
-
assert_no_queries do
|
252
|
-
assert_equal tagging, post.tagging
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
def test_include_polymorphic_has_one_defined_in_abstract_parent
|
257
|
-
item = Item.find_by_id(items(:dvd).id, :include => :tagging)
|
258
|
-
tagging = taggings(:godfather)
|
259
|
-
assert_no_queries do
|
260
|
-
assert_equal tagging, item.tagging
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
def test_include_polymorphic_has_many_through
|
265
|
-
posts = Post.find(:all, :order => 'posts.id')
|
266
|
-
posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
|
267
|
-
assert_equal posts.length, posts_with_tags.length
|
268
|
-
posts.length.times do |i|
|
269
|
-
assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
def test_include_polymorphic_has_many
|
274
|
-
posts = Post.find(:all, :order => 'posts.id')
|
275
|
-
posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
|
276
|
-
assert_equal posts.length, posts_with_taggings.length
|
277
|
-
posts.length.times do |i|
|
278
|
-
assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
def test_has_many_find_all
|
283
|
-
assert_equal [categories(:general)], authors(:david).categories.find(:all)
|
284
|
-
end
|
285
|
-
|
286
|
-
def test_has_many_find_first
|
287
|
-
assert_equal categories(:general), authors(:david).categories.find(:first)
|
288
|
-
end
|
289
|
-
|
290
|
-
def test_has_many_with_hash_conditions
|
291
|
-
assert_equal categories(:general), authors(:david).categories_like_general.find(:first)
|
292
|
-
end
|
293
|
-
|
294
|
-
def test_has_many_find_conditions
|
295
|
-
assert_equal categories(:general), authors(:david).categories.find(:first, :conditions => "categories.name = 'General'")
|
296
|
-
assert_nil authors(:david).categories.find(:first, :conditions => "categories.name = 'Technology'")
|
297
|
-
end
|
298
|
-
|
299
|
-
def test_has_many_class_methods_called_by_method_missing
|
300
|
-
assert_equal categories(:general), authors(:david).categories.find_all_by_name('General').first
|
301
|
-
assert_nil authors(:david).categories.find_by_name('Technology')
|
302
|
-
end
|
303
|
-
|
304
|
-
def test_has_many_array_methods_called_by_method_missing
|
305
|
-
assert authors(:david).categories.any? { |category| category.name == 'General' }
|
306
|
-
assert_nothing_raised { authors(:david).categories.sort }
|
307
|
-
end
|
308
|
-
|
309
|
-
def test_has_many_going_through_join_model_with_custom_foreign_key
|
310
|
-
assert_equal [authors(:bob)], posts(:thinking).authors
|
311
|
-
assert_equal [authors(:mary)], posts(:authorless).authors
|
312
|
-
end
|
313
|
-
|
314
|
-
def test_has_many_going_through_join_model_with_custom_primary_key
|
315
|
-
assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
|
316
|
-
end
|
317
|
-
|
318
|
-
def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
|
319
|
-
assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
|
320
|
-
end
|
321
|
-
|
322
|
-
def test_has_many_through_with_custom_primary_key_on_belongs_to_source
|
323
|
-
assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
|
324
|
-
end
|
325
|
-
|
326
|
-
def test_has_many_through_with_custom_primary_key_on_has_many_source
|
327
|
-
assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
|
328
|
-
end
|
329
|
-
|
330
|
-
def test_both_scoped_and_explicit_joins_should_be_respected
|
331
|
-
assert_nothing_raised do
|
332
|
-
Post.send(:with_scope, :find => {:joins => "left outer join comments on comments.id = posts.id"}) do
|
333
|
-
Post.find :all, :select => "comments.id, authors.id", :joins => "left outer join authors on authors.id = posts.author_id"
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
def test_belongs_to_polymorphic_with_counter_cache
|
339
|
-
assert_equal 1, posts(:welcome)[:taggings_count]
|
340
|
-
tagging = posts(:welcome).taggings.create(:tag => tags(:general))
|
341
|
-
assert_equal 2, posts(:welcome, :reload)[:taggings_count]
|
342
|
-
tagging.destroy
|
343
|
-
assert_equal 1, posts(:welcome, :reload)[:taggings_count]
|
344
|
-
end
|
345
|
-
|
346
|
-
def test_unavailable_through_reflection
|
347
|
-
assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
|
348
|
-
end
|
349
|
-
|
350
|
-
def test_has_many_through_join_model_with_conditions
|
351
|
-
assert_equal [], posts(:welcome).invalid_taggings
|
352
|
-
assert_equal [], posts(:welcome).invalid_tags
|
353
|
-
end
|
354
|
-
|
355
|
-
def test_has_many_polymorphic
|
356
|
-
assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
|
357
|
-
tags(:general).taggables
|
358
|
-
end
|
359
|
-
|
360
|
-
assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
|
361
|
-
taggings(:welcome_general).things
|
362
|
-
end
|
363
|
-
|
364
|
-
assert_raise ActiveRecord::EagerLoadPolymorphicError do
|
365
|
-
tags(:general).taggings.find(:all, :include => :taggable, :conditions => 'bogus_table.column = 1')
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
def test_has_many_polymorphic_with_source_type
|
370
|
-
# added sort by ID as otherwise Oracle select sometimes returned rows in different order
|
371
|
-
assert_equal posts(:welcome, :thinking).sort_by(&:id), tags(:general).tagged_posts.sort_by(&:id)
|
372
|
-
end
|
373
|
-
|
374
|
-
def test_eager_has_many_polymorphic_with_source_type
|
375
|
-
tag_with_include = Tag.find(tags(:general).id, :include => :tagged_posts)
|
376
|
-
desired = posts(:welcome, :thinking)
|
377
|
-
assert_no_queries do
|
378
|
-
# added sort by ID as otherwise test using JRuby was failing as array elements were in different order
|
379
|
-
assert_equal desired.sort_by(&:id), tag_with_include.tagged_posts.sort_by(&:id)
|
380
|
-
end
|
381
|
-
assert_equal 5, tag_with_include.taggings.length
|
382
|
-
end
|
383
|
-
|
384
|
-
def test_has_many_through_has_many_find_all
|
385
|
-
assert_equal comments(:greetings), authors(:david).comments.find(:all, :order => 'comments.id').first
|
386
|
-
end
|
387
|
-
|
388
|
-
def test_has_many_through_has_many_find_all_with_custom_class
|
389
|
-
assert_equal comments(:greetings), authors(:david).funky_comments.find(:all, :order => 'comments.id').first
|
390
|
-
end
|
391
|
-
|
392
|
-
def test_has_many_through_has_many_find_first
|
393
|
-
assert_equal comments(:greetings), authors(:david).comments.find(:first, :order => 'comments.id')
|
394
|
-
end
|
395
|
-
|
396
|
-
def test_has_many_through_has_many_find_conditions
|
397
|
-
options = { :conditions => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
|
398
|
-
assert_equal comments(:does_it_hurt), authors(:david).comments.find(:first, options)
|
399
|
-
end
|
400
|
-
|
401
|
-
def test_has_many_through_has_many_find_by_id
|
402
|
-
assert_equal comments(:more_greetings), authors(:david).comments.find(2)
|
403
|
-
end
|
404
|
-
|
405
|
-
def test_has_many_through_polymorphic_has_one
|
406
|
-
assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging.order(:id)
|
407
|
-
end
|
408
|
-
|
409
|
-
def test_has_many_through_polymorphic_has_many
|
410
|
-
assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.uniq.sort_by { |t| t.id }
|
411
|
-
end
|
412
|
-
|
413
|
-
def test_include_has_many_through_polymorphic_has_many
|
414
|
-
author = Author.find_by_id(authors(:david).id, :include => :taggings)
|
415
|
-
expected_taggings = taggings(:welcome_general, :thinking_general)
|
416
|
-
assert_no_queries do
|
417
|
-
assert_equal expected_taggings, author.taggings.uniq.sort_by { |t| t.id }
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
unless current_adapter?(:IBM_DBAdapter)
|
422
|
-
# DB2 throws SQL0214N
|
423
|
-
def test_eager_load_has_many_through_has_many
|
424
|
-
author = Author.find :first, :conditions => ['name = ?', 'David'], :include => :comments, :order => 'comments.id'
|
425
|
-
SpecialComment.new; VerySpecialComment.new
|
426
|
-
assert_no_queries do
|
427
|
-
assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
|
428
|
-
end
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
def test_eager_load_has_many_through_has_many_with_conditions
|
433
|
-
post = Post.find(:first, :include => :invalid_tags)
|
434
|
-
assert_no_queries do
|
435
|
-
post.invalid_tags
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
def test_eager_belongs_to_and_has_one_not_singularized
|
440
|
-
assert_nothing_raised do
|
441
|
-
Author.find(:first, :include => :author_address)
|
442
|
-
AuthorAddress.find(:first, :include => :author)
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
def test_self_referential_has_many_through
|
447
|
-
assert_equal [authors(:mary)], authors(:david).favorite_authors
|
448
|
-
assert_equal [], authors(:mary).favorite_authors
|
449
|
-
end
|
450
|
-
|
451
|
-
def test_add_to_self_referential_has_many_through
|
452
|
-
new_author = Author.create(:name => "Bob")
|
453
|
-
authors(:david).author_favorites.create :favorite_author => new_author
|
454
|
-
assert_equal new_author, authors(:david).reload.favorite_authors.first
|
455
|
-
end
|
456
|
-
|
457
|
-
def test_has_many_through_uses_conditions_specified_on_the_has_many_association
|
458
|
-
author = Author.order(:id).first
|
459
|
-
assert_present author.comments
|
460
|
-
assert_blank author.nonexistant_comments
|
461
|
-
end
|
462
|
-
|
463
|
-
def test_has_many_through_uses_correct_attributes
|
464
|
-
assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
|
465
|
-
end
|
466
|
-
|
467
|
-
def test_associating_unsaved_records_with_has_many_through
|
468
|
-
saved_post = posts(:thinking)
|
469
|
-
new_tag = Tag.new(:name => "new")
|
470
|
-
|
471
|
-
saved_post.tags << new_tag
|
472
|
-
assert new_tag.persisted? #consistent with habtm!
|
473
|
-
assert saved_post.persisted?
|
474
|
-
assert saved_post.tags.include?(new_tag)
|
475
|
-
|
476
|
-
assert new_tag.persisted?
|
477
|
-
assert new_tag.in?(saved_post.reload.tags(true))
|
478
|
-
|
479
|
-
|
480
|
-
new_post = Post.new(:title => "Association replacmenet works!", :body => "You best believe it.")
|
481
|
-
saved_tag = tags(:general)
|
482
|
-
|
483
|
-
new_post.tags << saved_tag
|
484
|
-
assert !new_post.persisted?
|
485
|
-
assert saved_tag.persisted?
|
486
|
-
assert new_post.tags.include?(saved_tag)
|
487
|
-
|
488
|
-
new_post.save!
|
489
|
-
assert new_post.persisted?
|
490
|
-
assert saved_tag.in?(new_post.reload.tags(true))
|
491
|
-
|
492
|
-
assert !posts(:thinking).tags.build.persisted?
|
493
|
-
assert !posts(:thinking).tags.new.persisted?
|
494
|
-
end
|
495
|
-
|
496
|
-
def test_create_associate_when_adding_to_has_many_through
|
497
|
-
count = posts(:thinking).tags.count
|
498
|
-
push = Tag.create!(:name => 'pushme')
|
499
|
-
post_thinking = posts(:thinking)
|
500
|
-
assert_nothing_raised { post_thinking.tags << push }
|
501
|
-
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
|
502
|
-
message = "Expected a Tag in tags collection, got #{wrong.class}.")
|
503
|
-
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
|
504
|
-
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
505
|
-
assert_equal(count + 1, post_thinking.tags.size)
|
506
|
-
assert_equal(count + 1, post_thinking.tags(true).size)
|
507
|
-
|
508
|
-
assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
|
509
|
-
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
|
510
|
-
message = "Expected a Tag in tags collection, got #{wrong.class}.")
|
511
|
-
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
|
512
|
-
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
513
|
-
assert_equal(count + 2, post_thinking.tags.size)
|
514
|
-
assert_equal(count + 2, post_thinking.tags(true).size)
|
515
|
-
|
516
|
-
assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
|
517
|
-
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
|
518
|
-
message = "Expected a Tag in tags collection, got #{wrong.class}.")
|
519
|
-
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
|
520
|
-
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
521
|
-
assert_equal(count + 4, post_thinking.tags.size)
|
522
|
-
assert_equal(count + 4, post_thinking.tags(true).size)
|
523
|
-
|
524
|
-
# Raises if the wrong reflection name is used to set the Edge belongs_to
|
525
|
-
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
526
|
-
end
|
527
|
-
|
528
|
-
def test_add_to_join_table_with_no_id
|
529
|
-
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
530
|
-
end
|
531
|
-
|
532
|
-
def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
|
533
|
-
author = authors(:david)
|
534
|
-
assert_equal 10, author.comments.size
|
535
|
-
assert !author.comments.loaded?
|
536
|
-
end
|
537
|
-
|
538
|
-
def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
|
539
|
-
c = categories(:general)
|
540
|
-
c.categorizations_count = 100
|
541
|
-
assert_equal 100, c.categorizations.size
|
542
|
-
assert !c.categorizations.loaded?
|
543
|
-
end
|
544
|
-
|
545
|
-
def test_adding_junk_to_has_many_through_should_raise_type_mismatch
|
546
|
-
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
|
547
|
-
end
|
548
|
-
|
549
|
-
def test_adding_to_has_many_through_should_return_self
|
550
|
-
tags = posts(:thinking).tags
|
551
|
-
assert_equal tags, posts(:thinking).tags.push(tags(:general))
|
552
|
-
end
|
553
|
-
|
554
|
-
def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
|
555
|
-
count = books(:awdr).references.count
|
556
|
-
references_before = books(:awdr).references
|
557
|
-
book = Book.create!(:name => 'Getting Real')
|
558
|
-
book_awdr = books(:awdr)
|
559
|
-
book_awdr.references << book
|
560
|
-
assert_equal(count + 1, book_awdr.references(true).size)
|
561
|
-
|
562
|
-
assert_nothing_raised { book_awdr.references.delete(book) }
|
563
|
-
assert_equal(count, book_awdr.references.size)
|
564
|
-
assert_equal(count, book_awdr.references(true).size)
|
565
|
-
assert_equal(references_before.sort, book_awdr.references.sort)
|
566
|
-
end
|
567
|
-
|
568
|
-
def test_delete_associate_when_deleting_from_has_many_through
|
569
|
-
count = posts(:thinking).tags.count
|
570
|
-
tags_before = posts(:thinking).tags
|
571
|
-
tag = Tag.create!(:name => 'doomed')
|
572
|
-
post_thinking = posts(:thinking)
|
573
|
-
post_thinking.tags << tag
|
574
|
-
assert_equal(count + 1, post_thinking.taggings(true).size)
|
575
|
-
assert_equal(count + 1, post_thinking.tags(true).size)
|
576
|
-
|
577
|
-
assert_nothing_raised { post_thinking.tags.delete(tag) }
|
578
|
-
assert_equal(count, post_thinking.tags.size)
|
579
|
-
assert_equal(count, post_thinking.tags(true).size)
|
580
|
-
assert_equal(count, post_thinking.taggings(true).size)
|
581
|
-
assert_equal(tags_before.sort, post_thinking.tags.sort)
|
582
|
-
end
|
583
|
-
|
584
|
-
def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
|
585
|
-
count = posts(:thinking).tags.count
|
586
|
-
tags_before = posts(:thinking).tags
|
587
|
-
doomed = Tag.create!(:name => 'doomed')
|
588
|
-
doomed2 = Tag.create!(:name => 'doomed2')
|
589
|
-
quaked = Tag.create!(:name => 'quaked')
|
590
|
-
post_thinking = posts(:thinking)
|
591
|
-
post_thinking.tags << doomed << doomed2
|
592
|
-
assert_equal(count + 2, post_thinking.tags(true).size)
|
593
|
-
|
594
|
-
assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
|
595
|
-
assert_equal(count, post_thinking.tags.size)
|
596
|
-
assert_equal(count, post_thinking.tags(true).size)
|
597
|
-
assert_equal(tags_before.sort, post_thinking.tags.sort)
|
598
|
-
end
|
599
|
-
|
600
|
-
def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
|
601
|
-
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete("Uhh what now?") }
|
602
|
-
end
|
603
|
-
|
604
|
-
def test_has_many_through_sum_uses_calculations
|
605
|
-
assert_nothing_raised { authors(:david).comments.sum(:post_id) }
|
606
|
-
end
|
607
|
-
|
608
|
-
def test_calculations_on_has_many_through_should_disambiguate_fields
|
609
|
-
assert_nothing_raised { authors(:david).categories.maximum(:id) }
|
610
|
-
end
|
611
|
-
|
612
|
-
def test_calculations_on_has_many_through_should_not_disambiguate_fields_unless_necessary
|
613
|
-
assert_nothing_raised { authors(:david).categories.maximum("categories.id") }
|
614
|
-
end
|
615
|
-
|
616
|
-
def test_has_many_through_has_many_with_sti
|
617
|
-
assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
|
618
|
-
end
|
619
|
-
|
620
|
-
def test_uniq_has_many_through_should_retain_order
|
621
|
-
comment_ids = authors(:david).comments.map(&:id)
|
622
|
-
assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
|
623
|
-
assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
|
624
|
-
end
|
625
|
-
|
626
|
-
def test_polymorphic_has_many
|
627
|
-
expected = taggings(:welcome_general)
|
628
|
-
p = Post.find(posts(:welcome).id, :include => :taggings)
|
629
|
-
assert_no_queries {assert p.taggings.include?(expected)}
|
630
|
-
assert posts(:welcome).taggings.include?(taggings(:welcome_general))
|
631
|
-
end
|
632
|
-
|
633
|
-
def test_polymorphic_has_one
|
634
|
-
expected = posts(:welcome)
|
635
|
-
|
636
|
-
tagging = Tagging.find(taggings(:welcome_general).id, :include => :taggable)
|
637
|
-
assert_no_queries { assert_equal expected, tagging.taggable}
|
638
|
-
end
|
639
|
-
|
640
|
-
def test_polymorphic_belongs_to
|
641
|
-
p = Post.find(posts(:welcome).id, :include => {:taggings => :taggable})
|
642
|
-
assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
|
643
|
-
end
|
644
|
-
|
645
|
-
def test_preload_polymorphic_has_many_through
|
646
|
-
posts = Post.find(:all, :order => 'posts.id')
|
647
|
-
posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
|
648
|
-
assert_equal posts.length, posts_with_tags.length
|
649
|
-
posts.length.times do |i|
|
650
|
-
assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
|
651
|
-
end
|
652
|
-
end
|
653
|
-
|
654
|
-
def test_preload_polymorph_many_types
|
655
|
-
taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel'], :order => 'id'
|
656
|
-
assert_no_queries do
|
657
|
-
taggings.first.taggable.id
|
658
|
-
taggings[1].taggable.id
|
659
|
-
end
|
660
|
-
|
661
|
-
taggables = taggings.map(&:taggable)
|
662
|
-
assert taggables.include?(items(:dvd))
|
663
|
-
assert taggables.include?(posts(:welcome))
|
664
|
-
end
|
665
|
-
|
666
|
-
def test_preload_nil_polymorphic_belongs_to
|
667
|
-
assert_nothing_raised do
|
668
|
-
Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL'])
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
def test_preload_polymorphic_has_many
|
673
|
-
posts = Post.find(:all, :order => 'posts.id')
|
674
|
-
posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
|
675
|
-
assert_equal posts.length, posts_with_taggings.length
|
676
|
-
posts.length.times do |i|
|
677
|
-
assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
def test_belongs_to_shared_parent
|
682
|
-
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 1')
|
683
|
-
assert_no_queries do
|
684
|
-
assert_equal comments.first.post, comments[1].post
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
def test_has_many_through_include_uses_array_include_after_loaded
|
689
|
-
david = authors(:david)
|
690
|
-
david.categories.class # force load target
|
691
|
-
|
692
|
-
category = david.categories.first
|
693
|
-
|
694
|
-
assert_no_queries do
|
695
|
-
assert david.categories.loaded?
|
696
|
-
assert david.categories.include?(category)
|
697
|
-
end
|
698
|
-
end
|
699
|
-
|
700
|
-
def test_has_many_through_include_checks_if_record_exists_if_target_not_loaded
|
701
|
-
david = authors(:david)
|
702
|
-
category = david.categories.first
|
703
|
-
|
704
|
-
david.reload
|
705
|
-
assert ! david.categories.loaded?
|
706
|
-
assert_queries(1) do
|
707
|
-
assert david.categories.include?(category)
|
708
|
-
end
|
709
|
-
assert ! david.categories.loaded?
|
710
|
-
end
|
711
|
-
|
712
|
-
def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
|
713
|
-
david = authors(:david)
|
714
|
-
category = Category.create!(:name => 'Not Associated')
|
715
|
-
|
716
|
-
assert ! david.categories.loaded?
|
717
|
-
assert ! david.categories.include?(category)
|
718
|
-
end
|
719
|
-
|
720
|
-
def test_has_many_through_goes_through_all_sti_classes
|
721
|
-
sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
|
722
|
-
new_comment = sub_sti_post.comments.create(:body => 'test')
|
723
|
-
|
724
|
-
assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
|
725
|
-
end
|
726
|
-
|
727
|
-
def test_has_many_with_pluralize_table_names_false
|
728
|
-
aircraft = Aircraft.create!(:name => "Airbus 380")
|
729
|
-
engine = Engine.create!(:car_id => aircraft.id)
|
730
|
-
assert_equal aircraft.engines, [engine]
|
731
|
-
end
|
732
|
-
|
733
|
-
private
|
734
|
-
# create dynamic Post models to allow different dependency options
|
735
|
-
def find_post_with_dependency(post_id, association, association_name, dependency)
|
736
|
-
class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
|
737
|
-
Post.find(post_id).update_column :type, class_name
|
738
|
-
klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
|
739
|
-
klass.table_name = 'posts'
|
740
|
-
klass.send(association, association_name, :as => :taggable, :dependent => dependency)
|
741
|
-
klass.find(post_id)
|
742
|
-
end
|
743
|
-
end
|
1
|
+
require "cases/helper"
|
2
|
+
require 'active_support/core_ext/object/inclusion'
|
3
|
+
require 'models/tag'
|
4
|
+
require 'models/tagging'
|
5
|
+
require 'models/post'
|
6
|
+
require 'models/rating'
|
7
|
+
require 'models/item'
|
8
|
+
require 'models/comment'
|
9
|
+
require 'models/author'
|
10
|
+
require 'models/category'
|
11
|
+
require 'models/categorization'
|
12
|
+
require 'models/vertex'
|
13
|
+
require 'models/edge'
|
14
|
+
require 'models/book'
|
15
|
+
require 'models/citation'
|
16
|
+
require 'models/aircraft'
|
17
|
+
require 'models/engine'
|
18
|
+
require 'models/car'
|
19
|
+
|
20
|
+
class AssociationsJoinModelTest < ActiveRecord::TestCase
|
21
|
+
self.use_transactional_fixtures = false unless supports_savepoints?
|
22
|
+
|
23
|
+
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
|
24
|
+
# Reload edges table from fixtures as otherwise repeated test was failing
|
25
|
+
:edges
|
26
|
+
|
27
|
+
def test_has_many
|
28
|
+
assert authors(:david).categories.include?(categories(:general))
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_has_many_inherited
|
32
|
+
assert authors(:mary).categories.include?(categories(:sti_test))
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_inherited_has_many
|
36
|
+
assert categories(:sti_test).authors.include?(authors(:mary))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_has_many_uniq_through_join_model
|
40
|
+
assert_equal 2, authors(:mary).categorized_posts.size
|
41
|
+
assert_equal 1, authors(:mary).unique_categorized_posts.size
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_has_many_uniq_through_count
|
45
|
+
author = authors(:mary)
|
46
|
+
assert !authors(:mary).unique_categorized_posts.loaded?
|
47
|
+
assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count }
|
48
|
+
assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count(:title) }
|
49
|
+
assert_queries(1) { assert_equal 0, author.unique_categorized_posts.count(:title, :conditions => "title is NULL") }
|
50
|
+
assert !authors(:mary).unique_categorized_posts.loaded?
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_has_many_uniq_through_find
|
54
|
+
assert_equal 1, authors(:mary).unique_categorized_posts.find(:all).size
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_has_many_uniq_through_dynamic_find
|
58
|
+
assert_equal 1, authors(:mary).unique_categorized_posts.find_all_by_title("So I was thinking").size
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_polymorphic_has_many_going_through_join_model
|
62
|
+
assert_equal tags(:general), tag = posts(:welcome).tags.first
|
63
|
+
assert_no_queries do
|
64
|
+
tag.tagging
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_count_polymorphic_has_many
|
69
|
+
assert_equal 1, posts(:welcome).taggings.count
|
70
|
+
assert_equal 1, posts(:welcome).tags.count
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_polymorphic_has_many_going_through_join_model_with_find
|
74
|
+
assert_equal tags(:general), tag = posts(:welcome).tags.find(:first)
|
75
|
+
assert_no_queries do
|
76
|
+
tag.tagging
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection
|
81
|
+
assert_equal tags(:general), tag = posts(:welcome).funky_tags.first
|
82
|
+
assert_no_queries do
|
83
|
+
tag.tagging
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_polymorphic_has_many_going_through_join_model_with_include_on_source_reflection_with_find
|
88
|
+
assert_equal tags(:general), tag = posts(:welcome).funky_tags.find(:first)
|
89
|
+
assert_no_queries do
|
90
|
+
tag.tagging
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
|
95
|
+
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
|
96
|
+
assert_nothing_raised(NoMethodError) { tag.author_id }
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
|
100
|
+
assert_equal tags(:misc), taggings(:welcome_general).super_tag
|
101
|
+
assert_equal tags(:misc), posts(:welcome).super_tags.first
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
|
105
|
+
post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
|
106
|
+
assert_instance_of SubStiPost, post
|
107
|
+
|
108
|
+
tagging = tags(:misc).taggings.create(:taggable => post)
|
109
|
+
assert_equal "SubStiPost", tagging.taggable_type
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_polymorphic_has_many_going_through_join_model_with_inheritance
|
113
|
+
assert_equal tags(:general), posts(:thinking).tags.first
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_polymorphic_has_many_going_through_join_model_with_inheritance_with_custom_class_name
|
117
|
+
assert_equal tags(:general), posts(:thinking).funky_tags.first
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_polymorphic_has_many_create_model_with_inheritance
|
121
|
+
post = posts(:thinking)
|
122
|
+
assert_instance_of SpecialPost, post
|
123
|
+
|
124
|
+
tagging = tags(:misc).taggings.create(:taggable => post)
|
125
|
+
assert_equal "Post", tagging.taggable_type
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_polymorphic_has_one_create_model_with_inheritance
|
129
|
+
tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
|
130
|
+
assert_equal "Post", tagging.taggable_type
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_set_polymorphic_has_many
|
134
|
+
tagging = tags(:misc).taggings.create
|
135
|
+
posts(:thinking).taggings << tagging
|
136
|
+
assert_equal "Post", tagging.taggable_type
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_set_polymorphic_has_one
|
140
|
+
tagging = tags(:misc).taggings.create
|
141
|
+
posts(:thinking).tagging = tagging
|
142
|
+
|
143
|
+
assert_equal "Post", tagging.taggable_type
|
144
|
+
assert_equal posts(:thinking).id, tagging.taggable_id
|
145
|
+
assert_equal posts(:thinking), tagging.taggable
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_set_polymorphic_has_one_on_new_record
|
149
|
+
tagging = tags(:misc).taggings.create
|
150
|
+
post = Post.new :title => "foo", :body => "bar"
|
151
|
+
post.tagging = tagging
|
152
|
+
post.save!
|
153
|
+
|
154
|
+
assert_equal "Post", tagging.taggable_type
|
155
|
+
assert_equal post.id, tagging.taggable_id
|
156
|
+
assert_equal post, tagging.taggable
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_create_polymorphic_has_many_with_scope
|
160
|
+
old_count = posts(:welcome).taggings.count
|
161
|
+
tagging = posts(:welcome).taggings.create(:tag => tags(:misc))
|
162
|
+
assert_equal "Post", tagging.taggable_type
|
163
|
+
assert_equal old_count+1, posts(:welcome).taggings.count
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_create_bang_polymorphic_with_has_many_scope
|
167
|
+
old_count = posts(:welcome).taggings.count
|
168
|
+
tagging = posts(:welcome).taggings.create!(:tag => tags(:misc))
|
169
|
+
assert_equal "Post", tagging.taggable_type
|
170
|
+
assert_equal old_count+1, posts(:welcome).taggings.count
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_create_polymorphic_has_one_with_scope
|
174
|
+
old_count = Tagging.count
|
175
|
+
tagging = posts(:welcome).create_tagging(:tag => tags(:misc))
|
176
|
+
assert_equal "Post", tagging.taggable_type
|
177
|
+
assert_equal old_count+1, Tagging.count
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_delete_polymorphic_has_many_with_delete_all
|
181
|
+
assert_equal 1, posts(:welcome).taggings.count
|
182
|
+
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyDeleteAll'
|
183
|
+
post = find_post_with_dependency(1, :has_many, :taggings, :delete_all)
|
184
|
+
|
185
|
+
old_count = Tagging.count
|
186
|
+
post.destroy
|
187
|
+
assert_equal old_count-1, Tagging.count
|
188
|
+
assert_equal 0, posts(:welcome).taggings.count
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_delete_polymorphic_has_many_with_destroy
|
192
|
+
assert_equal 1, posts(:welcome).taggings.count
|
193
|
+
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyDestroy'
|
194
|
+
post = find_post_with_dependency(1, :has_many, :taggings, :destroy)
|
195
|
+
|
196
|
+
old_count = Tagging.count
|
197
|
+
post.destroy
|
198
|
+
assert_equal old_count-1, Tagging.count
|
199
|
+
assert_equal 0, posts(:welcome).taggings.count
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_delete_polymorphic_has_many_with_nullify
|
203
|
+
assert_equal 1, posts(:welcome).taggings.count
|
204
|
+
posts(:welcome).taggings.first.update_column :taggable_type, 'PostWithHasManyNullify'
|
205
|
+
post = find_post_with_dependency(1, :has_many, :taggings, :nullify)
|
206
|
+
|
207
|
+
old_count = Tagging.count
|
208
|
+
post.destroy
|
209
|
+
assert_equal old_count, Tagging.count
|
210
|
+
assert_equal 0, posts(:welcome).taggings.count
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_delete_polymorphic_has_one_with_destroy
|
214
|
+
assert posts(:welcome).tagging
|
215
|
+
posts(:welcome).tagging.update_column :taggable_type, 'PostWithHasOneDestroy'
|
216
|
+
post = find_post_with_dependency(1, :has_one, :tagging, :destroy)
|
217
|
+
|
218
|
+
old_count = Tagging.count
|
219
|
+
post.destroy
|
220
|
+
assert_equal old_count-1, Tagging.count
|
221
|
+
assert_nil posts(:welcome).tagging(true)
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_delete_polymorphic_has_one_with_nullify
|
225
|
+
assert posts(:welcome).tagging
|
226
|
+
posts(:welcome).tagging.update_column :taggable_type, 'PostWithHasOneNullify'
|
227
|
+
post = find_post_with_dependency(1, :has_one, :tagging, :nullify)
|
228
|
+
|
229
|
+
old_count = Tagging.count
|
230
|
+
post.destroy
|
231
|
+
assert_equal old_count, Tagging.count
|
232
|
+
assert_nil posts(:welcome).tagging(true)
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_has_many_with_piggyback
|
236
|
+
assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_include_has_many_through
|
240
|
+
posts = Post.find(:all, :order => 'posts.id')
|
241
|
+
posts_with_authors = Post.find(:all, :include => :authors, :order => 'posts.id')
|
242
|
+
assert_equal posts.length, posts_with_authors.length
|
243
|
+
posts.length.times do |i|
|
244
|
+
assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length }
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_include_polymorphic_has_one
|
249
|
+
post = Post.find_by_id(posts(:welcome).id, :include => :tagging)
|
250
|
+
tagging = taggings(:welcome_general)
|
251
|
+
assert_no_queries do
|
252
|
+
assert_equal tagging, post.tagging
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_include_polymorphic_has_one_defined_in_abstract_parent
|
257
|
+
item = Item.find_by_id(items(:dvd).id, :include => :tagging)
|
258
|
+
tagging = taggings(:godfather)
|
259
|
+
assert_no_queries do
|
260
|
+
assert_equal tagging, item.tagging
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_include_polymorphic_has_many_through
|
265
|
+
posts = Post.find(:all, :order => 'posts.id')
|
266
|
+
posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
|
267
|
+
assert_equal posts.length, posts_with_tags.length
|
268
|
+
posts.length.times do |i|
|
269
|
+
assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_include_polymorphic_has_many
|
274
|
+
posts = Post.find(:all, :order => 'posts.id')
|
275
|
+
posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
|
276
|
+
assert_equal posts.length, posts_with_taggings.length
|
277
|
+
posts.length.times do |i|
|
278
|
+
assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_has_many_find_all
|
283
|
+
assert_equal [categories(:general)], authors(:david).categories.find(:all)
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_has_many_find_first
|
287
|
+
assert_equal categories(:general), authors(:david).categories.find(:first)
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_has_many_with_hash_conditions
|
291
|
+
assert_equal categories(:general), authors(:david).categories_like_general.find(:first)
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_has_many_find_conditions
|
295
|
+
assert_equal categories(:general), authors(:david).categories.find(:first, :conditions => "categories.name = 'General'")
|
296
|
+
assert_nil authors(:david).categories.find(:first, :conditions => "categories.name = 'Technology'")
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_has_many_class_methods_called_by_method_missing
|
300
|
+
assert_equal categories(:general), authors(:david).categories.find_all_by_name('General').first
|
301
|
+
assert_nil authors(:david).categories.find_by_name('Technology')
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_has_many_array_methods_called_by_method_missing
|
305
|
+
assert authors(:david).categories.any? { |category| category.name == 'General' }
|
306
|
+
assert_nothing_raised { authors(:david).categories.sort }
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_has_many_going_through_join_model_with_custom_foreign_key
|
310
|
+
assert_equal [authors(:bob)], posts(:thinking).authors
|
311
|
+
assert_equal [authors(:mary)], posts(:authorless).authors
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_has_many_going_through_join_model_with_custom_primary_key
|
315
|
+
assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
|
319
|
+
assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_has_many_through_with_custom_primary_key_on_belongs_to_source
|
323
|
+
assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
|
324
|
+
end
|
325
|
+
|
326
|
+
def test_has_many_through_with_custom_primary_key_on_has_many_source
|
327
|
+
assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id')
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_both_scoped_and_explicit_joins_should_be_respected
|
331
|
+
assert_nothing_raised do
|
332
|
+
Post.send(:with_scope, :find => {:joins => "left outer join comments on comments.id = posts.id"}) do
|
333
|
+
Post.find :all, :select => "comments.id, authors.id", :joins => "left outer join authors on authors.id = posts.author_id"
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_belongs_to_polymorphic_with_counter_cache
|
339
|
+
assert_equal 1, posts(:welcome)[:taggings_count]
|
340
|
+
tagging = posts(:welcome).taggings.create(:tag => tags(:general))
|
341
|
+
assert_equal 2, posts(:welcome, :reload)[:taggings_count]
|
342
|
+
tagging.destroy
|
343
|
+
assert_equal 1, posts(:welcome, :reload)[:taggings_count]
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_unavailable_through_reflection
|
347
|
+
assert_raise(ActiveRecord::HasManyThroughAssociationNotFoundError) { authors(:david).nothings }
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_has_many_through_join_model_with_conditions
|
351
|
+
assert_equal [], posts(:welcome).invalid_taggings
|
352
|
+
assert_equal [], posts(:welcome).invalid_tags
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_has_many_polymorphic
|
356
|
+
assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
|
357
|
+
tags(:general).taggables
|
358
|
+
end
|
359
|
+
|
360
|
+
assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
|
361
|
+
taggings(:welcome_general).things
|
362
|
+
end
|
363
|
+
|
364
|
+
assert_raise ActiveRecord::EagerLoadPolymorphicError do
|
365
|
+
tags(:general).taggings.find(:all, :include => :taggable, :conditions => 'bogus_table.column = 1')
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_has_many_polymorphic_with_source_type
|
370
|
+
# added sort by ID as otherwise Oracle select sometimes returned rows in different order
|
371
|
+
assert_equal posts(:welcome, :thinking).sort_by(&:id), tags(:general).tagged_posts.sort_by(&:id)
|
372
|
+
end
|
373
|
+
|
374
|
+
def test_eager_has_many_polymorphic_with_source_type
|
375
|
+
tag_with_include = Tag.find(tags(:general).id, :include => :tagged_posts)
|
376
|
+
desired = posts(:welcome, :thinking)
|
377
|
+
assert_no_queries do
|
378
|
+
# added sort by ID as otherwise test using JRuby was failing as array elements were in different order
|
379
|
+
assert_equal desired.sort_by(&:id), tag_with_include.tagged_posts.sort_by(&:id)
|
380
|
+
end
|
381
|
+
assert_equal 5, tag_with_include.taggings.length
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_has_many_through_has_many_find_all
|
385
|
+
assert_equal comments(:greetings), authors(:david).comments.find(:all, :order => 'comments.id').first
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_has_many_through_has_many_find_all_with_custom_class
|
389
|
+
assert_equal comments(:greetings), authors(:david).funky_comments.find(:all, :order => 'comments.id').first
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_has_many_through_has_many_find_first
|
393
|
+
assert_equal comments(:greetings), authors(:david).comments.find(:first, :order => 'comments.id')
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_has_many_through_has_many_find_conditions
|
397
|
+
options = { :conditions => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' }
|
398
|
+
assert_equal comments(:does_it_hurt), authors(:david).comments.find(:first, options)
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_has_many_through_has_many_find_by_id
|
402
|
+
assert_equal comments(:more_greetings), authors(:david).comments.find(2)
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_has_many_through_polymorphic_has_one
|
406
|
+
assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging.order(:id)
|
407
|
+
end
|
408
|
+
|
409
|
+
def test_has_many_through_polymorphic_has_many
|
410
|
+
assert_equal taggings(:welcome_general, :thinking_general), authors(:david).taggings.uniq.sort_by { |t| t.id }
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_include_has_many_through_polymorphic_has_many
|
414
|
+
author = Author.find_by_id(authors(:david).id, :include => :taggings)
|
415
|
+
expected_taggings = taggings(:welcome_general, :thinking_general)
|
416
|
+
assert_no_queries do
|
417
|
+
assert_equal expected_taggings, author.taggings.uniq.sort_by { |t| t.id }
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
unless current_adapter?(:IBM_DBAdapter)
|
422
|
+
# DB2 throws SQL0214N
|
423
|
+
def test_eager_load_has_many_through_has_many
|
424
|
+
author = Author.find :first, :conditions => ['name = ?', 'David'], :include => :comments, :order => 'comments.id'
|
425
|
+
SpecialComment.new; VerySpecialComment.new
|
426
|
+
assert_no_queries do
|
427
|
+
assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id)
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_eager_load_has_many_through_has_many_with_conditions
|
433
|
+
post = Post.find(:first, :include => :invalid_tags)
|
434
|
+
assert_no_queries do
|
435
|
+
post.invalid_tags
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
def test_eager_belongs_to_and_has_one_not_singularized
|
440
|
+
assert_nothing_raised do
|
441
|
+
Author.find(:first, :include => :author_address)
|
442
|
+
AuthorAddress.find(:first, :include => :author)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
def test_self_referential_has_many_through
|
447
|
+
assert_equal [authors(:mary)], authors(:david).favorite_authors
|
448
|
+
assert_equal [], authors(:mary).favorite_authors
|
449
|
+
end
|
450
|
+
|
451
|
+
def test_add_to_self_referential_has_many_through
|
452
|
+
new_author = Author.create(:name => "Bob")
|
453
|
+
authors(:david).author_favorites.create :favorite_author => new_author
|
454
|
+
assert_equal new_author, authors(:david).reload.favorite_authors.first
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_has_many_through_uses_conditions_specified_on_the_has_many_association
|
458
|
+
author = Author.order(:id).first
|
459
|
+
assert_present author.comments
|
460
|
+
assert_blank author.nonexistant_comments
|
461
|
+
end
|
462
|
+
|
463
|
+
def test_has_many_through_uses_correct_attributes
|
464
|
+
assert_nil posts(:thinking).tags.find_by_name("General").attributes["tag_id"]
|
465
|
+
end
|
466
|
+
|
467
|
+
def test_associating_unsaved_records_with_has_many_through
|
468
|
+
saved_post = posts(:thinking)
|
469
|
+
new_tag = Tag.new(:name => "new")
|
470
|
+
|
471
|
+
saved_post.tags << new_tag
|
472
|
+
assert new_tag.persisted? #consistent with habtm!
|
473
|
+
assert saved_post.persisted?
|
474
|
+
assert saved_post.tags.include?(new_tag)
|
475
|
+
|
476
|
+
assert new_tag.persisted?
|
477
|
+
assert new_tag.in?(saved_post.reload.tags(true))
|
478
|
+
|
479
|
+
|
480
|
+
new_post = Post.new(:title => "Association replacmenet works!", :body => "You best believe it.")
|
481
|
+
saved_tag = tags(:general)
|
482
|
+
|
483
|
+
new_post.tags << saved_tag
|
484
|
+
assert !new_post.persisted?
|
485
|
+
assert saved_tag.persisted?
|
486
|
+
assert new_post.tags.include?(saved_tag)
|
487
|
+
|
488
|
+
new_post.save!
|
489
|
+
assert new_post.persisted?
|
490
|
+
assert saved_tag.in?(new_post.reload.tags(true))
|
491
|
+
|
492
|
+
assert !posts(:thinking).tags.build.persisted?
|
493
|
+
assert !posts(:thinking).tags.new.persisted?
|
494
|
+
end
|
495
|
+
|
496
|
+
def test_create_associate_when_adding_to_has_many_through
|
497
|
+
count = posts(:thinking).tags.count
|
498
|
+
push = Tag.create!(:name => 'pushme')
|
499
|
+
post_thinking = posts(:thinking)
|
500
|
+
assert_nothing_raised { post_thinking.tags << push }
|
501
|
+
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
|
502
|
+
message = "Expected a Tag in tags collection, got #{wrong.class}.")
|
503
|
+
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
|
504
|
+
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
505
|
+
assert_equal(count + 1, post_thinking.tags.size)
|
506
|
+
assert_equal(count + 1, post_thinking.tags(true).size)
|
507
|
+
|
508
|
+
assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo')
|
509
|
+
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
|
510
|
+
message = "Expected a Tag in tags collection, got #{wrong.class}.")
|
511
|
+
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
|
512
|
+
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
513
|
+
assert_equal(count + 2, post_thinking.tags.size)
|
514
|
+
assert_equal(count + 2, post_thinking.tags(true).size)
|
515
|
+
|
516
|
+
assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
|
517
|
+
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
|
518
|
+
message = "Expected a Tag in tags collection, got #{wrong.class}.")
|
519
|
+
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
|
520
|
+
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
521
|
+
assert_equal(count + 4, post_thinking.tags.size)
|
522
|
+
assert_equal(count + 4, post_thinking.tags(true).size)
|
523
|
+
|
524
|
+
# Raises if the wrong reflection name is used to set the Edge belongs_to
|
525
|
+
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
526
|
+
end
|
527
|
+
|
528
|
+
def test_add_to_join_table_with_no_id
|
529
|
+
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
530
|
+
end
|
531
|
+
|
532
|
+
def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
|
533
|
+
author = authors(:david)
|
534
|
+
assert_equal 10, author.comments.size
|
535
|
+
assert !author.comments.loaded?
|
536
|
+
end
|
537
|
+
|
538
|
+
def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
|
539
|
+
c = categories(:general)
|
540
|
+
c.categorizations_count = 100
|
541
|
+
assert_equal 100, c.categorizations.size
|
542
|
+
assert !c.categorizations.loaded?
|
543
|
+
end
|
544
|
+
|
545
|
+
def test_adding_junk_to_has_many_through_should_raise_type_mismatch
|
546
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags << "Uhh what now?" }
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_adding_to_has_many_through_should_return_self
|
550
|
+
tags = posts(:thinking).tags
|
551
|
+
assert_equal tags, posts(:thinking).tags.push(tags(:general))
|
552
|
+
end
|
553
|
+
|
554
|
+
def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id
|
555
|
+
count = books(:awdr).references.count
|
556
|
+
references_before = books(:awdr).references
|
557
|
+
book = Book.create!(:name => 'Getting Real')
|
558
|
+
book_awdr = books(:awdr)
|
559
|
+
book_awdr.references << book
|
560
|
+
assert_equal(count + 1, book_awdr.references(true).size)
|
561
|
+
|
562
|
+
assert_nothing_raised { book_awdr.references.delete(book) }
|
563
|
+
assert_equal(count, book_awdr.references.size)
|
564
|
+
assert_equal(count, book_awdr.references(true).size)
|
565
|
+
assert_equal(references_before.sort, book_awdr.references.sort)
|
566
|
+
end
|
567
|
+
|
568
|
+
def test_delete_associate_when_deleting_from_has_many_through
|
569
|
+
count = posts(:thinking).tags.count
|
570
|
+
tags_before = posts(:thinking).tags
|
571
|
+
tag = Tag.create!(:name => 'doomed')
|
572
|
+
post_thinking = posts(:thinking)
|
573
|
+
post_thinking.tags << tag
|
574
|
+
assert_equal(count + 1, post_thinking.taggings(true).size)
|
575
|
+
assert_equal(count + 1, post_thinking.tags(true).size)
|
576
|
+
|
577
|
+
assert_nothing_raised { post_thinking.tags.delete(tag) }
|
578
|
+
assert_equal(count, post_thinking.tags.size)
|
579
|
+
assert_equal(count, post_thinking.tags(true).size)
|
580
|
+
assert_equal(count, post_thinking.taggings(true).size)
|
581
|
+
assert_equal(tags_before.sort, post_thinking.tags.sort)
|
582
|
+
end
|
583
|
+
|
584
|
+
def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags
|
585
|
+
count = posts(:thinking).tags.count
|
586
|
+
tags_before = posts(:thinking).tags
|
587
|
+
doomed = Tag.create!(:name => 'doomed')
|
588
|
+
doomed2 = Tag.create!(:name => 'doomed2')
|
589
|
+
quaked = Tag.create!(:name => 'quaked')
|
590
|
+
post_thinking = posts(:thinking)
|
591
|
+
post_thinking.tags << doomed << doomed2
|
592
|
+
assert_equal(count + 2, post_thinking.tags(true).size)
|
593
|
+
|
594
|
+
assert_nothing_raised { post_thinking.tags.delete(doomed, doomed2, quaked) }
|
595
|
+
assert_equal(count, post_thinking.tags.size)
|
596
|
+
assert_equal(count, post_thinking.tags(true).size)
|
597
|
+
assert_equal(tags_before.sort, post_thinking.tags.sort)
|
598
|
+
end
|
599
|
+
|
600
|
+
def test_deleting_junk_from_has_many_through_should_raise_type_mismatch
|
601
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete("Uhh what now?") }
|
602
|
+
end
|
603
|
+
|
604
|
+
def test_has_many_through_sum_uses_calculations
|
605
|
+
assert_nothing_raised { authors(:david).comments.sum(:post_id) }
|
606
|
+
end
|
607
|
+
|
608
|
+
def test_calculations_on_has_many_through_should_disambiguate_fields
|
609
|
+
assert_nothing_raised { authors(:david).categories.maximum(:id) }
|
610
|
+
end
|
611
|
+
|
612
|
+
def test_calculations_on_has_many_through_should_not_disambiguate_fields_unless_necessary
|
613
|
+
assert_nothing_raised { authors(:david).categories.maximum("categories.id") }
|
614
|
+
end
|
615
|
+
|
616
|
+
def test_has_many_through_has_many_with_sti
|
617
|
+
assert_equal [comments(:does_it_hurt)], authors(:david).special_post_comments
|
618
|
+
end
|
619
|
+
|
620
|
+
def test_uniq_has_many_through_should_retain_order
|
621
|
+
comment_ids = authors(:david).comments.map(&:id)
|
622
|
+
assert_equal comment_ids.sort, authors(:david).ordered_uniq_comments.map(&:id)
|
623
|
+
assert_equal comment_ids.sort.reverse, authors(:david).ordered_uniq_comments_desc.map(&:id)
|
624
|
+
end
|
625
|
+
|
626
|
+
def test_polymorphic_has_many
|
627
|
+
expected = taggings(:welcome_general)
|
628
|
+
p = Post.find(posts(:welcome).id, :include => :taggings)
|
629
|
+
assert_no_queries {assert p.taggings.include?(expected)}
|
630
|
+
assert posts(:welcome).taggings.include?(taggings(:welcome_general))
|
631
|
+
end
|
632
|
+
|
633
|
+
def test_polymorphic_has_one
|
634
|
+
expected = posts(:welcome)
|
635
|
+
|
636
|
+
tagging = Tagging.find(taggings(:welcome_general).id, :include => :taggable)
|
637
|
+
assert_no_queries { assert_equal expected, tagging.taggable}
|
638
|
+
end
|
639
|
+
|
640
|
+
def test_polymorphic_belongs_to
|
641
|
+
p = Post.find(posts(:welcome).id, :include => {:taggings => :taggable})
|
642
|
+
assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable}
|
643
|
+
end
|
644
|
+
|
645
|
+
def test_preload_polymorphic_has_many_through
|
646
|
+
posts = Post.find(:all, :order => 'posts.id')
|
647
|
+
posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
|
648
|
+
assert_equal posts.length, posts_with_tags.length
|
649
|
+
posts.length.times do |i|
|
650
|
+
assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length }
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_preload_polymorph_many_types
|
655
|
+
taggings = Tagging.find :all, :include => :taggable, :conditions => ['taggable_type != ?', 'FakeModel'], :order => 'id'
|
656
|
+
assert_no_queries do
|
657
|
+
taggings.first.taggable.id
|
658
|
+
taggings[1].taggable.id
|
659
|
+
end
|
660
|
+
|
661
|
+
taggables = taggings.map(&:taggable)
|
662
|
+
assert taggables.include?(items(:dvd))
|
663
|
+
assert taggables.include?(posts(:welcome))
|
664
|
+
end
|
665
|
+
|
666
|
+
def test_preload_nil_polymorphic_belongs_to
|
667
|
+
assert_nothing_raised do
|
668
|
+
Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL'])
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_preload_polymorphic_has_many
|
673
|
+
posts = Post.find(:all, :order => 'posts.id')
|
674
|
+
posts_with_taggings = Post.find(:all, :include => :taggings, :order => 'posts.id')
|
675
|
+
assert_equal posts.length, posts_with_taggings.length
|
676
|
+
posts.length.times do |i|
|
677
|
+
assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length }
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
def test_belongs_to_shared_parent
|
682
|
+
comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 1')
|
683
|
+
assert_no_queries do
|
684
|
+
assert_equal comments.first.post, comments[1].post
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
def test_has_many_through_include_uses_array_include_after_loaded
|
689
|
+
david = authors(:david)
|
690
|
+
david.categories.class # force load target
|
691
|
+
|
692
|
+
category = david.categories.first
|
693
|
+
|
694
|
+
assert_no_queries do
|
695
|
+
assert david.categories.loaded?
|
696
|
+
assert david.categories.include?(category)
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
700
|
+
def test_has_many_through_include_checks_if_record_exists_if_target_not_loaded
|
701
|
+
david = authors(:david)
|
702
|
+
category = david.categories.first
|
703
|
+
|
704
|
+
david.reload
|
705
|
+
assert ! david.categories.loaded?
|
706
|
+
assert_queries(1) do
|
707
|
+
assert david.categories.include?(category)
|
708
|
+
end
|
709
|
+
assert ! david.categories.loaded?
|
710
|
+
end
|
711
|
+
|
712
|
+
def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping
|
713
|
+
david = authors(:david)
|
714
|
+
category = Category.create!(:name => 'Not Associated')
|
715
|
+
|
716
|
+
assert ! david.categories.loaded?
|
717
|
+
assert ! david.categories.include?(category)
|
718
|
+
end
|
719
|
+
|
720
|
+
def test_has_many_through_goes_through_all_sti_classes
|
721
|
+
sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1)
|
722
|
+
new_comment = sub_sti_post.comments.create(:body => 'test')
|
723
|
+
|
724
|
+
assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort
|
725
|
+
end
|
726
|
+
|
727
|
+
def test_has_many_with_pluralize_table_names_false
|
728
|
+
aircraft = Aircraft.create!(:name => "Airbus 380")
|
729
|
+
engine = Engine.create!(:car_id => aircraft.id)
|
730
|
+
assert_equal aircraft.engines, [engine]
|
731
|
+
end
|
732
|
+
|
733
|
+
private
|
734
|
+
# create dynamic Post models to allow different dependency options
|
735
|
+
def find_post_with_dependency(post_id, association, association_name, dependency)
|
736
|
+
class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}"
|
737
|
+
Post.find(post_id).update_column :type, class_name
|
738
|
+
klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
|
739
|
+
klass.table_name = 'posts'
|
740
|
+
klass.send(association, association_name, :as => :taggable, :dependent => dependency)
|
741
|
+
klass.find(post_id)
|
742
|
+
end
|
743
|
+
end
|