composite_primary_keys 14.0.6 → 14.0.7

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +6 -0
  3. data/Rakefile +1 -1
  4. data/lib/composite_primary_keys/associations/association.rb +2 -2
  5. data/lib/composite_primary_keys/associations/association_scope.rb +1 -1
  6. data/lib/composite_primary_keys/associations/has_many_through_association.rb +19 -0
  7. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +1 -2
  8. data/lib/composite_primary_keys/relation/query_methods.rb +14 -16
  9. data/lib/composite_primary_keys/relation.rb +199 -197
  10. data/lib/composite_primary_keys/version.rb +1 -1
  11. data/lib/composite_primary_keys.rb +117 -119
  12. data/scripts/console.rb +2 -2
  13. data/tasks/databases/trilogy.rake +23 -0
  14. data/test/abstract_unit.rb +124 -118
  15. data/test/connections/databases.ci.yml +10 -0
  16. data/test/fixtures/admin.rb +4 -0
  17. data/test/fixtures/comments.yml +6 -0
  18. data/test/fixtures/db_definitions/db2-create-tables.sql +34 -0
  19. data/test/fixtures/db_definitions/db2-drop-tables.sql +7 -1
  20. data/test/fixtures/db_definitions/mysql.sql +23 -0
  21. data/test/fixtures/db_definitions/oracle.drop.sql +4 -0
  22. data/test/fixtures/db_definitions/oracle.sql +21 -0
  23. data/test/fixtures/db_definitions/postgresql.sql +23 -0
  24. data/test/fixtures/db_definitions/sqlite.sql +21 -0
  25. data/test/fixtures/db_definitions/sqlserver.sql +23 -0
  26. data/test/fixtures/moderator.rb +4 -0
  27. data/test/fixtures/room.rb +4 -1
  28. data/test/fixtures/staff_room.rb +6 -0
  29. data/test/fixtures/staff_room_key.rb +6 -0
  30. data/test/fixtures/user.rb +3 -0
  31. data/test/fixtures/user_with_polymorphic_name.rb +9 -0
  32. data/test/test_associations.rb +403 -403
  33. data/test/test_has_one_through.rb +30 -0
  34. data/test/test_polymorphic.rb +6 -0
  35. metadata +11 -4
  36. data/lib/composite_primary_keys/associations/through_association.rb +0 -24
@@ -1,403 +1,403 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestAssociations < ActiveSupport::TestCase
4
- fixtures :articles, :products, :tariffs, :product_tariffs, :suburbs, :streets, :restaurants,
5
- :dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
6
- :departments, :employees, :memberships, :membership_statuses
7
-
8
- def test_products
9
- assert_not_nil products(:first_product).product_tariffs
10
- assert_equal 2, products(:first_product).product_tariffs.length
11
- assert_not_nil products(:first_product).tariffs
12
- assert_equal 2, products(:first_product).tariffs.length
13
- end
14
-
15
- def test_product_tariffs
16
- assert_not_nil product_tariffs(:first_flat).product
17
- assert_not_nil product_tariffs(:first_flat).tariff
18
- assert_equal Product, product_tariffs(:first_flat).product.class
19
- assert_equal Tariff, product_tariffs(:first_flat).tariff.class
20
- end
21
-
22
- def test_tariffs
23
- assert_not_nil tariffs(:flat).product_tariffs
24
- assert_equal 1, tariffs(:flat).product_tariffs.length
25
- assert_not_nil tariffs(:flat).products
26
- assert_equal 1, tariffs(:flat).products.length
27
- end
28
-
29
- # Its not generating the instances of associated classes from the rows
30
- def test_find_includes
31
- products = Product.includes(:product_tariffs)
32
- assert_equal(3, products.length)
33
- assert_equal(3, products.inject(0) {|sum, product| sum + product.product_tariffs.length})
34
- end
35
-
36
- def test_find_includes_2
37
- products = ProductTariff.where(:tariff_id => 2).order('product_id, tariff_id').includes(:tariff)
38
- assert_equal(2, products.length)
39
- end
40
-
41
- def test_find_includes_eager_loading
42
- product = products(:second_product)
43
- product_tarrif = product_tariffs(:second_free)
44
-
45
- # First get a legitimate product tarrif
46
- products = Product.includes(:product_tariffs).where('product_tariffs.product_id = ?', product.id).references(:product_tariffs)
47
- assert_equal(1, products.length)
48
- assert_equal(product, products.first)
49
- assert_equal([product_tarrif], products.first.product_tariffs)
50
- end
51
-
52
- def test_find_eager_loading_none
53
- product = products(:third_product)
54
-
55
- products = Product.includes(:product_tariffs).where(:id => product.id).references(:product_tariffs)
56
- assert_equal(1, products.length)
57
- assert_equal(product, products.first)
58
- assert_empty(products.first.product_tariffs)
59
- end
60
-
61
- def test_find_includes_tariffs
62
- tariffs = Tariff.includes(:product_tariffs)
63
- assert_equal(3, tariffs.length)
64
- assert_equal(3, tariffs.inject(0) {|sum, tariff| sum + tariff.product_tariffs.length})
65
- end
66
-
67
- def test_find_each_does_not_throw_error
68
- tariffs = Tariff.includes(:product_tariffs)
69
- worked = false
70
- tariffs.first.product_tariffs.order(:tariff_id).find_each do |pt|
71
- worked = true
72
- end
73
- assert worked
74
- end
75
-
76
- def test_association_with_composite_primary_key_can_be_autosaved
77
- room = Room.new(dorm_id: 1000, room_id: 1001)
78
- room_assignment = RoomAssignment.new(student_id: 1000)
79
- room_assignment.room = room
80
- room_assignment.save
81
- room_assignment.reload
82
- assert_equal(room_assignment.dorm_id, 1000)
83
- assert_equal(room_assignment.room_id, 1001)
84
- end
85
-
86
- def test_has_one_association_is_not_cached_to_where_it_returns_the_wrong_one
87
- engineering = departments(:engineering)
88
- engineering_head = engineering.head
89
- assert_equal(employees(:sarah), engineering_head)
90
-
91
- accounting = departments(:accounting)
92
- accounting_head = accounting.head
93
- assert_equal(employees(:steve), accounting_head)
94
-
95
- refute_equal accounting_head, engineering_head
96
- end
97
-
98
- def test_has_one_association_primary_key_and_foreign_key_are_present
99
- # department = departments(:engineering)
100
- # assert_equal(2, department.employees.count)
101
- # assert_equal('Sarah', department.employees[0].name)
102
- # assert_equal('Robert', department.employees[1].name)
103
- # assert_equal('Sarah', department.head.name)
104
-
105
- department = departments(:human_resources)
106
- assert_equal(1, department.employees.count)
107
- assert_equal('Mindy', department.employees[0].name)
108
- assert_equal('Mindy', department.head.name)
109
-
110
- head = department.create_head(name: 'Rick')
111
- assert_equal(department, head.department)
112
- assert_equal('Rick', department.head.name)
113
-
114
- department.reload
115
- assert_equal(1, department.employees.count)
116
- end
117
-
118
- def test_has_one_autosave
119
- department = departments(:engineering)
120
- assert_equal('Sarah', department.head.name)
121
-
122
- department.head.name = 'Sarah1'
123
- department.save!
124
- assert_equal('Sarah1', department.head.name)
125
- end
126
-
127
- def test_has_no_autosave
128
- department = departments(:engineering)
129
- assert_equal('Sarah', department.head_without_autosave.name)
130
-
131
- department.head_without_autosave.name = 'Sarah1'
132
- department.save!
133
- assert_equal('Sarah1', department.head_without_autosave.name)
134
- end
135
-
136
- def test_has_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
137
- engineering = departments(:engineering)
138
- engineering_employees = engineering.employees
139
-
140
- accounting = departments(:accounting)
141
- accounting_employees = accounting.employees
142
-
143
- refute_equal accounting_employees, engineering_employees
144
- end
145
-
146
- def test_has_many_association_primary_key_and_foreign_key_are_present
147
- department = departments(:accounting)
148
- assert_equal(2, department.employees.count)
149
- assert_equal('Steve', department.employees[0].name)
150
- assert_equal('Jill', department.employees[1].name)
151
-
152
- department.employees.create(name: 'Rick')
153
-
154
- department.reload
155
- assert_equal(3, department.employees.count)
156
- employees = department.employees.sort_by(&:name)
157
- assert_equal('Jill', employees[0].name)
158
- assert_equal('Rick', employees[1].name)
159
- assert_equal('Steve', employees[2].name)
160
- end
161
-
162
- def test_find_includes_product_tariffs_product
163
- # Old style
164
- product_tariffs = ProductTariff.includes(:product)
165
- assert_not_nil(product_tariffs)
166
- assert_equal(3, product_tariffs.length)
167
-
168
- # New style
169
- product_tariffs = ProductTariff.includes(:product)
170
- assert_not_nil(product_tariffs)
171
- assert_equal(3, product_tariffs.length)
172
- end
173
-
174
- def test_find_includes_product_tariffs_tariff
175
- # Old style
176
- product_tariffs = ProductTariff.includes(:tariff)
177
- assert_equal(3, product_tariffs.length)
178
-
179
- # New style
180
- product_tariffs = ProductTariff.includes(:tariff)
181
- assert_equal(3, product_tariffs.length)
182
- end
183
-
184
- def test_has_many_through
185
- products = Product.includes(:tariffs)
186
- assert_equal(3, products.length)
187
-
188
- tarrifs_length = products.inject(0) {|sum, product| sum + product.tariffs.length}
189
- assert_equal(3, tarrifs_length)
190
- end
191
-
192
- def test_has_many_through_2
193
- assert_equal(3, Article.count)
194
- user = users(:santiago)
195
- article_names = user.articles.map(&:name).sort
196
- assert_equal(['Article One', 'Article Two'], article_names)
197
- end
198
-
199
- def test_new_style_includes_with_conditions
200
- product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
201
- assert_equal(0, product_tariff.tariff.amount)
202
- end
203
-
204
- def test_find_product_includes
205
- products = Product.includes(:product_tariffs => :tariff)
206
- assert_equal(3, products.length)
207
-
208
- product_tariffs_length = products.inject(0) {|sum, product| sum + product.product_tariffs.length}
209
- assert_equal(3, product_tariffs_length)
210
- end
211
-
212
- def test_has_many_through_when_not_pre_loaded
213
- student = Student.first
214
- rooms = student.rooms
215
- assert_equal(1, rooms.size)
216
- assert_equal(1, rooms.first.dorm_id)
217
- assert_equal(1, rooms.first.room_id)
218
- end
219
-
220
- def test_has_many_through_when_through_association_is_composite
221
- dorm = Dorm.first
222
- assert_equal(3, dorm.rooms.length)
223
- assert_equal(1, dorm.rooms.first.room_attributes.length)
224
- assert_equal('type', dorm.rooms.first.room_attributes.first.name)
225
- end
226
-
227
- def test_associations_with_conditions
228
- suburb = Suburb.find([2, 2])
229
- assert_equal 2, suburb.streets.size
230
- assert_equal 1, suburb.first_streets.size
231
- end
232
-
233
- def test_composite_has_many_composites
234
- room = rooms(:branner_room_1)
235
- assert_equal(2, room.room_assignments.length)
236
- assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
237
- assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
238
- end
239
-
240
- def test_composite_belongs_to_composite
241
- room_assignment = room_assignments(:jacksons_room)
242
- assert_equal(rooms(:branner_room_1), room_assignment.room)
243
- end
244
-
245
- def test_composite_belongs_to_changes
246
- room_assignment = room_assignments(:jacksons_room)
247
- room_assignment.room = rooms(:branner_room_2)
248
- # This was raising an error before:
249
- # TypeError: [:dorm_id, :room_id] is not a symbol
250
- # changes returns HashWithIndifferentAccess
251
- assert_equal({"room_id"=>[1, 2]}, room_assignment.changes)
252
-
253
- steve = employees(:steve)
254
- steve.department = departments(:engineering)
255
- # It was returning this before:
256
- # {"[:id, :location_id]"=>[nil, [2, 1]]}
257
- assert_equal({"department_id"=>[1, 2]}, steve.changes)
258
- end
259
-
260
- def test_composite_belongs_to_setting_to_nil
261
- room_assignment = room_assignments(:jacksons_room)
262
- # This was raising an error before:
263
- # NoMethodError: undefined method `length' for nil:NilClass
264
- assert_nothing_raised { room_assignment.room = nil }
265
- end
266
-
267
- def test_has_one_with_composite
268
- # In this case a regular model has_one composite model
269
- department = departments(:engineering)
270
- assert_not_nil(department.head)
271
- end
272
-
273
- def test_has_many_build_simple_key
274
- user = users(:santiago)
275
- reading = user.readings.build
276
- assert_equal user.id, reading.user_id
277
- assert_equal user, reading.user
278
- end
279
-
280
- def test_has_many_build_composite_key
281
- department = departments(:engineering)
282
- employee = department.employees.build
283
- assert_equal(department[:id], employee.department_id)
284
- assert_equal(department.location_id, employee.location_id)
285
- assert_equal(department, employee.department)
286
- end
287
-
288
- def test_has_many_with_primary_key
289
- @membership = Membership.find([1, 1])
290
- assert_equal 2, @membership.readings.size
291
- end
292
-
293
- def test_has_many_with_composite_key
294
- # In this case a regular model (Dorm) has_many composite models (Rooms)
295
- dorm = dorms(:branner)
296
- assert_equal(3, dorm.rooms.length)
297
- assert_equal(1, dorm.rooms[0].room_id)
298
- assert_equal(2, dorm.rooms[1].room_id)
299
- assert_equal(3, dorm.rooms[2].room_id)
300
- end
301
-
302
- def test_has_many_with_foreign_composite_key
303
- tariff = Tariff.find_by('tariff_id = ?', 2)
304
- assert_equal(2, tariff.product_tariffs.length)
305
- end
306
-
307
- def test_joins_has_many_with_primary_key
308
- #@membership = Membership.find(:first, :joins => :readings, :conditions => { :readings => { :id => 1 } })
309
- @membership = Membership.joins(:readings).where(readings: { id: 1 }).first
310
-
311
- assert_equal [1, 1], @membership.id
312
- end
313
-
314
- def test_joins_has_one_with_primary_key
315
- @membership = Membership.joins(:readings).where(readings: { id: 2 }).first
316
-
317
- assert_equal [1, 1], @membership.id
318
- end
319
-
320
- def test_has_many_through_with_conditions_when_through_association_is_not_composite
321
- user = User.first
322
- assert_equal 1, user.articles.where("articles.name = ?", "Article One").size
323
- end
324
-
325
- def test_has_many_through_with_conditions_when_through_association_is_composite
326
- room = Room.first
327
- assert_equal 0, room.room_attributes.where("room_attributes.name != ?", "type").size
328
- end
329
-
330
- def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
331
- user = User.first
332
- assert_equal(1, user.find_custom_articles.size)
333
- end
334
-
335
- def test_has_many_through_on_custom_finder_when_through_association_is_composite
336
- room = Room.first
337
- assert_equal(0, room.find_custom_room_attributes.size)
338
- end
339
-
340
- def test_has_many_with_primary_key_with_associations
341
- memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
342
- assert_equal(2, memberships.length)
343
- assert_equal([1,1], memberships[0].id)
344
- assert_equal([3,2], memberships[1].id)
345
- end
346
-
347
- def test_limitable_reflections
348
- memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
349
- assert_equal(2, memberships.length)
350
-
351
- assert_equal([1,1], memberships[0].id)
352
- assert_equal([3,2], memberships[1].id)
353
- end
354
-
355
- def test_scoped_has_many_with_primary_key_with_associations
356
- memberships = Membership.joins(:active_statuses)
357
- assert_equal(2, memberships.length)
358
-
359
- assert_equal([1,1], memberships[0].id)
360
- assert_equal([3,2], memberships[1].id)
361
- end
362
-
363
- def test_foreign_key_present_with_null_association_ids
364
- group = Group.new
365
- group.memberships.build
366
- associations = group.association(:memberships)
367
- assert_equal(false, associations.send('foreign_key_present?'))
368
- end
369
-
370
- def test_assignment_by_ids_as_arrays
371
- room = Room.create dorm: dorms(:branner), room_id: 4
372
- room.room_assignment_ids = [[3, 1, 2], [4, 1, 2]]
373
- room.save!
374
- assert_equal room.room_assignments.map(&:student_id), [3, 4]
375
- end
376
-
377
- def test_assignment_by_ids_as_arrays_that_contains_a_comma
378
- room = Room.create dorm: dorms(:branner), room_id: 4
379
- e = assert_raises ActiveRecord::RecordNotFound do
380
- room.room_assignment_ids = [['5,,', '5,,', '5,,']]
381
- end
382
- assert_match /'student_id,dorm_id,room_id'=\[\[5, 5, 5\]\]/, e.message
383
- end
384
-
385
- def test_assignment_by_ids_as_strings
386
- room = Room.create dorm: dorms(:branner), room_id: 4
387
- room.room_assignment_ids = ['3,1,2', '4,1,2']
388
- room.save!
389
- assert_equal room.room_assignments.map(&:student_id), [3, 4]
390
- end
391
-
392
- def test_assignment_by_ids_for_non_CPK_case
393
- article = Article.new
394
- article.reading_ids = Reading.pluck(:id)
395
- assert_equal article.reading_ids, Reading.pluck(:id)
396
- end
397
-
398
- def test_find_by_association
399
- assert_equal Membership.where(user: '1').count, 1
400
- assert_equal Membership.where(user_id: '1').count, 1
401
- assert_equal Membership.where(user: User.find(1)).count, 1
402
- end
403
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestAssociations < ActiveSupport::TestCase
4
+ fixtures :articles, :products, :tariffs, :product_tariffs, :suburbs, :streets, :restaurants,
5
+ :dorms, :rooms, :room_attributes, :room_attribute_assignments, :students, :room_assignments, :users, :readings,
6
+ :departments, :employees, :memberships, :membership_statuses
7
+
8
+ def test_products
9
+ assert_not_nil products(:first_product).product_tariffs
10
+ assert_equal 2, products(:first_product).product_tariffs.length
11
+ assert_not_nil products(:first_product).tariffs
12
+ assert_equal 2, products(:first_product).tariffs.length
13
+ end
14
+
15
+ def test_product_tariffs
16
+ assert_not_nil product_tariffs(:first_flat).product
17
+ assert_not_nil product_tariffs(:first_flat).tariff
18
+ assert_equal Product, product_tariffs(:first_flat).product.class
19
+ assert_equal Tariff, product_tariffs(:first_flat).tariff.class
20
+ end
21
+
22
+ def test_tariffs
23
+ assert_not_nil tariffs(:flat).product_tariffs
24
+ assert_equal 1, tariffs(:flat).product_tariffs.length
25
+ assert_not_nil tariffs(:flat).products
26
+ assert_equal 1, tariffs(:flat).products.length
27
+ end
28
+
29
+ # Its not generating the instances of associated classes from the rows
30
+ def test_find_includes
31
+ products = Product.includes(:product_tariffs)
32
+ assert_equal(3, products.length)
33
+ assert_equal(3, products.inject(0) {|sum, product| sum + product.product_tariffs.length})
34
+ end
35
+
36
+ def test_find_includes_2
37
+ products = ProductTariff.where(:tariff_id => 2).order('product_id, tariff_id').includes(:tariff)
38
+ assert_equal(2, products.length)
39
+ end
40
+
41
+ def test_find_includes_eager_loading
42
+ product = products(:second_product)
43
+ product_tarrif = product_tariffs(:second_free)
44
+
45
+ # First get a legitimate product tarrif
46
+ products = Product.includes(:product_tariffs).where('product_tariffs.product_id = ?', product.id).references(:product_tariffs)
47
+ assert_equal(1, products.length)
48
+ assert_equal(product, products.first)
49
+ assert_equal([product_tarrif], products.first.product_tariffs)
50
+ end
51
+
52
+ def test_find_eager_loading_none
53
+ product = products(:third_product)
54
+
55
+ products = Product.includes(:product_tariffs).where(:id => product.id).references(:product_tariffs)
56
+ assert_equal(1, products.length)
57
+ assert_equal(product, products.first)
58
+ assert_empty(products.first.product_tariffs)
59
+ end
60
+
61
+ def test_find_includes_tariffs
62
+ tariffs = Tariff.includes(:product_tariffs)
63
+ assert_equal(3, tariffs.length)
64
+ assert_equal(3, tariffs.inject(0) {|sum, tariff| sum + tariff.product_tariffs.length})
65
+ end
66
+
67
+ def test_find_each_does_not_throw_error
68
+ tariffs = Tariff.includes(:product_tariffs)
69
+ worked = false
70
+ tariffs.first.product_tariffs.order(:tariff_id).find_each do |pt|
71
+ worked = true
72
+ end
73
+ assert worked
74
+ end
75
+
76
+ def test_association_with_composite_primary_key_can_be_autosaved
77
+ room = Room.new(dorm_id: 1000, room_id: 1001)
78
+ room_assignment = RoomAssignment.new(student_id: 1000)
79
+ room_assignment.room = room
80
+ room_assignment.save
81
+ room_assignment.reload
82
+ assert_equal(room_assignment.dorm_id, 1000)
83
+ assert_equal(room_assignment.room_id, 1001)
84
+ end
85
+
86
+ def test_has_one_association_is_not_cached_to_where_it_returns_the_wrong_one
87
+ engineering = departments(:engineering)
88
+ engineering_head = engineering.head
89
+ assert_equal(employees(:sarah), engineering_head)
90
+
91
+ accounting = departments(:accounting)
92
+ accounting_head = accounting.head
93
+ assert_equal(employees(:steve), accounting_head)
94
+
95
+ refute_equal accounting_head, engineering_head
96
+ end
97
+
98
+ def test_has_one_association_primary_key_and_foreign_key_are_present
99
+ # department = departments(:engineering)
100
+ # assert_equal(2, department.employees.count)
101
+ # assert_equal('Sarah', department.employees[0].name)
102
+ # assert_equal('Robert', department.employees[1].name)
103
+ # assert_equal('Sarah', department.head.name)
104
+
105
+ department = departments(:human_resources)
106
+ assert_equal(1, department.employees.count)
107
+ assert_equal('Mindy', department.employees[0].name)
108
+ assert_equal('Mindy', department.head.name)
109
+
110
+ head = department.create_head(name: 'Rick')
111
+ assert_equal(department, head.department)
112
+ assert_equal('Rick', department.head.name)
113
+
114
+ department.reload
115
+ assert_equal(1, department.employees.count)
116
+ end
117
+
118
+ def test_has_one_autosave
119
+ department = departments(:engineering)
120
+ assert_equal('Sarah', department.head.name)
121
+
122
+ department.head.name = 'Sarah1'
123
+ department.save!
124
+ assert_equal('Sarah1', department.head.name)
125
+ end
126
+
127
+ def test_has_no_autosave
128
+ department = departments(:engineering)
129
+ assert_equal('Sarah', department.head_without_autosave.name)
130
+
131
+ department.head_without_autosave.name = 'Sarah1'
132
+ department.save!
133
+ assert_equal('Sarah1', department.head_without_autosave.name)
134
+ end
135
+
136
+ def test_has_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
137
+ engineering = departments(:engineering)
138
+ engineering_employees = engineering.employees
139
+
140
+ accounting = departments(:accounting)
141
+ accounting_employees = accounting.employees
142
+
143
+ refute_equal accounting_employees, engineering_employees
144
+ end
145
+
146
+ def test_has_many_association_primary_key_and_foreign_key_are_present
147
+ department = departments(:accounting)
148
+ assert_equal(2, department.employees.count)
149
+ assert_equal('Steve', department.employees[0].name)
150
+ assert_equal('Jill', department.employees[1].name)
151
+
152
+ department.employees.create(name: 'Rick')
153
+
154
+ department.reload
155
+ assert_equal(3, department.employees.count)
156
+ employees = department.employees.sort_by(&:name)
157
+ assert_equal('Jill', employees[0].name)
158
+ assert_equal('Rick', employees[1].name)
159
+ assert_equal('Steve', employees[2].name)
160
+ end
161
+
162
+ def test_find_includes_product_tariffs_product
163
+ # Old style
164
+ product_tariffs = ProductTariff.includes(:product)
165
+ assert_not_nil(product_tariffs)
166
+ assert_equal(3, product_tariffs.length)
167
+
168
+ # New style
169
+ product_tariffs = ProductTariff.includes(:product)
170
+ assert_not_nil(product_tariffs)
171
+ assert_equal(3, product_tariffs.length)
172
+ end
173
+
174
+ def test_find_includes_product_tariffs_tariff
175
+ # Old style
176
+ product_tariffs = ProductTariff.includes(:tariff)
177
+ assert_equal(3, product_tariffs.length)
178
+
179
+ # New style
180
+ product_tariffs = ProductTariff.includes(:tariff)
181
+ assert_equal(3, product_tariffs.length)
182
+ end
183
+
184
+ def test_has_many_through
185
+ products = Product.includes(:tariffs)
186
+ assert_equal(3, products.length)
187
+
188
+ tarrifs_length = products.inject(0) {|sum, product| sum + product.tariffs.length}
189
+ assert_equal(3, tarrifs_length)
190
+ end
191
+
192
+ def test_has_many_through_2
193
+ assert_equal(3, Article.count)
194
+ user = users(:santiago)
195
+ article_names = user.articles.map(&:name).sort
196
+ assert_equal(['Article One', 'Article Two'], article_names)
197
+ end
198
+
199
+ def test_new_style_includes_with_conditions
200
+ product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
201
+ assert_equal(0, product_tariff.tariff.amount)
202
+ end
203
+
204
+ def test_find_product_includes
205
+ products = Product.includes(:product_tariffs => :tariff)
206
+ assert_equal(3, products.length)
207
+
208
+ product_tariffs_length = products.inject(0) {|sum, product| sum + product.product_tariffs.length}
209
+ assert_equal(3, product_tariffs_length)
210
+ end
211
+
212
+ def test_has_many_through_when_not_pre_loaded
213
+ student = Student.first
214
+ rooms = student.rooms
215
+ assert_equal(1, rooms.size)
216
+ assert_equal(1, rooms.first.dorm_id)
217
+ assert_equal(1, rooms.first.room_id)
218
+ end
219
+
220
+ def test_has_many_through_when_through_association_is_composite
221
+ dorm = Dorm.first
222
+ assert_equal(3, dorm.rooms.length)
223
+ assert_equal(1, dorm.rooms.first.room_attributes.length)
224
+ assert_equal('type', dorm.rooms.first.room_attributes.first.name)
225
+ end
226
+
227
+ def test_associations_with_conditions
228
+ suburb = Suburb.find([2, 2])
229
+ assert_equal 2, suburb.streets.size
230
+ assert_equal 1, suburb.first_streets.size
231
+ end
232
+
233
+ def test_composite_has_many_composites
234
+ room = rooms(:branner_room_1)
235
+ assert_equal(2, room.room_assignments.length)
236
+ assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
237
+ assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
238
+ end
239
+
240
+ def test_composite_belongs_to_composite
241
+ room_assignment = room_assignments(:jacksons_room)
242
+ assert_equal(rooms(:branner_room_1), room_assignment.room)
243
+ end
244
+
245
+ def test_composite_belongs_to_changes
246
+ room_assignment = room_assignments(:jacksons_room)
247
+ room_assignment.room = rooms(:branner_room_2)
248
+ # This was raising an error before:
249
+ # TypeError: [:dorm_id, :room_id] is not a symbol
250
+ # changes returns HashWithIndifferentAccess
251
+ assert_equal({"room_id"=>[1, 2]}, room_assignment.changes)
252
+
253
+ steve = employees(:steve)
254
+ steve.department = departments(:engineering)
255
+ # It was returning this before:
256
+ # {"[:id, :location_id]"=>[nil, [2, 1]]}
257
+ assert_equal({"department_id"=>[1, 2]}, steve.changes)
258
+ end
259
+
260
+ def test_composite_belongs_to_setting_to_nil
261
+ room_assignment = room_assignments(:jacksons_room)
262
+ # This was raising an error before:
263
+ # NoMethodError: undefined method `length' for nil:NilClass
264
+ assert_nothing_raised { room_assignment.room = nil }
265
+ end
266
+
267
+ def test_has_one_with_composite
268
+ # In this case a regular model has_one composite model
269
+ department = departments(:engineering)
270
+ assert_not_nil(department.head)
271
+ end
272
+
273
+ def test_has_many_build_simple_key
274
+ user = users(:santiago)
275
+ reading = user.readings.build
276
+ assert_equal user.id, reading.user_id
277
+ assert_equal user, reading.user
278
+ end
279
+
280
+ def test_has_many_build_composite_key
281
+ department = departments(:engineering)
282
+ employee = department.employees.build
283
+ assert_equal(department[:id], employee.department_id)
284
+ assert_equal(department.location_id, employee.location_id)
285
+ assert_equal(department, employee.department)
286
+ end
287
+
288
+ def test_has_many_with_primary_key
289
+ @membership = Membership.find([1, 1])
290
+ assert_equal 2, @membership.readings.size
291
+ end
292
+
293
+ def test_has_many_with_composite_key
294
+ # In this case a regular model (Dorm) has_many composite models (Rooms)
295
+ dorm = dorms(:branner)
296
+ assert_equal(3, dorm.rooms.length)
297
+ assert_equal(1, dorm.rooms[0].room_id)
298
+ assert_equal(2, dorm.rooms[1].room_id)
299
+ assert_equal(3, dorm.rooms[2].room_id)
300
+ end
301
+
302
+ def test_has_many_with_foreign_composite_key
303
+ tariff = Tariff.find_by('tariff_id = ?', 2)
304
+ assert_equal(2, tariff.product_tariffs.length)
305
+ end
306
+
307
+ def test_joins_has_many_with_primary_key
308
+ #@membership = Membership.find(:first, :joins => :readings, :conditions => { :readings => { :id => 1 } })
309
+ @membership = Membership.joins(:readings).where(readings: { id: 1 }).first
310
+
311
+ assert_equal [1, 1], @membership.id
312
+ end
313
+
314
+ def test_joins_has_one_with_primary_key
315
+ @membership = Membership.joins(:readings).where(readings: { id: 2 }).first
316
+
317
+ assert_equal [1, 1], @membership.id
318
+ end
319
+
320
+ def test_has_many_through_with_conditions_when_through_association_is_not_composite
321
+ user = User.first
322
+ assert_equal 1, user.articles.where("articles.name = ?", "Article One").size
323
+ end
324
+
325
+ def test_has_many_through_with_conditions_when_through_association_is_composite
326
+ room = Room.first
327
+ assert_equal 0, room.room_attributes.where("room_attributes.name != ?", "type").size
328
+ end
329
+
330
+ def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
331
+ user = User.first
332
+ assert_equal(1, user.find_custom_articles.size)
333
+ end
334
+
335
+ def test_has_many_through_on_custom_finder_when_through_association_is_composite
336
+ room = Room.first
337
+ assert_equal(0, room.find_custom_room_attributes.size)
338
+ end
339
+
340
+ def test_has_many_with_primary_key_with_associations
341
+ memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
342
+ assert_equal(2, memberships.length)
343
+ assert_equal([1,1], memberships[0].id)
344
+ assert_equal([3,2], memberships[1].id)
345
+ end
346
+
347
+ def test_limitable_reflections
348
+ memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
349
+ assert_equal(2, memberships.length)
350
+
351
+ assert_equal([1,1], memberships[0].id)
352
+ assert_equal([3,2], memberships[1].id)
353
+ end
354
+
355
+ def test_scoped_has_many_with_primary_key_with_associations
356
+ memberships = Membership.joins(:active_statuses)
357
+ assert_equal(2, memberships.length)
358
+
359
+ assert_equal([1,1], memberships[0].id)
360
+ assert_equal([3,2], memberships[1].id)
361
+ end
362
+
363
+ def test_foreign_key_present_with_null_association_ids
364
+ group = Group.new
365
+ group.memberships.build
366
+ associations = group.association(:memberships)
367
+ assert_equal(false, associations.send('foreign_key_present?'))
368
+ end
369
+
370
+ def test_assignment_by_ids_as_arrays
371
+ room = Room.create dorm: dorms(:branner), room_id: 4
372
+ room.room_assignment_ids = [[3, 1, 2], [4, 1, 2]]
373
+ room.save!
374
+ assert_equal room.room_assignments.map(&:student_id), [3, 4]
375
+ end
376
+
377
+ def test_assignment_by_ids_as_arrays_that_contains_a_comma
378
+ room = Room.create dorm: dorms(:branner), room_id: 4
379
+ e = assert_raises ActiveRecord::RecordNotFound do
380
+ room.room_assignment_ids = [['5,,', '5,,', '5,,']]
381
+ end
382
+ assert_match /'student_id,dorm_id,room_id'=\[\[5, 5, 5\]\]/, e.message
383
+ end
384
+
385
+ def test_assignment_by_ids_as_strings
386
+ room = Room.create dorm: dorms(:branner), room_id: 4
387
+ room.room_assignment_ids = ['3,1,2', '4,1,2']
388
+ room.save!
389
+ assert_equal room.room_assignments.map(&:student_id), [3, 4]
390
+ end
391
+
392
+ def test_assignment_by_ids_for_non_CPK_case
393
+ article = Article.new
394
+ article.reading_ids = Reading.pluck(:id)
395
+ assert_equal article.reading_ids, Reading.pluck(:id)
396
+ end
397
+
398
+ def test_find_by_association
399
+ assert_equal Membership.where(user: '1').count, 1
400
+ assert_equal Membership.where(user_id: '1').count, 1
401
+ assert_equal Membership.where(user: User.find(1)).count, 1
402
+ end
403
+ end