composite_primary_keys 7.0.13 → 7.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +615 -608
  3. data/lib/composite_primary_keys.rb +110 -110
  4. data/lib/composite_primary_keys/associations/association.rb +23 -23
  5. data/lib/composite_primary_keys/associations/association_scope.rb +77 -77
  6. data/lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb +59 -59
  7. data/lib/composite_primary_keys/associations/has_many_association.rb +56 -56
  8. data/lib/composite_primary_keys/associations/join_dependency.rb +89 -89
  9. data/lib/composite_primary_keys/associations/join_dependency/join_part.rb +38 -38
  10. data/lib/composite_primary_keys/associations/preloader/association.rb +78 -78
  11. data/lib/composite_primary_keys/associations/preloader/has_and_belongs_to_many.rb +46 -46
  12. data/lib/composite_primary_keys/attribute_methods/dirty.rb +26 -26
  13. data/lib/composite_primary_keys/attribute_methods/read.rb +34 -34
  14. data/lib/composite_primary_keys/attribute_methods/write.rb +36 -36
  15. data/lib/composite_primary_keys/base.rb +0 -6
  16. data/lib/composite_primary_keys/composite_arrays.rb +30 -30
  17. data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +4 -2
  18. data/lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb +17 -0
  19. data/lib/composite_primary_keys/core.rb +47 -47
  20. data/lib/composite_primary_keys/persistence.rb +60 -60
  21. data/lib/composite_primary_keys/relation.rb +56 -56
  22. data/lib/composite_primary_keys/relation/calculations.rb +75 -65
  23. data/lib/composite_primary_keys/relation/finder_methods.rb +196 -196
  24. data/lib/composite_primary_keys/sanitization.rb +52 -52
  25. data/lib/composite_primary_keys/validations/uniqueness.rb +37 -39
  26. data/lib/composite_primary_keys/version.rb +8 -8
  27. data/tasks/databases/sqlserver.rake +40 -27
  28. data/test/connections/databases.example.yml +18 -18
  29. data/test/connections/native_sqlserver/connection.rb +14 -11
  30. data/test/fixtures/db_definitions/mysql.sql +208 -208
  31. data/test/fixtures/db_definitions/postgresql.sql +210 -210
  32. data/test/fixtures/db_definitions/sqlite.sql +197 -197
  33. data/test/fixtures/db_definitions/sqlserver.drop.sql +94 -91
  34. data/test/fixtures/db_definitions/sqlserver.sql +232 -226
  35. data/test/fixtures/employee.rb +5 -5
  36. data/test/test_associations.rb +275 -275
  37. data/test/test_attributes.rb +60 -60
  38. data/test/test_create.rb +112 -112
  39. data/test/test_delete.rb +152 -148
  40. data/test/test_delete_all.rb +21 -21
  41. data/test/test_enum.rb +20 -20
  42. data/test/test_equal.rb +1 -1
  43. data/test/test_tutorial_example.rb +21 -21
  44. metadata +3 -2
@@ -1,61 +1,61 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestAttributes < ActiveSupport::TestCase
4
- fixtures :reference_types, :reference_codes, :products, :tariffs, :product_tariffs
5
-
6
- CLASSES = {
7
- :single => {
8
- :class => ReferenceType,
9
- :primary_keys => :reference_type_id,
10
- },
11
- :dual => {
12
- :class => ReferenceCode,
13
- :primary_keys => [:reference_type_id, :reference_code],
14
- },
15
- }
16
-
17
- def setup
18
- self.class.classes = CLASSES
19
- end
20
-
21
- def test_brackets
22
- testing_with do
23
- @first.attributes.each_pair do |attr_name, value|
24
- assert_equal value, @first[attr_name]
25
- end
26
- end
27
- end
28
-
29
- def test_brackets_primary_key
30
- testing_with do
31
- assert_equal(@first.id, @first[@primary_keys])
32
- assert_equal(@first.id, @first[@first.class.primary_key])
33
- end
34
- end
35
-
36
- def test_brackets_assignment
37
- testing_with do
38
- @first.attributes.each_pair do |attr_name, value|
39
- next if attr_name == @first.class.primary_key
40
- @first[attr_name]= !value.nil? ? value * 2 : '1'
41
- assert_equal !value.nil? ? value * 2 : '1', @first[attr_name]
42
- end
43
- end
44
- end
45
-
46
- def test_brackets_foreign_key_assignment
47
- tarrif = tariffs(:flat)
48
- product_tariff = product_tariffs(:first_flat)
49
- compare_indexes(tarrif, tarrif.class.primary_key, product_tariff, [:tariff_id, :tariff_start_date])
50
- end
51
-
52
- private
53
-
54
- def compare_indexes(obj1, indexes1, obj2, indexes2)
55
- indexes1.length.times do |key_index|
56
- key1 = indexes1[key_index]
57
- key2 = indexes2[key_index]
58
- assert_equal(obj1[key1], obj2[key2])
59
- end
60
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestAttributes < ActiveSupport::TestCase
4
+ fixtures :reference_types, :reference_codes, :products, :tariffs, :product_tariffs
5
+
6
+ CLASSES = {
7
+ :single => {
8
+ :class => ReferenceType,
9
+ :primary_keys => :reference_type_id,
10
+ },
11
+ :dual => {
12
+ :class => ReferenceCode,
13
+ :primary_keys => [:reference_type_id, :reference_code],
14
+ },
15
+ }
16
+
17
+ def setup
18
+ self.class.classes = CLASSES
19
+ end
20
+
21
+ def test_brackets
22
+ testing_with do
23
+ @first.attributes.each_pair do |attr_name, value|
24
+ assert_equal value, @first[attr_name]
25
+ end
26
+ end
27
+ end
28
+
29
+ def test_brackets_primary_key
30
+ testing_with do
31
+ assert_equal(@first.id, @first[@primary_keys])
32
+ assert_equal(@first.id, @first[@first.class.primary_key])
33
+ end
34
+ end
35
+
36
+ def test_brackets_assignment
37
+ testing_with do
38
+ @first.attributes.each_pair do |attr_name, value|
39
+ next if attr_name == @first.class.primary_key
40
+ @first[attr_name]= !value.nil? ? value * 2 : '1'
41
+ assert_equal !value.nil? ? value * 2 : '1', @first[attr_name]
42
+ end
43
+ end
44
+ end
45
+
46
+ def test_brackets_foreign_key_assignment
47
+ tarrif = tariffs(:flat)
48
+ product_tariff = product_tariffs(:first_flat)
49
+ compare_indexes(tarrif, tarrif.class.primary_key, product_tariff, [:tariff_id, :tariff_start_date])
50
+ end
51
+
52
+ private
53
+
54
+ def compare_indexes(obj1, indexes1, obj2, indexes2)
55
+ indexes1.length.times do |key_index|
56
+ key1 = indexes1[key_index]
57
+ key2 = indexes2[key_index]
58
+ assert_equal(obj1[key1], obj2[key2])
59
+ end
60
+ end
61
61
  end
@@ -1,112 +1,112 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestCreate < ActiveSupport::TestCase
4
- fixtures :reference_types, :reference_codes, :streets, :suburbs
5
-
6
- CLASSES = {
7
- :single => {
8
- :class => ReferenceType,
9
- :primary_keys => :reference_type_id,
10
- :create => {:reference_type_id => 10, :type_label => 'NEW_TYPE', :abbreviation => 'New Type'}
11
- },
12
- :dual => {
13
- :class => ReferenceCode,
14
- :primary_keys => [:reference_type_id, :reference_code],
15
- :create => {:reference_type_id => 1, :reference_code => 20, :code_label => 'NEW_CODE', :abbreviation => 'New Code'}
16
- }
17
- }
18
-
19
- def setup
20
- self.class.classes = CLASSES
21
- end
22
-
23
- def test_setup
24
- testing_with do
25
- assert_not_nil @klass_info[:create]
26
- end
27
- end
28
-
29
- def test_create
30
- testing_with do
31
- assert new_obj = @klass.create(@klass_info[:create])
32
- assert !new_obj.new_record?
33
- assert new_obj.id
34
- end
35
- end
36
-
37
- def test_create_no_id
38
- testing_with do
39
- begin
40
- @obj = @klass.create(@klass_info[:create].except(@klass.primary_key))
41
- @successful = !composite?
42
- rescue ActiveRecord::CompositeKeyError
43
- @successful = false
44
- rescue
45
- flunk "Incorrect exception raised: #{$!}, #{$!.class}"
46
- end
47
- assert_equal composite?, !@successful, "Create should have failed for composites; #{@obj.inspect}"
48
- end
49
- end
50
-
51
- def test_create_on_association
52
- suburb = Suburb.first
53
- suburb.streets.create(:name => "my street")
54
- street = Street.find_by_name('my street')
55
- assert_equal(suburb.city_id, street.city_id)
56
- assert_equal(suburb.suburb_id, street.suburb_id)
57
- end
58
-
59
- def test_create_on_association_when_belongs_to_is_single_key
60
- rt = ReferenceType.first
61
- rt.reference_codes.create(:reference_code => 4321, :code_label => 'foo', :abbreviation => 'bar')
62
- rc = ReferenceCode.find_by_reference_code(4321)
63
- assert_equal(rc.reference_type_id, rt.reference_type_id)
64
- end
65
-
66
- def test_new_habtm
67
- restaurant = Restaurant.new(:franchise_id => 101,
68
- :store_id => 201,
69
- :name => "My Store")
70
-
71
- restaurant.suburbs << Suburb.new(:city_id => 24,
72
- :suburb_id => 25,
73
- :name => "My Suburb")
74
-
75
- restaurant.save!
76
-
77
- # Test restaurant
78
- assert_equal(101, restaurant.franchise_id)
79
- assert_equal(201, restaurant.store_id)
80
- assert_equal("My Store", restaurant.name)
81
- assert_equal(1, restaurant.suburbs.length)
82
-
83
- # Test suburbs
84
- suburb = restaurant.suburbs[0]
85
- assert_equal(24, suburb.city_id)
86
- assert_equal(25, suburb.suburb_id)
87
- assert_equal("My Suburb", suburb.name)
88
- end
89
-
90
- def test_create_habtm
91
- restaurant = Restaurant.create(:franchise_id => 100,
92
- :store_id => 200,
93
- :name => "My Store")
94
-
95
- restaurant.suburbs.create(:city_id => 24,
96
- :suburb_id => 25,
97
- :name => "My Suburb")
98
-
99
- # Test restaurant
100
- assert_equal(100, restaurant.franchise_id)
101
- assert_equal(200, restaurant.store_id)
102
- assert_equal("My Store", restaurant.name)
103
-
104
- assert_equal(1, restaurant.suburbs(true).length)
105
-
106
- # Test suburbs
107
- suburb = restaurant.suburbs[0]
108
- assert_equal(24, suburb.city_id)
109
- assert_equal(25, suburb.suburb_id)
110
- assert_equal("My Suburb", suburb.name)
111
- end
112
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestCreate < ActiveSupport::TestCase
4
+ fixtures :reference_types, :reference_codes, :streets, :suburbs
5
+
6
+ CLASSES = {
7
+ :single => {
8
+ :class => ReferenceType,
9
+ :primary_keys => :reference_type_id,
10
+ :create => {:reference_type_id => 10, :type_label => 'NEW_TYPE', :abbreviation => 'New Type'}
11
+ },
12
+ :dual => {
13
+ :class => ReferenceCode,
14
+ :primary_keys => [:reference_type_id, :reference_code],
15
+ :create => {:reference_type_id => 1, :reference_code => 20, :code_label => 'NEW_CODE', :abbreviation => 'New Code'}
16
+ }
17
+ }
18
+
19
+ def setup
20
+ self.class.classes = CLASSES
21
+ end
22
+
23
+ def test_setup
24
+ testing_with do
25
+ assert_not_nil @klass_info[:create]
26
+ end
27
+ end
28
+
29
+ def test_create
30
+ testing_with do
31
+ assert new_obj = @klass.create(@klass_info[:create])
32
+ assert !new_obj.new_record?
33
+ assert new_obj.id
34
+ end
35
+ end
36
+
37
+ def test_create_no_id
38
+ testing_with do
39
+ begin
40
+ @obj = @klass.create(@klass_info[:create].except(@klass.primary_key))
41
+ @successful = !composite?
42
+ rescue ActiveRecord::CompositeKeyError
43
+ @successful = false
44
+ rescue
45
+ flunk "Incorrect exception raised: #{$!}, #{$!.class}"
46
+ end
47
+ assert_equal composite?, !@successful, "Create should have failed for composites; #{@obj.inspect}"
48
+ end
49
+ end
50
+
51
+ def test_create_on_association
52
+ suburb = Suburb.first
53
+ suburb.streets.create(:name => "my street")
54
+ street = Street.find_by_name('my street')
55
+ assert_equal(suburb.city_id, street.city_id)
56
+ assert_equal(suburb.suburb_id, street.suburb_id)
57
+ end
58
+
59
+ def test_create_on_association_when_belongs_to_is_single_key
60
+ rt = ReferenceType.first
61
+ rt.reference_codes.create(:reference_code => 4321, :code_label => 'foo', :abbreviation => 'bar')
62
+ rc = ReferenceCode.find_by_reference_code(4321)
63
+ assert_equal(rc.reference_type_id, rt.reference_type_id)
64
+ end
65
+
66
+ def test_new_habtm
67
+ restaurant = Restaurant.new(:franchise_id => 101,
68
+ :store_id => 201,
69
+ :name => "My Store")
70
+
71
+ restaurant.suburbs << Suburb.new(:city_id => 24,
72
+ :suburb_id => 25,
73
+ :name => "My Suburb")
74
+
75
+ restaurant.save!
76
+
77
+ # Test restaurant
78
+ assert_equal(101, restaurant.franchise_id)
79
+ assert_equal(201, restaurant.store_id)
80
+ assert_equal("My Store", restaurant.name)
81
+ assert_equal(1, restaurant.suburbs.length)
82
+
83
+ # Test suburbs
84
+ suburb = restaurant.suburbs[0]
85
+ assert_equal(24, suburb.city_id)
86
+ assert_equal(25, suburb.suburb_id)
87
+ assert_equal("My Suburb", suburb.name)
88
+ end
89
+
90
+ def test_create_habtm
91
+ restaurant = Restaurant.create(:franchise_id => 100,
92
+ :store_id => 200,
93
+ :name => "My Store")
94
+
95
+ restaurant.suburbs.create(:city_id => 24,
96
+ :suburb_id => 25,
97
+ :name => "My Suburb")
98
+
99
+ # Test restaurant
100
+ assert_equal(100, restaurant.franchise_id)
101
+ assert_equal(200, restaurant.store_id)
102
+ assert_equal("My Store", restaurant.name)
103
+
104
+ assert_equal(1, restaurant.suburbs(true).length)
105
+
106
+ # Test suburbs
107
+ suburb = restaurant.suburbs[0]
108
+ assert_equal(24, suburb.city_id)
109
+ assert_equal(25, suburb.suburb_id)
110
+ assert_equal("My Suburb", suburb.name)
111
+ end
112
+ end
@@ -1,148 +1,152 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestDelete < ActiveSupport::TestCase
4
- fixtures :articles, :departments, :employees, :products, :tariffs, :product_tariffs,
5
- :reference_types, :reference_codes
6
-
7
- CLASSES = {
8
- :single => {
9
- :class => ReferenceType,
10
- :primary_keys => :reference_type_id,
11
- },
12
- :dual => {
13
- :class => ReferenceCode,
14
- :primary_keys => [:reference_type_id, :reference_code],
15
- },
16
- }
17
-
18
- def setup
19
- self.class.classes = CLASSES
20
- end
21
-
22
- def test_destroy_one
23
- testing_with do
24
- assert @first.destroy
25
- end
26
- end
27
-
28
- def test_destroy_one_alone_via_class
29
- testing_with do
30
- assert @klass.destroy(@first.id)
31
- end
32
- end
33
-
34
- def test_delete_one_alone
35
- testing_with do
36
- assert @klass.delete(@first.id)
37
- end
38
- end
39
-
40
- def test_delete_many
41
- testing_with do
42
- to_delete = @klass.limit(2)
43
- assert_equal 2, to_delete.length
44
- end
45
- end
46
-
47
- def test_delete_all
48
- testing_with do
49
- @klass.delete_all
50
- end
51
- end
52
-
53
- def test_clear_association
54
- department = Department.find([1,1])
55
- assert_equal(2, department.employees.size, "Before clear employee count should be 2.")
56
-
57
- department.employees.clear
58
- assert_equal(0, department.employees.size, "After clear employee count should be 0.")
59
-
60
- department.reload
61
- assert_equal(0, department.employees.size, "After clear and a reload from DB employee count should be 0.")
62
- end
63
-
64
- def test_delete_association
65
- department = Department.find([1,1])
66
- assert_equal 2, department.employees.size , "Before delete employee count should be 2."
67
- first_employee = department.employees[0]
68
- department.employees.delete(first_employee)
69
- assert_equal 1, department.employees.size, "After delete employee count should be 1."
70
- department.reload
71
- assert_equal 1, department.employees.size, "After delete and a reload from DB employee count should be 1."
72
- end
73
-
74
- def test_destroy_has_one
75
- # In this case the association is a has_one with
76
- # dependent set to :destroy
77
- department = departments(:engineering)
78
- assert_not_nil(department.head)
79
-
80
- # Get head employee id
81
- head_id = department.head.id
82
-
83
- # Delete department - should delete the head
84
- department.destroy
85
-
86
- # Verify the head is also
87
- assert_raise(ActiveRecord::RecordNotFound) do
88
- Employee.find(head_id)
89
- end
90
- end
91
-
92
- def test_destroy_has_and_belongs_to_many_on_non_cpk
93
- steve = employees(:steve)
94
- records_before = ActiveRecord::Base.connection.execute("select * from employees_groups").count
95
- steve.destroy
96
- records_after = ActiveRecord::Base.connection.execute("select * from employees_groups").count
97
- assert_equal records_after, records_before - steve.groups.count
98
- end
99
-
100
- def test_delete_not_destroy_on_cpk
101
- tariff = Tariff.where(tariff_id: 2).first
102
- tariff.delete
103
- assert !tariff.persisted?
104
- end
105
-
106
- def test_delete_not_destroy_on_non_cpk
107
- article = Article.first
108
- article.delete
109
- assert !article.persisted?
110
- end
111
-
112
- def test_destroy_has_many_delete_all
113
- # In this case the association is a has_many composite key with
114
- # dependent set to :delete_all
115
- product = Product.find(1)
116
- assert_equal(2, product.product_tariffs.length)
117
-
118
- # Get product_tariff length
119
- product_tariff_size = ProductTariff.count
120
-
121
- # Delete product - should delete 2 product tariffs
122
- product.destroy
123
-
124
- # Verify product_tariff are deleted
125
- assert_equal(product_tariff_size - 2, ProductTariff.count)
126
- end
127
-
128
- def test_delete_cpk_association
129
- product = Product.find(1)
130
- assert_equal(2, product.product_tariffs.length)
131
-
132
- product_tariff = product.product_tariffs.first
133
- product.product_tariffs.delete(product_tariff)
134
-
135
- product.reload
136
- assert_equal(1, product.product_tariffs.length)
137
- end
138
-
139
- def test_delete_records_for_has_many_association_with_composite_primary_key
140
- reference_type = ReferenceType.find(1)
141
- codes_to_delete = reference_type.reference_codes[0..1]
142
- assert_equal(3, reference_type.reference_codes.size, "Before deleting records reference_code count should be 3.")
143
-
144
- reference_type.reference_codes.delete(codes_to_delete)
145
- reference_type.reload
146
- assert_equal(1, reference_type.reference_codes.size, "After deleting 2 records and a reload from DB reference_code count should be 1.")
147
- end
148
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestDelete < ActiveSupport::TestCase
4
+ fixtures :articles, :departments, :employees, :products, :tariffs, :product_tariffs,
5
+ :reference_types, :reference_codes
6
+
7
+ CLASSES = {
8
+ :single => {
9
+ :class => ReferenceType,
10
+ :primary_keys => :reference_type_id,
11
+ },
12
+ :dual => {
13
+ :class => ReferenceCode,
14
+ :primary_keys => [:reference_type_id, :reference_code],
15
+ },
16
+ }
17
+
18
+ def setup
19
+ self.class.classes = CLASSES
20
+ end
21
+
22
+ def test_destroy_one
23
+ testing_with do
24
+ assert @first.destroy
25
+ end
26
+ end
27
+
28
+ def test_destroy_one_alone_via_class
29
+ testing_with do
30
+ assert @klass.destroy(@first.id)
31
+ end
32
+ end
33
+
34
+ def test_delete_one_alone
35
+ testing_with do
36
+ assert @klass.delete(@first.id)
37
+ end
38
+ end
39
+
40
+ def test_delete_many
41
+ testing_with do
42
+ to_delete = @klass.limit(2)
43
+ assert_equal 2, to_delete.length
44
+ end
45
+ end
46
+
47
+ def test_delete_all
48
+ testing_with do
49
+ @klass.delete_all
50
+ end
51
+ end
52
+
53
+ def test_delete_all_with_joins
54
+ ReferenceCode.joins(:reference_type).where(:reference_type_id => 1).delete_all
55
+ end
56
+
57
+ def test_clear_association
58
+ department = Department.find([1,1])
59
+ assert_equal(2, department.employees.size, "Before clear employee count should be 2.")
60
+
61
+ department.employees.clear
62
+ assert_equal(0, department.employees.size, "After clear employee count should be 0.")
63
+
64
+ department.reload
65
+ assert_equal(0, department.employees.size, "After clear and a reload from DB employee count should be 0.")
66
+ end
67
+
68
+ def test_delete_association
69
+ department = Department.find([1,1])
70
+ assert_equal 2, department.employees.size , "Before delete employee count should be 2."
71
+ first_employee = department.employees[0]
72
+ department.employees.delete(first_employee)
73
+ assert_equal 1, department.employees.size, "After delete employee count should be 1."
74
+ department.reload
75
+ assert_equal 1, department.employees.size, "After delete and a reload from DB employee count should be 1."
76
+ end
77
+
78
+ def test_destroy_has_one
79
+ # In this case the association is a has_one with
80
+ # dependent set to :destroy
81
+ department = departments(:engineering)
82
+ assert_not_nil(department.head)
83
+
84
+ # Get head employee id
85
+ head_id = department.head.id
86
+
87
+ # Delete department - should delete the head
88
+ department.destroy
89
+
90
+ # Verify the head is also
91
+ assert_raise(ActiveRecord::RecordNotFound) do
92
+ Employee.find(head_id)
93
+ end
94
+ end
95
+
96
+ def test_destroy_has_and_belongs_to_many_on_non_cpk
97
+ steve = employees(:steve)
98
+ records_before = ActiveRecord::Base.connection.execute("select * from employees_groups").count
99
+ steve.destroy
100
+ records_after = ActiveRecord::Base.connection.execute("select * from employees_groups").count
101
+ assert_equal records_after, records_before - steve.groups.count
102
+ end
103
+
104
+ def test_delete_not_destroy_on_cpk
105
+ tariff = Tariff.where(tariff_id: 2).first
106
+ tariff.delete
107
+ assert !tariff.persisted?
108
+ end
109
+
110
+ def test_delete_not_destroy_on_non_cpk
111
+ article = Article.first
112
+ article.delete
113
+ assert !article.persisted?
114
+ end
115
+
116
+ def test_destroy_has_many_delete_all
117
+ # In this case the association is a has_many composite key with
118
+ # dependent set to :delete_all
119
+ product = Product.find(1)
120
+ assert_equal(2, product.product_tariffs.length)
121
+
122
+ # Get product_tariff length
123
+ product_tariff_size = ProductTariff.count
124
+
125
+ # Delete product - should delete 2 product tariffs
126
+ product.destroy
127
+
128
+ # Verify product_tariff are deleted
129
+ assert_equal(product_tariff_size - 2, ProductTariff.count)
130
+ end
131
+
132
+ def test_delete_cpk_association
133
+ product = Product.find(1)
134
+ assert_equal(2, product.product_tariffs.length)
135
+
136
+ product_tariff = product.product_tariffs.first
137
+ product.product_tariffs.delete(product_tariff)
138
+
139
+ product.reload
140
+ assert_equal(1, product.product_tariffs.length)
141
+ end
142
+
143
+ def test_delete_records_for_has_many_association_with_composite_primary_key
144
+ reference_type = ReferenceType.find(1)
145
+ codes_to_delete = reference_type.reference_codes[0..1]
146
+ assert_equal(3, reference_type.reference_codes.size, "Before deleting records reference_code count should be 3.")
147
+
148
+ reference_type.reference_codes.delete(codes_to_delete)
149
+ reference_type.reload
150
+ assert_equal(1, reference_type.reference_codes.size, "After deleting 2 records and a reload from DB reference_code count should be 1.")
151
+ end
152
+ end