composite_primary_keys 8.1.0 → 8.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +642 -625
  3. data/README.rdoc +5 -2
  4. data/lib/composite_primary_keys.rb +115 -115
  5. data/lib/composite_primary_keys/associations/association.rb +23 -23
  6. data/lib/composite_primary_keys/associations/association_scope.rb +73 -73
  7. data/lib/composite_primary_keys/associations/collection_association.rb +14 -14
  8. data/lib/composite_primary_keys/associations/has_many_association.rb +69 -69
  9. data/lib/composite_primary_keys/associations/join_dependency.rb +87 -87
  10. data/lib/composite_primary_keys/associations/preloader/association.rb +90 -90
  11. data/lib/composite_primary_keys/associations/singular_association.rb +18 -18
  12. data/lib/composite_primary_keys/attribute_methods.rb +9 -9
  13. data/lib/composite_primary_keys/attribute_methods/dirty.rb +29 -29
  14. data/lib/composite_primary_keys/attribute_methods/read.rb +24 -24
  15. data/lib/composite_primary_keys/attribute_methods/write.rb +30 -30
  16. data/lib/composite_primary_keys/attribute_set/builder.rb +19 -19
  17. data/lib/composite_primary_keys/base.rb +129 -135
  18. data/lib/composite_primary_keys/composite_arrays.rb +43 -43
  19. data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +2 -3
  20. data/lib/composite_primary_keys/core.rb +60 -60
  21. data/lib/composite_primary_keys/persistence.rb +56 -56
  22. data/lib/composite_primary_keys/relation.rb +68 -68
  23. data/lib/composite_primary_keys/relation/calculations.rb +78 -78
  24. data/lib/composite_primary_keys/relation/finder_methods.rb +179 -179
  25. data/lib/composite_primary_keys/sanitization.rb +52 -52
  26. data/lib/composite_primary_keys/validations/uniqueness.rb +36 -36
  27. data/lib/composite_primary_keys/version.rb +8 -8
  28. data/tasks/databases/sqlserver.rake +27 -27
  29. data/test/abstract_unit.rb +114 -113
  30. data/test/connections/databases.example.yml +25 -25
  31. data/test/connections/native_sqlserver/connection.rb +11 -11
  32. data/test/fixtures/db_definitions/mysql.sql +218 -218
  33. data/test/fixtures/db_definitions/postgresql.sql +220 -220
  34. data/test/fixtures/db_definitions/sqlite.sql +206 -206
  35. data/test/fixtures/db_definitions/sqlserver.drop.sql +91 -91
  36. data/test/fixtures/db_definitions/sqlserver.sql +226 -226
  37. data/test/fixtures/employee.rb +11 -11
  38. data/test/fixtures/salary.rb +5 -5
  39. data/test/test_associations.rb +341 -340
  40. data/test/test_attributes.rb +60 -60
  41. data/test/test_create.rb +157 -157
  42. data/test/test_delete.rb +158 -158
  43. data/test/test_delete_all.rb +33 -28
  44. data/test/test_enum.rb +21 -21
  45. data/test/test_equal.rb +26 -26
  46. data/test/test_find.rb +119 -118
  47. data/test/test_habtm.rb +117 -113
  48. data/test/test_polymorphic.rb +27 -26
  49. data/test/test_tutorial_example.rb +25 -25
  50. metadata +44 -2
@@ -1,28 +1,33 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class EmployeesGroup < ActiveRecord::Base
4
-
5
- end
6
-
7
- class TestValidations < ActiveSupport::TestCase
8
- fixtures :employees
9
-
10
- def test_delete_for_model_without_primary_key
11
- EmployeesGroup.create(employee_id: 1, group_id: 100)
12
- EmployeesGroup.create(employee_id: 2, group_id: 102)
13
- EmployeesGroup.create(employee_id: 3, group_id: 103)
14
-
15
- assert_equal(EmployeesGroup.all.size, 3)
16
- exception = assert_raises(ActiveRecord::StatementInvalid) {
17
- EmployeesGroup.where(employee_id: 1).first.destroy
18
- }
19
-
20
- mysql_match = /Unknown column 'employees_groups.' in 'where clause/ =~ exception.message
21
- sqlite3_match = /no such column: employees_groups./ =~ exception.message
22
- postgresql_match = /PG::SyntaxError: ERROR: zero-length delimited identifier/ =~ exception.message
23
-
24
- assert(postgresql_match || mysql_match || sqlite3_match)
25
-
26
- assert(EmployeesGroup.all.size == 3)
27
- end
28
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class EmployeesGroup < ActiveRecord::Base
4
+
5
+ end
6
+
7
+ class TestValidations < ActiveSupport::TestCase
8
+ fixtures :employees
9
+
10
+ def test_delete_for_model_without_primary_key
11
+ EmployeesGroup.create(employee_id: 1, group_id: 100)
12
+ EmployeesGroup.create(employee_id: 2, group_id: 102)
13
+ EmployeesGroup.create(employee_id: 3, group_id: 103)
14
+
15
+ assert_equal(EmployeesGroup.all.size, 3)
16
+ exception = assert_raises(ActiveRecord::StatementInvalid) {
17
+ EmployeesGroup.where(employee_id: 1).first.destroy
18
+ }
19
+
20
+ mysql_match = /Unknown column 'employees_groups.' in 'where clause/ =~ exception.message
21
+ sqlite3_match = /no such column: employees_groups./ =~ exception.message
22
+ postgresql_match = /PG::SyntaxError: ERROR: zero-length delimited identifier/ =~ exception.message
23
+
24
+ assert(postgresql_match || mysql_match || sqlite3_match)
25
+
26
+ assert(EmployeesGroup.all.size == 3)
27
+ end
28
+
29
+ # This test fails, requires fixin arel
30
+ #def test_delete_all_with_joins
31
+ # ReferenceCode.joins(:reference_type).where(:reference_type_id => 1).delete_all
32
+ #end
33
+ end
@@ -1,21 +1,21 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestEnum < ActiveSupport::TestCase
4
- fixtures :comments
5
-
6
- def test_enum_was
7
- comment = Comment.first
8
- assert_nil comment.shown
9
- puts "comment.changed_attributes = #{comment.changed_attributes.inspect}"
10
- comment.shown = :true
11
- puts "comment.changed_attributes = #{comment.changed_attributes.inspect}"
12
- assert_equal 'true', comment.shown
13
- assert_nil comment.shown_was
14
-
15
- comment.save
16
-
17
- comment.shown = :false
18
- assert_equal 'false', comment.shown
19
- assert_equal 'true', comment.shown_was
20
- end
21
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestEnum < ActiveSupport::TestCase
4
+ fixtures :comments
5
+
6
+ def test_enum_was
7
+ comment = Comment.first
8
+ assert_nil comment.shown
9
+ assert_equal({}, comment.changed_attributes)
10
+ comment.shown = :true
11
+ assert_equal({ "shown" => nil }, comment.changed_attributes)
12
+ assert_equal 'true', comment.shown
13
+ assert_nil comment.shown_was
14
+
15
+ comment.save
16
+
17
+ comment.shown = :false
18
+ assert_equal 'false', comment.shown
19
+ assert_equal 'true', comment.shown_was
20
+ end
21
+ end
@@ -1,26 +1,26 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestEqual < ActiveSupport::TestCase
4
- fixtures :capitols
5
-
6
- def test_new
7
- assert_not_equal(Capitol.new, Capitol.new)
8
- end
9
-
10
- def test_same_new
11
- it = Capitol.new
12
- assert_equal(it, it)
13
- end
14
-
15
- def test_same
16
- first = Capitol.find(['Canada', 'Ottawa'])
17
- second = Capitol.find(['Canada', 'Ottawa'])
18
- assert_equal(first, second)
19
- end
20
-
21
- def test_different
22
- first = Capitol.find(['Mexico', 'Mexico City'])
23
- second = Capitol.find(['Canada', 'Ottawa'])
24
- assert_not_equal(first, second)
25
- end
26
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestEqual < ActiveSupport::TestCase
4
+ fixtures :capitols
5
+
6
+ def test_new
7
+ assert_equal(Capitol.new, Capitol.new)
8
+ end
9
+
10
+ def test_same_new
11
+ it = Capitol.new
12
+ assert_equal(it, it)
13
+ end
14
+
15
+ def test_same
16
+ first = Capitol.find(['Canada', 'Ottawa'])
17
+ second = Capitol.find(['Canada', 'Ottawa'])
18
+ assert_equal(first, second)
19
+ end
20
+
21
+ def test_different
22
+ first = Capitol.find(['Mexico', 'Mexico City'])
23
+ second = Capitol.find(['Canada', 'Ottawa'])
24
+ assert_not_equal(first, second)
25
+ end
26
+ end
@@ -1,118 +1,119 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- # Testing the find action on composite ActiveRecords with two primary keys
4
- class TestFind < ActiveSupport::TestCase
5
- fixtures :capitols, :departments, :reference_types, :reference_codes, :suburbs
6
-
7
- def test_find_first
8
- ref_code = ReferenceCode.order('reference_type_id, reference_code').first
9
- assert_kind_of(ReferenceCode, ref_code)
10
- assert_equal([1,1], ref_code.id)
11
- end
12
-
13
- def test_find_last
14
- ref_code = ReferenceCode.order('reference_type_id, reference_code').last
15
- assert_kind_of(ReferenceCode, ref_code)
16
- assert_equal([2,2], ref_code.id)
17
- end
18
-
19
- def test_find_one
20
- ref_code = ReferenceCode.find([1,3])
21
- assert_not_nil(ref_code)
22
- assert_equal([1,3], ref_code.id)
23
- end
24
-
25
- def test_find_some
26
- ref_codes = ReferenceCode.find([1,3], [2,1])
27
- assert_kind_of(Array, ref_codes)
28
- assert_equal(2, ref_codes.length)
29
-
30
- ref_code = ref_codes[0]
31
- assert_equal([1,3], ref_code.id)
32
-
33
- ref_code = ref_codes[1]
34
- assert_equal([2,1], ref_code.id)
35
- end
36
-
37
- def test_find_with_strings_as_composite_keys
38
- capitol = Capitol.find(['The Netherlands', 'Amsterdam'])
39
- assert_kind_of(Capitol, capitol)
40
- assert_equal(['The Netherlands', 'Amsterdam'], capitol.id)
41
- end
42
-
43
- def test_find_each
44
- room_assignments = []
45
- RoomAssignment.find_each(:batch_size => 2) do |assignment|
46
- room_assignments << assignment
47
- end
48
-
49
- assert_equal(RoomAssignment.count, room_assignments.uniq.length)
50
- end
51
-
52
- def test_find_each_with_scope
53
- scoped_departments = Department.where("department_id <> 3")
54
- scoped_departments.find_each(:batch_size => 2) do |department|
55
- assert department.id != 3
56
- end
57
- end
58
-
59
- def test_not_found
60
- error = assert_raise(::ActiveRecord::RecordNotFound) do
61
- ReferenceCode.find(['999', '999'])
62
- end
63
-
64
- connection = ActiveRecord::Base.connection
65
- ref_type_quoted = "#{connection.quote_table_name('reference_codes')}.#{connection.quote_column_name('reference_type_id')}"
66
- ref_code_quoted = "#{connection.quote_table_name('reference_codes')}.#{connection.quote_column_name('reference_code')}"
67
-
68
- expected = "Couldn't find all ReferenceCodes with 'reference_type_id,reference_code': (999, 999) (found 0 results, but was looking for 1)"
69
- assert_equal(with_quoted_identifiers(expected), error.message)
70
- end
71
-
72
- def test_find_last_suburb
73
- suburb = Suburb.last
74
- assert_equal([2,1], suburb.id)
75
- end
76
-
77
- def test_find_last_suburb_with_order
78
- # Rails actually changes city_id DESC to city_id ASC
79
- suburb = Suburb.order('suburbs.city_id DESC').last
80
- assert_equal([1,1], suburb.id)
81
- end
82
-
83
- def test_find_in_batches
84
- Department.find_in_batches do |batch|
85
- assert_equal(Department.count, batch.size)
86
- end
87
- end
88
-
89
- def test_expand
90
- department = departments(:engineering)
91
- employees = Employee.where(:department => department)
92
- assert_equal(2, employees.count)
93
- end
94
-
95
- def test_find_one_with_params_id
96
- params_id = ReferenceCode.find([1,3]).to_param
97
- assert_equal params_id, "1,3"
98
-
99
- ref_code = ReferenceCode.find(params_id)
100
- assert_not_nil(ref_code)
101
- assert_equal([1,3], ref_code.id)
102
- end
103
-
104
- def test_find_some_with_array_of_params_id
105
- params_ids = ReferenceCode.find([1,3], [2,1]).map(&:to_param)
106
- assert_equal ["1,3", "2,1"], params_ids
107
-
108
- ref_codes = ReferenceCode.find(params_ids)
109
- assert_kind_of(Array, ref_codes)
110
- assert_equal(2, ref_codes.length)
111
-
112
- ref_code = ref_codes[0]
113
- assert_equal([1,3], ref_code.id)
114
-
115
- ref_code = ref_codes[1]
116
- assert_equal([2,1], ref_code.id)
117
- end
118
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ # Testing the find action on composite ActiveRecords with two primary keys
4
+ class TestFind < ActiveSupport::TestCase
5
+ fixtures :capitols, :departments, :reference_types, :reference_codes,
6
+ :suburbs, :employees
7
+
8
+ def test_find_first
9
+ ref_code = ReferenceCode.order('reference_type_id, reference_code').first
10
+ assert_kind_of(ReferenceCode, ref_code)
11
+ assert_equal([1,1], ref_code.id)
12
+ end
13
+
14
+ def test_find_last
15
+ ref_code = ReferenceCode.order('reference_type_id, reference_code').last
16
+ assert_kind_of(ReferenceCode, ref_code)
17
+ assert_equal([2,2], ref_code.id)
18
+ end
19
+
20
+ def test_find_one
21
+ ref_code = ReferenceCode.find([1,3])
22
+ assert_not_nil(ref_code)
23
+ assert_equal([1,3], ref_code.id)
24
+ end
25
+
26
+ def test_find_some
27
+ ref_codes = ReferenceCode.find([1,3], [2,1])
28
+ assert_kind_of(Array, ref_codes)
29
+ assert_equal(2, ref_codes.length)
30
+
31
+ ref_code = ref_codes[0]
32
+ assert_equal([1,3], ref_code.id)
33
+
34
+ ref_code = ref_codes[1]
35
+ assert_equal([2,1], ref_code.id)
36
+ end
37
+
38
+ def test_find_with_strings_as_composite_keys
39
+ capitol = Capitol.find(['The Netherlands', 'Amsterdam'])
40
+ assert_kind_of(Capitol, capitol)
41
+ assert_equal(['The Netherlands', 'Amsterdam'], capitol.id)
42
+ end
43
+
44
+ def test_find_each
45
+ room_assignments = []
46
+ RoomAssignment.find_each(:batch_size => 2) do |assignment|
47
+ room_assignments << assignment
48
+ end
49
+
50
+ assert_equal(RoomAssignment.count, room_assignments.uniq.length)
51
+ end
52
+
53
+ def test_find_each_with_scope
54
+ scoped_departments = Department.where("department_id <> 3")
55
+ scoped_departments.find_each(:batch_size => 2) do |department|
56
+ assert department.id != 3
57
+ end
58
+ end
59
+
60
+ def test_not_found
61
+ error = assert_raise(::ActiveRecord::RecordNotFound) do
62
+ ReferenceCode.find(['999', '999'])
63
+ end
64
+
65
+ connection = ActiveRecord::Base.connection
66
+ ref_type_quoted = "#{connection.quote_table_name('reference_codes')}.#{connection.quote_column_name('reference_type_id')}"
67
+ ref_code_quoted = "#{connection.quote_table_name('reference_codes')}.#{connection.quote_column_name('reference_code')}"
68
+
69
+ expected = "Couldn't find all ReferenceCodes with 'reference_type_id,reference_code': (999, 999) (found 0 results, but was looking for 1)"
70
+ assert_equal(with_quoted_identifiers(expected), error.message)
71
+ end
72
+
73
+ def test_find_last_suburb
74
+ suburb = Suburb.last
75
+ assert_equal([2,1], suburb.id)
76
+ end
77
+
78
+ def test_find_last_suburb_with_order
79
+ # Rails actually changes city_id DESC to city_id ASC
80
+ suburb = Suburb.order('suburbs.city_id DESC').last
81
+ assert_equal([1,1], suburb.id)
82
+ end
83
+
84
+ def test_find_in_batches
85
+ Department.find_in_batches do |batch|
86
+ assert_equal(Department.count, batch.size)
87
+ end
88
+ end
89
+
90
+ def test_expand
91
+ department = departments(:engineering)
92
+ employees = Employee.where(:department => department)
93
+ assert_equal(2, employees.count)
94
+ end
95
+
96
+ def test_find_one_with_params_id
97
+ params_id = ReferenceCode.find([1,3]).to_param
98
+ assert_equal params_id, "1,3"
99
+
100
+ ref_code = ReferenceCode.find(params_id)
101
+ assert_not_nil(ref_code)
102
+ assert_equal([1,3], ref_code.id)
103
+ end
104
+
105
+ def test_find_some_with_array_of_params_id
106
+ params_ids = ReferenceCode.find([1,3], [2,1]).map(&:to_param)
107
+ assert_equal ["1,3", "2,1"], params_ids
108
+
109
+ ref_codes = ReferenceCode.find(params_ids)
110
+ assert_kind_of(Array, ref_codes)
111
+ assert_equal(2, ref_codes.length)
112
+
113
+ ref_code = ref_codes[0]
114
+ assert_equal([1,3], ref_code.id)
115
+
116
+ ref_code = ref_codes[1]
117
+ assert_equal([2,1], ref_code.id)
118
+ end
119
+ end
@@ -1,113 +1,117 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestHabtm < ActiveSupport::TestCase
4
- fixtures :suburbs, :restaurants, :restaurants_suburbs, :products
5
-
6
- def test_has_and_belongs_to_many
7
- @restaurant = Restaurant.find([1,1])
8
- assert_equal 2, @restaurant.suburbs.size
9
-
10
- @restaurant = Restaurant.includes(:suburbs).find([1,1])
11
- assert_equal 2, @restaurant.suburbs.size
12
- end
13
-
14
- def test_include_cpk_both_sides
15
- # assuming the association was set up in the fixtures
16
- # file restaurants_suburbs.yml
17
- mcdonalds = restaurants(:mcdonalds)
18
- # check positive
19
- suburb = mcdonalds.suburbs[0]
20
- assert mcdonalds.suburbs.include?(suburb)
21
- # check negative
22
- suburb_with_no_mcdonalds = suburbs(:no_mcdonalds)
23
- assert !mcdonalds.suburbs.include?(suburb_with_no_mcdonalds)
24
- end
25
-
26
- def test_include_cpk_owner_side_only
27
- subway = restaurants(:subway_one)
28
- product = products(:first_product)
29
- subway.products << product
30
-
31
- # reload
32
- # test positive
33
- subway = restaurants(:subway_one)
34
- assert subway.products.include?(product)
35
-
36
- # test negative
37
- product_two = products(:second_product)
38
- assert !subway.products.include?(product_two)
39
- end
40
-
41
- def test_include_cpk_association_side_only
42
- product = products(:first_product)
43
- subway = restaurants(:subway_one)
44
- product.restaurants << subway
45
-
46
- # reload
47
- # test positive
48
- product = products(:first_product)
49
- assert product.restaurants.include?(subway)
50
-
51
- # test negative
52
- mcdonalds = restaurants(:mcdonalds)
53
- assert !product.restaurants.include?(mcdonalds)
54
- end
55
-
56
- def test_habtm_clear_cpk_both_sides
57
- @restaurant = restaurants(:mcdonalds)
58
- assert_equal 2, @restaurant.suburbs.size
59
- @restaurant.suburbs.clear
60
- assert_equal 0, @restaurant.suburbs.size
61
- end
62
-
63
- def test_habtm_clear_cpk_owner_side_only
64
- subway = restaurants(:subway_one)
65
- first_product = products(:first_product)
66
- second_product = products(:second_product)
67
- subway.products << first_product << second_product
68
- assert_equal 2, subway.products.size
69
- subway.products.clear
70
- # reload to force reload of associations
71
- subway = restaurants(:subway_one)
72
- assert_equal 0, subway.products.size
73
- end
74
-
75
- def test_habtm_clear_cpk_association_side_only
76
- product = products(:first_product)
77
- subway_one = restaurants(:subway_one)
78
- subway_two = restaurants(:subway_two)
79
- product.restaurants << subway_one << subway_two
80
- assert_equal 2, product.restaurants.size
81
- product.restaurants.clear
82
- # reload to force reload of associations
83
- product = products(:first_product)
84
- assert_equal 0, product.restaurants.size
85
- end
86
-
87
- # tests case reported in issue #39 where a bug resulted in
88
- # deletion of incorrect join table records because the owner's id
89
- # was assumed to be an array and is not in this case
90
- # and evaluates to a useable but incorrect value
91
- def test_habtm_clear_cpk_association_side_only_deletes_only_correct_records
92
- product_one = Product.find(1)
93
- product_three = Product.find(3)
94
- subway_one = restaurants(:subway_one)
95
- subway_two = restaurants(:subway_two)
96
- product_one.restaurants << subway_one << subway_two
97
- product_three.restaurants << subway_one << subway_two
98
- assert_equal 2, product_one.restaurants.size
99
- assert_equal 2, product_three.restaurants.size
100
-
101
- # if product_three's id is incorrectly assumed to be
102
- # an array it will be evaluated as 3[0], which is 1, which would
103
- # delete product_one's associations rather than product_three's
104
- product_three.restaurants.clear
105
-
106
- # reload to force reload of associations
107
- product_one = Product.find(1)
108
- assert_equal 2, product_one.restaurants.size
109
-
110
- product_three = Product.find(3)
111
- assert_equal 0, product_three.restaurants.size
112
- end
113
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestHabtm < ActiveSupport::TestCase
4
+ fixtures :suburbs, :restaurants, :restaurants_suburbs, :products
5
+
6
+ def test_has_and_belongs_to_many
7
+ @restaurant = Restaurant.find([1,1])
8
+ assert_equal 2, @restaurant.suburbs.size
9
+
10
+ @restaurant = Restaurant.includes(:suburbs).find([1,1])
11
+ assert_equal 2, @restaurant.suburbs.size
12
+ end
13
+
14
+ def test_include_cpk_both_sides
15
+ # assuming the association was set up in the fixtures
16
+ # file restaurants_suburbs.yml
17
+ mcdonalds = restaurants(:mcdonalds)
18
+ # check positive
19
+ suburb = mcdonalds.suburbs[0]
20
+ assert mcdonalds.suburbs.include?(suburb)
21
+ # check negative
22
+ suburb_with_no_mcdonalds = suburbs(:no_mcdonalds)
23
+ assert !mcdonalds.suburbs.include?(suburb_with_no_mcdonalds)
24
+ end
25
+
26
+ def test_include_cpk_owner_side_only
27
+ subway = restaurants(:subway_one)
28
+ product = products(:first_product)
29
+ subway.products << product
30
+
31
+ # reload
32
+ # test positive
33
+ subway = restaurants(:subway_one)
34
+ assert subway.products.include?(product)
35
+
36
+ # test negative
37
+ product_two = products(:second_product)
38
+ assert !subway.products.include?(product_two)
39
+ end
40
+
41
+ def test_include_cpk_association_side_only
42
+ product = products(:first_product)
43
+ subway = restaurants(:subway_one)
44
+ product.restaurants << subway
45
+
46
+ # reload
47
+ # test positive
48
+ product = products(:first_product)
49
+ assert product.restaurants.include?(subway)
50
+
51
+ # test negative
52
+ mcdonalds = restaurants(:mcdonalds)
53
+ assert !product.restaurants.include?(mcdonalds)
54
+ end
55
+
56
+ def test_habtm_clear_cpk_both_sides
57
+ @restaurant = restaurants(:mcdonalds)
58
+ assert_equal 2, @restaurant.suburbs.size
59
+ @restaurant.suburbs.clear
60
+ assert_equal 0, @restaurant.suburbs.size
61
+ end
62
+
63
+ def test_habtm_clear_cpk_owner_side_only
64
+ subway = restaurants(:subway_one)
65
+ assert_equal 0, subway.products.size, 'Baseline'
66
+
67
+ first_product = products(:first_product)
68
+ second_product = products(:second_product)
69
+ subway.products << first_product << second_product
70
+ assert_equal 2, subway.products.size
71
+ subway.products.clear
72
+ # reload to force reload of associations
73
+ subway = restaurants(:subway_one)
74
+ assert_equal 0, subway.products.size
75
+ end
76
+
77
+ def test_habtm_clear_cpk_association_side_only
78
+ product = products(:first_product)
79
+ assert_equal 0, product.restaurants.size, 'Baseline'
80
+
81
+ subway_one = restaurants(:subway_one)
82
+ subway_two = restaurants(:subway_two)
83
+ product.restaurants << subway_one << subway_two
84
+ assert_equal 2, product.restaurants.size
85
+ product.restaurants.clear
86
+ # reload to force reload of associations
87
+ product = products(:first_product)
88
+ assert_equal 0, product.restaurants.size
89
+ end
90
+
91
+ # tests case reported in issue #39 where a bug resulted in
92
+ # deletion of incorrect join table records because the owner's id
93
+ # was assumed to be an array and is not in this case
94
+ # and evaluates to a useable but incorrect value
95
+ def test_habtm_clear_cpk_association_side_only_deletes_only_correct_records
96
+ product_one = Product.find(1)
97
+ product_three = Product.find(3)
98
+ subway_one = restaurants(:subway_one)
99
+ subway_two = restaurants(:subway_two)
100
+ product_one.restaurants << subway_one << subway_two
101
+ product_three.restaurants << subway_one << subway_two
102
+ assert_equal 2, product_one.restaurants.size
103
+ assert_equal 2, product_three.restaurants.size
104
+
105
+ # if product_three's id is incorrectly assumed to be
106
+ # an array it will be evaluated as 3[0], which is 1, which would
107
+ # delete product_one's associations rather than product_three's
108
+ product_three.restaurants.clear
109
+
110
+ # reload to force reload of associations
111
+ product_one = Product.find(1)
112
+ assert_equal 2, product_one.restaurants.size
113
+
114
+ product_three = Product.find(3)
115
+ assert_equal 0, product_three.restaurants.size
116
+ end
117
+ end