composite_primary_keys 12.0.2 → 12.0.10

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +880 -841
  3. data/README.rdoc +180 -179
  4. data/lib/composite_primary_keys/active_model/attribute_assignment.rb +19 -0
  5. data/lib/composite_primary_keys/arel/sqlserver.rb +1 -3
  6. data/lib/composite_primary_keys/associations/association_scope.rb +68 -68
  7. data/lib/composite_primary_keys/associations/join_dependency.rb +103 -103
  8. data/lib/composite_primary_keys/associations/through_association.rb +2 -1
  9. data/lib/composite_primary_keys/attribute_methods/primary_key.rb +13 -0
  10. data/lib/composite_primary_keys/attribute_methods/read.rb +30 -30
  11. data/lib/composite_primary_keys/attribute_methods/write.rb +35 -35
  12. data/lib/composite_primary_keys/attribute_methods.rb +9 -9
  13. data/lib/composite_primary_keys/base.rb +141 -130
  14. data/lib/composite_primary_keys/composite_arrays.rb +0 -8
  15. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +37 -17
  16. data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +44 -23
  17. data/lib/composite_primary_keys/core.rb +48 -48
  18. data/lib/composite_primary_keys/persistence.rb +82 -81
  19. data/lib/composite_primary_keys/reflection.rb +29 -29
  20. data/lib/composite_primary_keys/relation/batches.rb +1 -1
  21. data/lib/composite_primary_keys/relation/calculations.rb +81 -81
  22. data/lib/composite_primary_keys/relation/finder_methods.rb +235 -235
  23. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +20 -20
  24. data/lib/composite_primary_keys/relation/query_methods.rb +42 -42
  25. data/lib/composite_primary_keys/relation/where_clause.rb +23 -23
  26. data/lib/composite_primary_keys/relation.rb +193 -118
  27. data/lib/composite_primary_keys/version.rb +8 -8
  28. data/lib/composite_primary_keys.rb +117 -118
  29. data/test/abstract_unit.rb +114 -113
  30. data/test/connections/databases.ci.yml +22 -19
  31. data/test/fixtures/article.rb +4 -0
  32. data/test/fixtures/articles.yml +4 -3
  33. data/test/fixtures/comment.rb +1 -3
  34. data/test/fixtures/comments.yml +10 -9
  35. data/test/fixtures/db_definitions/db2-create-tables.sql +112 -126
  36. data/test/fixtures/db_definitions/db2-drop-tables.sql +17 -19
  37. data/test/fixtures/db_definitions/mysql.sql +180 -217
  38. data/test/fixtures/db_definitions/oracle.drop.sql +42 -48
  39. data/test/fixtures/db_definitions/oracle.sql +200 -236
  40. data/test/fixtures/db_definitions/postgresql.sql +183 -220
  41. data/test/fixtures/db_definitions/sqlite.sql +170 -206
  42. data/test/fixtures/db_definitions/sqlserver.sql +176 -212
  43. data/test/fixtures/department.rb +16 -11
  44. data/test/fixtures/departments.yml +15 -15
  45. data/test/fixtures/employees.yml +27 -27
  46. data/test/fixtures/readings.yml +2 -2
  47. data/test/fixtures/restaurants_suburbs.yml +11 -11
  48. data/test/fixtures/streets.yml +16 -16
  49. data/test/fixtures/suburbs.yml +14 -14
  50. data/test/fixtures/user.rb +11 -10
  51. data/test/test_associations.rb +358 -351
  52. data/test/test_attributes.rb +60 -60
  53. data/test/test_calculations.rb +42 -42
  54. data/test/test_create.rb +218 -183
  55. data/test/test_delete.rb +182 -179
  56. data/test/test_exists.rb +39 -39
  57. data/test/test_find.rb +164 -145
  58. data/test/test_habtm.rb +2 -2
  59. data/test/test_ids.rb +112 -116
  60. data/test/test_nested_attributes.rb +67 -124
  61. data/test/test_polymorphic.rb +29 -13
  62. data/test/test_preload.rb +4 -3
  63. data/test/test_serialize.rb +2 -2
  64. data/test/test_update.rb +96 -78
  65. metadata +4 -19
  66. data/test/fixtures/hack.rb +0 -5
  67. data/test/fixtures/hacks.yml +0 -3
  68. data/test/fixtures/pk_called_id.rb +0 -5
  69. data/test/fixtures/pk_called_ids.yml +0 -11
  70. data/test/fixtures/reference_code_using_composite_key_alias.rb +0 -8
  71. data/test/fixtures/reference_code_using_simple_key_alias.rb +0 -8
  72. data/test/fixtures/seat.rb +0 -5
  73. data/test/fixtures/seats.yml +0 -9
  74. data/test/fixtures/topic.rb +0 -6
  75. data/test/fixtures/topic_source.rb +0 -7
  76. data/test/test_aliases.rb +0 -18
  77. data/test/test_enum.rb +0 -21
  78. data/test/test_suite.rb +0 -35
@@ -1,351 +1,358 @@
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(:human_resources)
100
-
101
- assert_equal(1, department.employees.count)
102
- assert_equal('Mindy', department.employees[0].name)
103
-
104
- head = department.create_head(name: 'Rick')
105
- assert_equal(department.department_id, head.department_id)
106
- assert_equal(department.location_id, head.location_id)
107
-
108
- department.reload
109
- assert_equal(1, department.employees.count)
110
- assert_equal('Rick', department.employees[0].name)
111
- end
112
-
113
- def test_has_one_autosave
114
- department = departments(:engineering)
115
- assert_equal('Sarah', department.head.name)
116
-
117
- department.head.name = 'Sarah1'
118
- department.save!
119
- assert_equal('Sarah1', department.head.name)
120
- end
121
-
122
- def test_has_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
123
- engineering = departments(:engineering)
124
- engineering_employees = engineering.employees
125
-
126
- accounting = departments(:accounting)
127
- accounting_employees = accounting.employees
128
-
129
- refute_equal accounting_employees, engineering_employees
130
- end
131
-
132
- def test_has_many_association_primary_key_and_foreign_key_are_present
133
- department = departments(:accounting)
134
- assert_equal(2, department.employees.count)
135
- assert_equal('Steve', department.employees[0].name)
136
- assert_equal('Jill', department.employees[1].name)
137
-
138
- department.employees.create(name: 'Rick')
139
-
140
- department.reload
141
- assert_equal(3, department.employees.count)
142
- assert_equal('Steve', department.employees[0].name)
143
- assert_equal('Jill', department.employees[1].name)
144
- assert_equal('Rick', department.employees[2].name)
145
- end
146
-
147
- def test_find_includes_product_tariffs_product
148
- # Old style
149
- product_tariffs = ProductTariff.includes(:product)
150
- assert_not_nil(product_tariffs)
151
- assert_equal(3, product_tariffs.length)
152
-
153
- # New style
154
- product_tariffs = ProductTariff.includes(:product)
155
- assert_not_nil(product_tariffs)
156
- assert_equal(3, product_tariffs.length)
157
- end
158
-
159
- def test_find_includes_product_tariffs_tariff
160
- # Old style
161
- product_tariffs = ProductTariff.includes(:tariff)
162
- assert_equal(3, product_tariffs.length)
163
-
164
- # New style
165
- product_tariffs = ProductTariff.includes(:tariff)
166
- assert_equal(3, product_tariffs.length)
167
- end
168
-
169
- def test_has_many_through
170
- products = Product.includes(:tariffs)
171
- assert_equal(3, products.length)
172
-
173
- tarrifs_length = products.inject(0) {|sum, product| sum + product.tariffs.length}
174
- assert_equal(3, tarrifs_length)
175
- end
176
-
177
- def test_new_style_includes_with_conditions
178
- product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
179
- assert_equal(0, product_tariff.tariff.amount)
180
- end
181
-
182
- def test_find_product_includes
183
- products = Product.includes(:product_tariffs => :tariff)
184
- assert_equal(3, products.length)
185
-
186
- product_tariffs_length = products.inject(0) {|sum, product| sum + product.product_tariffs.length}
187
- assert_equal(3, product_tariffs_length)
188
- end
189
-
190
- def test_has_many_through_when_not_pre_loaded
191
- student = Student.first
192
- rooms = student.rooms
193
- assert_equal(1, rooms.size)
194
- assert_equal(1, rooms.first.dorm_id)
195
- assert_equal(1, rooms.first.room_id)
196
- end
197
-
198
- def test_has_many_through_when_through_association_is_composite
199
- dorm = Dorm.first
200
- assert_equal(3, dorm.rooms.length)
201
- assert_equal(1, dorm.rooms.first.room_attributes.length)
202
- assert_equal('type', dorm.rooms.first.room_attributes.first.name)
203
- end
204
-
205
- def test_associations_with_conditions
206
- suburb = Suburb.find([2, 1])
207
- assert_equal 2, suburb.streets.size
208
-
209
- suburb = Suburb.find([2, 1])
210
- assert_equal 1, suburb.first_streets.size
211
-
212
- suburb = Suburb.includes(:streets).find([2, 1])
213
- assert_equal 2, suburb.streets.size
214
-
215
- suburb = Suburb.includes(:first_streets).find([2, 1])
216
- assert_equal 1, suburb.first_streets.size
217
- end
218
-
219
- def test_composite_has_many_composites
220
- room = rooms(:branner_room_1)
221
- assert_equal(2, room.room_assignments.length)
222
- assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
223
- assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
224
- end
225
-
226
- def test_composite_belongs_to_composite
227
- room_assignment = room_assignments(:jacksons_room)
228
- assert_equal(rooms(:branner_room_1), room_assignment.room)
229
- end
230
-
231
- def test_composite_belongs_to_changes
232
- room_assignment = room_assignments(:jacksons_room)
233
- room_assignment.room = rooms(:branner_room_2)
234
- # This was raising an error before:
235
- # TypeError: [:dorm_id, :room_id] is not a symbol
236
- # changes returns HashWithIndifferentAccess
237
- assert_equal({"room_id"=>[1, 2]}, room_assignment.changes)
238
-
239
- steve = employees(:steve)
240
- steve.department = departments(:engineering)
241
- # It was returning this before:
242
- # {"[:department_id, :location_id]"=>[nil, [2, 1]]}
243
- assert_equal({"department_id"=>[1, 2]}, steve.changes)
244
- end
245
-
246
- def test_composite_belongs_to_setting_to_nil
247
- room_assignment = room_assignments(:jacksons_room)
248
- # This was raising an error before:
249
- # NoMethodError: undefined method `length' for nil:NilClass
250
- assert_nothing_raised { room_assignment.room = nil }
251
- end
252
-
253
- def test_has_one_with_composite
254
- # In this case a regular model has_one composite model
255
- department = departments(:engineering)
256
- assert_not_nil(department.head)
257
- end
258
-
259
- def test_has_many_build_simple_key
260
- user = users(:santiago)
261
- reading = user.readings.build
262
- assert_equal user.id, reading.user_id
263
- assert_equal user, reading.user
264
- end
265
-
266
- def test_has_many_build__composite_key
267
- department = departments(:engineering)
268
- employee = department.employees.build
269
- assert_equal department.department_id, employee.department_id
270
- assert_equal department.location_id, employee.location_id
271
- assert_equal department, employee.department
272
- end
273
-
274
- def test_has_many_with_primary_key
275
- @membership = Membership.find([1, 1])
276
- assert_equal 2, @membership.readings.size
277
- end
278
-
279
- def test_has_many_with_composite_key
280
- # In this case a regular model (Dorm) has_many composite models (Rooms)
281
- dorm = dorms(:branner)
282
- assert_equal(3, dorm.rooms.length)
283
- assert_equal(1, dorm.rooms[0].room_id)
284
- assert_equal(2, dorm.rooms[1].room_id)
285
- assert_equal(3, dorm.rooms[2].room_id)
286
- end
287
-
288
- def test_has_many_with_foreign_composite_key
289
- tariff = Tariff.find_by('tariff_id = ?', 2)
290
- assert_equal(2, tariff.product_tariffs.length)
291
- end
292
-
293
- def test_joins_has_many_with_primary_key
294
- #@membership = Membership.find(:first, :joins => :readings, :conditions => { :readings => { :id => 1 } })
295
- @membership = Membership.joins(:readings).where(readings: { id: 1 }).first
296
-
297
- assert_equal [1, 1], @membership.id
298
- end
299
-
300
- def test_joins_has_one_with_primary_key
301
- @membership = Membership.joins(:readings).where(readings: { id: 2 }).first
302
-
303
- assert_equal [1, 1], @membership.id
304
- end
305
-
306
- def test_has_many_through_with_conditions_when_through_association_is_not_composite
307
- user = User.first
308
- assert_equal 1, user.articles.where("articles.name = ?", "Article One").size
309
- end
310
-
311
- def test_has_many_through_with_conditions_when_through_association_is_composite
312
- room = Room.first
313
- assert_equal 0, room.room_attributes.where("room_attributes.name != ?", "type").size
314
- end
315
-
316
- def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
317
- user = User.first
318
- assert_equal(1, user.find_custom_articles.size)
319
- end
320
-
321
- def test_has_many_through_on_custom_finder_when_through_association_is_composite
322
- room = Room.first
323
- assert_equal(0, room.find_custom_room_attributes.size)
324
- end
325
-
326
- def test_has_many_with_primary_key_with_associations
327
- memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
328
- assert_equal(2, memberships.length)
329
- assert_equal([1,1], memberships[0].id)
330
- assert_equal([3,2], memberships[1].id)
331
- end
332
-
333
- def test_limitable_reflections
334
- memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses).limit(1)
335
- assert_equal(1, memberships.length)
336
- assert_equal([1,1], memberships[0].id)
337
- end
338
-
339
- def test_foreign_key_present_with_null_association_ids
340
- group = Group.new
341
- group.memberships.build
342
- associations = group.association(:memberships)
343
- assert_equal(false, associations.send('foreign_key_present?'))
344
- end
345
-
346
- def test_ids_equals_for_non_CPK_case
347
- article = Article.new
348
- article.reading_ids = Reading.pluck(:id)
349
- assert_equal article.reading_ids, Reading.pluck(:id)
350
- end
351
- 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_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
128
+ engineering = departments(:engineering)
129
+ engineering_employees = engineering.employees
130
+
131
+ accounting = departments(:accounting)
132
+ accounting_employees = accounting.employees
133
+
134
+ refute_equal accounting_employees, engineering_employees
135
+ end
136
+
137
+ def test_has_many_association_primary_key_and_foreign_key_are_present
138
+ department = departments(:accounting)
139
+ assert_equal(2, department.employees.count)
140
+ assert_equal('Steve', department.employees[0].name)
141
+ assert_equal('Jill', department.employees[1].name)
142
+
143
+ department.employees.create(name: 'Rick')
144
+
145
+ department.reload
146
+ assert_equal(3, department.employees.count)
147
+ employees = department.employees.sort_by(&:name)
148
+ assert_equal('Jill', employees[0].name)
149
+ assert_equal('Rick', employees[1].name)
150
+ assert_equal('Steve', employees[2].name)
151
+ end
152
+
153
+ def test_find_includes_product_tariffs_product
154
+ # Old style
155
+ product_tariffs = ProductTariff.includes(:product)
156
+ assert_not_nil(product_tariffs)
157
+ assert_equal(3, product_tariffs.length)
158
+
159
+ # New style
160
+ product_tariffs = ProductTariff.includes(:product)
161
+ assert_not_nil(product_tariffs)
162
+ assert_equal(3, product_tariffs.length)
163
+ end
164
+
165
+ def test_find_includes_product_tariffs_tariff
166
+ # Old style
167
+ product_tariffs = ProductTariff.includes(:tariff)
168
+ assert_equal(3, product_tariffs.length)
169
+
170
+ # New style
171
+ product_tariffs = ProductTariff.includes(:tariff)
172
+ assert_equal(3, product_tariffs.length)
173
+ end
174
+
175
+ def test_has_many_through
176
+ products = Product.includes(:tariffs)
177
+ assert_equal(3, products.length)
178
+
179
+ tarrifs_length = products.inject(0) {|sum, product| sum + product.tariffs.length}
180
+ assert_equal(3, tarrifs_length)
181
+ end
182
+
183
+ def test_has_many_through_2
184
+ assert_equal(3, Article.count)
185
+ user = users(:santiago)
186
+ article_names = user.articles.map(&:name).sort
187
+ assert_equal(['Article One', 'Article Two'], article_names)
188
+ end
189
+
190
+ def test_new_style_includes_with_conditions
191
+ product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
192
+ assert_equal(0, product_tariff.tariff.amount)
193
+ end
194
+
195
+ def test_find_product_includes
196
+ products = Product.includes(:product_tariffs => :tariff)
197
+ assert_equal(3, products.length)
198
+
199
+ product_tariffs_length = products.inject(0) {|sum, product| sum + product.product_tariffs.length}
200
+ assert_equal(3, product_tariffs_length)
201
+ end
202
+
203
+ def test_has_many_through_when_not_pre_loaded
204
+ student = Student.first
205
+ rooms = student.rooms
206
+ assert_equal(1, rooms.size)
207
+ assert_equal(1, rooms.first.dorm_id)
208
+ assert_equal(1, rooms.first.room_id)
209
+ end
210
+
211
+ def test_has_many_through_when_through_association_is_composite
212
+ dorm = Dorm.first
213
+ assert_equal(3, dorm.rooms.length)
214
+ assert_equal(1, dorm.rooms.first.room_attributes.length)
215
+ assert_equal('type', dorm.rooms.first.room_attributes.first.name)
216
+ end
217
+
218
+ def test_associations_with_conditions
219
+ suburb = Suburb.find([2, 2])
220
+ assert_equal 2, suburb.streets.size
221
+ assert_equal 1, suburb.first_streets.size
222
+ end
223
+
224
+ def test_composite_has_many_composites
225
+ room = rooms(:branner_room_1)
226
+ assert_equal(2, room.room_assignments.length)
227
+ assert_equal(room_assignments(:jacksons_room), room.room_assignments[0])
228
+ assert_equal(room_assignments(:bobs_room), room.room_assignments[1])
229
+ end
230
+
231
+ def test_composite_belongs_to_composite
232
+ room_assignment = room_assignments(:jacksons_room)
233
+ assert_equal(rooms(:branner_room_1), room_assignment.room)
234
+ end
235
+
236
+ def test_composite_belongs_to_changes
237
+ room_assignment = room_assignments(:jacksons_room)
238
+ room_assignment.room = rooms(:branner_room_2)
239
+ # This was raising an error before:
240
+ # TypeError: [:dorm_id, :room_id] is not a symbol
241
+ # changes returns HashWithIndifferentAccess
242
+ assert_equal({"room_id"=>[1, 2]}, room_assignment.changes)
243
+
244
+ steve = employees(:steve)
245
+ steve.department = departments(:engineering)
246
+ # It was returning this before:
247
+ # {"[:id, :location_id]"=>[nil, [2, 1]]}
248
+ assert_equal({"department_id"=>[1, 2]}, steve.changes)
249
+ end
250
+
251
+ def test_composite_belongs_to_setting_to_nil
252
+ room_assignment = room_assignments(:jacksons_room)
253
+ # This was raising an error before:
254
+ # NoMethodError: undefined method `length' for nil:NilClass
255
+ assert_nothing_raised { room_assignment.room = nil }
256
+ end
257
+
258
+ def test_has_one_with_composite
259
+ # In this case a regular model has_one composite model
260
+ department = departments(:engineering)
261
+ assert_not_nil(department.head)
262
+ end
263
+
264
+ def test_has_many_build_simple_key
265
+ user = users(:santiago)
266
+ reading = user.readings.build
267
+ assert_equal user.id, reading.user_id
268
+ assert_equal user, reading.user
269
+ end
270
+
271
+ def test_has_many_build_composite_key
272
+ department = departments(:engineering)
273
+ employee = department.employees.build
274
+ assert_equal(department[:id], employee.department_id)
275
+ assert_equal(department.location_id, employee.location_id)
276
+ assert_equal(department, employee.department)
277
+ end
278
+
279
+ def test_has_many_with_primary_key
280
+ @membership = Membership.find([1, 1])
281
+ assert_equal 2, @membership.readings.size
282
+ end
283
+
284
+ def test_has_many_with_composite_key
285
+ # In this case a regular model (Dorm) has_many composite models (Rooms)
286
+ dorm = dorms(:branner)
287
+ assert_equal(3, dorm.rooms.length)
288
+ assert_equal(1, dorm.rooms[0].room_id)
289
+ assert_equal(2, dorm.rooms[1].room_id)
290
+ assert_equal(3, dorm.rooms[2].room_id)
291
+ end
292
+
293
+ def test_has_many_with_foreign_composite_key
294
+ tariff = Tariff.find_by('tariff_id = ?', 2)
295
+ assert_equal(2, tariff.product_tariffs.length)
296
+ end
297
+
298
+ def test_joins_has_many_with_primary_key
299
+ #@membership = Membership.find(:first, :joins => :readings, :conditions => { :readings => { :id => 1 } })
300
+ @membership = Membership.joins(:readings).where(readings: { id: 1 }).first
301
+
302
+ assert_equal [1, 1], @membership.id
303
+ end
304
+
305
+ def test_joins_has_one_with_primary_key
306
+ @membership = Membership.joins(:readings).where(readings: { id: 2 }).first
307
+
308
+ assert_equal [1, 1], @membership.id
309
+ end
310
+
311
+ def test_has_many_through_with_conditions_when_through_association_is_not_composite
312
+ user = User.first
313
+ assert_equal 1, user.articles.where("articles.name = ?", "Article One").size
314
+ end
315
+
316
+ def test_has_many_through_with_conditions_when_through_association_is_composite
317
+ room = Room.first
318
+ assert_equal 0, room.room_attributes.where("room_attributes.name != ?", "type").size
319
+ end
320
+
321
+ def test_has_many_through_on_custom_finder_when_through_association_is_composite_finder_when_through_association_is_not_composite
322
+ user = User.first
323
+ assert_equal(1, user.find_custom_articles.size)
324
+ end
325
+
326
+ def test_has_many_through_on_custom_finder_when_through_association_is_composite
327
+ room = Room.first
328
+ assert_equal(0, room.find_custom_room_attributes.size)
329
+ end
330
+
331
+ def test_has_many_with_primary_key_with_associations
332
+ memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
333
+ assert_equal(2, memberships.length)
334
+ assert_equal([1,1], memberships[0].id)
335
+ assert_equal([3,2], memberships[1].id)
336
+ end
337
+
338
+ def test_limitable_reflections
339
+ memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
340
+ assert_equal(2, memberships.length)
341
+
342
+ assert_equal([1,1], memberships[0].id)
343
+ assert_equal([3,2], memberships[1].id)
344
+ end
345
+
346
+ def test_foreign_key_present_with_null_association_ids
347
+ group = Group.new
348
+ group.memberships.build
349
+ associations = group.association(:memberships)
350
+ assert_equal(false, associations.send('foreign_key_present?'))
351
+ end
352
+
353
+ def test_ids_equals_for_non_CPK_case
354
+ article = Article.new
355
+ article.reading_ids = Reading.pluck(:id)
356
+ assert_equal article.reading_ids, Reading.pluck(:id)
357
+ end
358
+ end