composite_primary_keys 14.0.3 → 14.0.9

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +49 -0
  3. data/README.rdoc +182 -182
  4. data/Rakefile +1 -1
  5. data/lib/composite_primary_keys/associations/association.rb +2 -2
  6. data/lib/composite_primary_keys/associations/association_scope.rb +1 -1
  7. data/lib/composite_primary_keys/associations/collection_association.rb +10 -3
  8. data/lib/composite_primary_keys/associations/has_many_through_association.rb +19 -0
  9. data/lib/composite_primary_keys/associations/preloader/association.rb +52 -68
  10. data/lib/composite_primary_keys/autosave_association.rb +1 -1
  11. data/lib/composite_primary_keys/composite_arrays.rb +2 -0
  12. data/lib/composite_primary_keys/composite_predicates.rb +121 -71
  13. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +1 -2
  14. data/lib/composite_primary_keys/nested_attributes.rb +2 -2
  15. data/lib/composite_primary_keys/persistence.rb +96 -96
  16. data/lib/composite_primary_keys/relation/calculations.rb +110 -110
  17. data/lib/composite_primary_keys/relation/query_methods.rb +14 -16
  18. data/lib/composite_primary_keys/relation.rb +4 -2
  19. data/lib/composite_primary_keys/validations/uniqueness.rb +10 -2
  20. data/lib/composite_primary_keys/version.rb +1 -1
  21. data/lib/composite_primary_keys.rb +117 -119
  22. data/scripts/console.rb +2 -2
  23. data/tasks/databases/trilogy.rake +23 -0
  24. data/test/abstract_unit.rb +124 -118
  25. data/test/connections/databases.ci.yml +10 -0
  26. data/test/fixtures/admin.rb +4 -0
  27. data/test/fixtures/comments.yml +6 -0
  28. data/test/fixtures/db_definitions/db2-create-tables.sql +34 -0
  29. data/test/fixtures/db_definitions/db2-drop-tables.sql +7 -1
  30. data/test/fixtures/db_definitions/mysql.sql +23 -0
  31. data/test/fixtures/db_definitions/oracle.drop.sql +4 -0
  32. data/test/fixtures/db_definitions/oracle.sql +21 -0
  33. data/test/fixtures/db_definitions/postgresql.sql +23 -0
  34. data/test/fixtures/db_definitions/sqlite.sql +21 -0
  35. data/test/fixtures/db_definitions/sqlserver.sql +23 -0
  36. data/test/fixtures/department.rb +20 -16
  37. data/test/fixtures/moderator.rb +4 -0
  38. data/test/fixtures/room.rb +4 -1
  39. data/test/fixtures/room_assignment.rb +6 -2
  40. data/test/fixtures/staff_room.rb +6 -0
  41. data/test/fixtures/staff_room_key.rb +6 -0
  42. data/test/fixtures/user.rb +3 -0
  43. data/test/fixtures/user_with_polymorphic_name.rb +9 -0
  44. data/test/test_associations.rb +403 -372
  45. data/test/test_composite_arrays.rb +6 -0
  46. data/test/test_create.rb +219 -218
  47. data/test/test_has_one_through.rb +30 -0
  48. data/test/test_nested_attributes.rb +23 -0
  49. data/test/test_polymorphic.rb +6 -0
  50. data/test/test_predicates.rb +130 -60
  51. metadata +13 -6
  52. data/lib/composite_primary_keys/associations/through_association.rb +0 -24
@@ -35,4 +35,10 @@ class CompositeArraysTest < ActiveSupport::TestCase
35
35
  assert_equal 'The USA,^5EWashington^2C D.C.',
36
36
  CompositePrimaryKeys::CompositeKeys.new(['The USA', '^Washington, D.C.']).to_s
37
37
  end
38
+
39
+ def test_to_param
40
+ assert_equal '1,2', CompositePrimaryKeys::CompositeKeys.new([1, 2]).to_param
41
+ assert_equal 'The USA,^5EWashington^2C D.C.',
42
+ CompositePrimaryKeys::CompositeKeys.new(['The USA', '^Washington, D.C.']).to_param
43
+ end
38
44
  end
data/test/test_create.rb CHANGED
@@ -1,218 +1,219 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestCreate < ActiveSupport::TestCase
4
- fixtures :articles, :students, :dorms, :rooms, :room_assignments, :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_with_array
52
- date = Date.new(2027, 01, 27)
53
- tariff = Tariff.create!(id: [10, date], amount: 27)
54
- refute_nil(tariff)
55
- assert_equal([10, date], tariff.id)
56
- assert_equal(date, tariff.start_date)
57
- assert_equal(27, tariff.amount)
58
- end
59
-
60
- def test_create_with_partial_serial
61
- attributes = {:location_id => 100}
62
-
63
- # SQLite does not support an autoincrementing field in a composite key
64
- if Department.connection.class.name == "ActiveRecord::ConnectionAdapters::SQLite3Adapter"
65
- attributes[:id] = 200
66
- end
67
-
68
- department = Department.new(attributes)
69
- assert_nil(department.attributes[:id])
70
-
71
- department.save!
72
- refute_nil(department.attributes["id"])
73
- assert_equal(100, department.location_id)
74
- end
75
-
76
- def test_create_with_id
77
- department = Department.create!(id: [2, 3])
78
- assert_equal([2, 3], department.id)
79
- assert_equal(2, department.attributes["id"])
80
- assert_equal(3, department.attributes["location_id"])
81
-
82
- department.reload
83
- assert_equal([2, 3], department.id)
84
- assert_equal(2, department.attributes["id"])
85
- assert_equal(3, department.attributes["location_id"])
86
- end
87
-
88
- def test_create_on_association
89
- suburb = Suburb.first
90
- suburb.streets.create(:name => "my street")
91
- street = Street.find_by_name('my street')
92
- assert_equal(suburb.city_id, street.city_id)
93
- assert_equal(suburb.suburb_id, street.suburb_id)
94
- end
95
-
96
- def test_create_on_association_when_belongs_to_is_single_key
97
- rt = ReferenceType.first
98
- rt.reference_codes.create(:reference_code => 4321, :code_label => 'foo', :abbreviation => 'bar')
99
- rc = ReferenceCode.find_by_reference_code(4321)
100
- assert_equal(rc.reference_type_id, rt.reference_type_id)
101
- end
102
-
103
- def test_new_habtm
104
- restaurant = Restaurant.new(:franchise_id => 101,
105
- :store_id => 201,
106
- :name => "My Store")
107
-
108
- restaurant.suburbs << Suburb.new(:city_id => 24,
109
- :suburb_id => 25,
110
- :name => "My Suburb")
111
-
112
- restaurant.save!
113
-
114
- # Test restaurant
115
- assert_equal(101, restaurant.franchise_id)
116
- assert_equal(201, restaurant.store_id)
117
- assert_equal("My Store", restaurant.name)
118
- assert_equal(1, restaurant.suburbs.length)
119
-
120
- # Test suburbs
121
- suburb = restaurant.suburbs[0]
122
- assert_equal(24, suburb.city_id)
123
- assert_equal(25, suburb.suburb_id)
124
- assert_equal("My Suburb", suburb.name)
125
- end
126
-
127
- def test_create_habtm
128
- restaurant = Restaurant.create(:franchise_id => 100,
129
- :store_id => 200,
130
- :name => "My Store")
131
-
132
- restaurant.suburbs.create(:city_id => 24,
133
- :suburb_id => 25,
134
- :name => "My Suburb")
135
-
136
- # Test restaurant
137
- assert_equal(100, restaurant.franchise_id)
138
- assert_equal(200, restaurant.store_id)
139
- assert_equal("My Store", restaurant.name)
140
-
141
- assert_equal(1, restaurant.suburbs.reload.length)
142
-
143
- # Test suburbs
144
- suburb = restaurant.suburbs[0]
145
- assert_equal(24, suburb.city_id)
146
- assert_equal(25, suburb.suburb_id)
147
- assert_equal("My Suburb", suburb.name)
148
- end
149
-
150
- def test_has_many_ids_1
151
- dorm = dorms(:toyon)
152
- room = Room.new(:dorm_id => dorm.id, :room_id => 5)
153
- room.save!
154
-
155
- student1 = students(:kelly)
156
-
157
- RoomAssignment.delete_all
158
-
159
- assignment1 = RoomAssignment.new(:student_id => student1.id, :dorm_id => room.dorm_id, :room_id => room.room_id)
160
- assignment1.save!
161
-
162
- room.room_assignment_ids = [[assignment1.student_id, assignment1.dorm_id, assignment1.room_id]]
163
- room.save!
164
-
165
- assert_equal(1, room.room_assignments.length)
166
- assert_equal(assignment1, room.room_assignments.first)
167
- end
168
-
169
- def test_has_many_ids_2
170
- dorm = dorms(:toyon)
171
- room = Room.new(:dorm_id => dorm.id, :room_id => 5)
172
- room.save!
173
-
174
- student1 = students(:kelly)
175
- student2 = students(:jordan)
176
-
177
- RoomAssignment.delete_all
178
-
179
- assignment1 = RoomAssignment.new(:student_id => student1.id, :dorm_id => room.dorm_id, :room_id => room.room_id)
180
- assignment1.save!
181
-
182
- assignment2 = RoomAssignment.new(:student_id => student2.id, :dorm_id => room.dorm_id, :room_id => room.room_id)
183
- assignment2.save!
184
-
185
- room.room_assignment_ids = [[assignment1.student_id, assignment1.dorm_id, assignment1.room_id],
186
- [assignment2.student_id, assignment2.dorm_id, assignment2.room_id]]
187
- room.save!
188
-
189
- assert_equal(2, room.room_assignments.length)
190
- assert_equal(assignment1, room.room_assignments[0])
191
- assert_equal(assignment2, room.room_assignments[1])
192
- end
193
-
194
- def test_find_or_create_by
195
- suburb = Suburb.find_by(:city_id => 3, :suburb_id => 1)
196
- assert_nil(suburb)
197
-
198
- suburb = Suburb.find_or_create_by!(:name => 'New Suburb', :city_id => 3, :suburb_id => 1)
199
- refute_nil(suburb)
200
- end
201
-
202
- def test_cache
203
- Suburb.cache do
204
- # Suburb does not exist
205
- suburb = Suburb.find_by(:city_id => 10, :suburb_id => 10)
206
- assert_nil(suburb)
207
-
208
- # Create it
209
- suburb = Suburb.create!(:name => 'New Suburb', :city_id => 10, :suburb_id => 10)
210
-
211
- # Should be able to find it
212
- suburb = Suburb.find_by(:city_id => 10)
213
- refute_nil(suburb)
214
- refute_nil(suburb.city_id)
215
- refute_nil(suburb.suburb_id)
216
- end
217
- end
218
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestCreate < ActiveSupport::TestCase
4
+ fixtures :articles, :students, :dorms, :rooms, :room_assignments, :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
+ assert new_obj.previously_new_record?
35
+ end
36
+ end
37
+
38
+ def test_create_no_id
39
+ testing_with do
40
+ begin
41
+ @obj = @klass.create(@klass_info[:create].except(@klass.primary_key))
42
+ @successful = !composite?
43
+ rescue ActiveRecord::CompositeKeyError
44
+ @successful = false
45
+ rescue
46
+ flunk "Incorrect exception raised: #{$!}, #{$!.class}"
47
+ end
48
+ assert_equal composite?, !@successful, "Create should have failed for composites; #{@obj.inspect}"
49
+ end
50
+ end
51
+
52
+ def test_create_with_array
53
+ date = Date.new(2027, 01, 27)
54
+ tariff = Tariff.create!(id: [10, date], amount: 27)
55
+ refute_nil(tariff)
56
+ assert_equal([10, date], tariff.id)
57
+ assert_equal(date, tariff.start_date)
58
+ assert_equal(27, tariff.amount)
59
+ end
60
+
61
+ def test_create_with_partial_serial
62
+ attributes = {:location_id => 100}
63
+
64
+ # SQLite does not support an autoincrementing field in a composite key
65
+ if Department.connection.class.name == "ActiveRecord::ConnectionAdapters::SQLite3Adapter"
66
+ attributes[:id] = 200
67
+ end
68
+
69
+ department = Department.new(attributes)
70
+ assert_nil(department.attributes[:id])
71
+
72
+ department.save!
73
+ refute_nil(department.attributes["id"])
74
+ assert_equal(100, department.location_id)
75
+ end
76
+
77
+ def test_create_with_id
78
+ department = Department.create!(id: [2, 3])
79
+ assert_equal([2, 3], department.id)
80
+ assert_equal(2, department.attributes["id"])
81
+ assert_equal(3, department.attributes["location_id"])
82
+
83
+ department.reload
84
+ assert_equal([2, 3], department.id)
85
+ assert_equal(2, department.attributes["id"])
86
+ assert_equal(3, department.attributes["location_id"])
87
+ end
88
+
89
+ def test_create_on_association
90
+ suburb = Suburb.first
91
+ suburb.streets.create(:name => "my street")
92
+ street = Street.find_by_name('my street')
93
+ assert_equal(suburb.city_id, street.city_id)
94
+ assert_equal(suburb.suburb_id, street.suburb_id)
95
+ end
96
+
97
+ def test_create_on_association_when_belongs_to_is_single_key
98
+ rt = ReferenceType.first
99
+ rt.reference_codes.create(:reference_code => 4321, :code_label => 'foo', :abbreviation => 'bar')
100
+ rc = ReferenceCode.find_by_reference_code(4321)
101
+ assert_equal(rc.reference_type_id, rt.reference_type_id)
102
+ end
103
+
104
+ def test_new_habtm
105
+ restaurant = Restaurant.new(:franchise_id => 101,
106
+ :store_id => 201,
107
+ :name => "My Store")
108
+
109
+ restaurant.suburbs << Suburb.new(:city_id => 24,
110
+ :suburb_id => 25,
111
+ :name => "My Suburb")
112
+
113
+ restaurant.save!
114
+
115
+ # Test restaurant
116
+ assert_equal(101, restaurant.franchise_id)
117
+ assert_equal(201, restaurant.store_id)
118
+ assert_equal("My Store", restaurant.name)
119
+ assert_equal(1, restaurant.suburbs.length)
120
+
121
+ # Test suburbs
122
+ suburb = restaurant.suburbs[0]
123
+ assert_equal(24, suburb.city_id)
124
+ assert_equal(25, suburb.suburb_id)
125
+ assert_equal("My Suburb", suburb.name)
126
+ end
127
+
128
+ def test_create_habtm
129
+ restaurant = Restaurant.create(:franchise_id => 100,
130
+ :store_id => 200,
131
+ :name => "My Store")
132
+
133
+ restaurant.suburbs.create(:city_id => 24,
134
+ :suburb_id => 25,
135
+ :name => "My Suburb")
136
+
137
+ # Test restaurant
138
+ assert_equal(100, restaurant.franchise_id)
139
+ assert_equal(200, restaurant.store_id)
140
+ assert_equal("My Store", restaurant.name)
141
+
142
+ assert_equal(1, restaurant.suburbs.reload.length)
143
+
144
+ # Test suburbs
145
+ suburb = restaurant.suburbs[0]
146
+ assert_equal(24, suburb.city_id)
147
+ assert_equal(25, suburb.suburb_id)
148
+ assert_equal("My Suburb", suburb.name)
149
+ end
150
+
151
+ def test_has_many_ids_1
152
+ dorm = dorms(:toyon)
153
+ room = Room.new(:dorm_id => dorm.id, :room_id => 5)
154
+ room.save!
155
+
156
+ student1 = students(:kelly)
157
+
158
+ RoomAssignment.delete_all
159
+
160
+ assignment1 = RoomAssignment.new(:student_id => student1.id, :dorm_id => room.dorm_id, :room_id => room.room_id)
161
+ assignment1.save!
162
+
163
+ room.room_assignment_ids = [[assignment1.student_id, assignment1.dorm_id, assignment1.room_id]]
164
+ room.save!
165
+
166
+ assert_equal(1, room.room_assignments.length)
167
+ assert_equal(assignment1, room.room_assignments.first)
168
+ end
169
+
170
+ def test_has_many_ids_2
171
+ dorm = dorms(:toyon)
172
+ room = Room.new(:dorm_id => dorm.id, :room_id => 5)
173
+ room.save!
174
+
175
+ student1 = students(:kelly)
176
+ student2 = students(:jordan)
177
+
178
+ RoomAssignment.delete_all
179
+
180
+ assignment1 = RoomAssignment.new(:student_id => student1.id, :dorm_id => room.dorm_id, :room_id => room.room_id)
181
+ assignment1.save!
182
+
183
+ assignment2 = RoomAssignment.new(:student_id => student2.id, :dorm_id => room.dorm_id, :room_id => room.room_id)
184
+ assignment2.save!
185
+
186
+ room.room_assignment_ids = [[assignment1.student_id, assignment1.dorm_id, assignment1.room_id],
187
+ [assignment2.student_id, assignment2.dorm_id, assignment2.room_id]]
188
+ room.save!
189
+
190
+ assert_equal(2, room.room_assignments.length)
191
+ assert_equal(assignment1, room.room_assignments[0])
192
+ assert_equal(assignment2, room.room_assignments[1])
193
+ end
194
+
195
+ def test_find_or_create_by
196
+ suburb = Suburb.find_by(:city_id => 3, :suburb_id => 1)
197
+ assert_nil(suburb)
198
+
199
+ suburb = Suburb.find_or_create_by!(:name => 'New Suburb', :city_id => 3, :suburb_id => 1)
200
+ refute_nil(suburb)
201
+ end
202
+
203
+ def test_cache
204
+ Suburb.cache do
205
+ # Suburb does not exist
206
+ suburb = Suburb.find_by(:city_id => 10, :suburb_id => 10)
207
+ assert_nil(suburb)
208
+
209
+ # Create it
210
+ suburb = Suburb.create!(:name => 'New Suburb', :city_id => 10, :suburb_id => 10)
211
+
212
+ # Should be able to find it
213
+ suburb = Suburb.find_by(:city_id => 10)
214
+ refute_nil(suburb)
215
+ refute_nil(suburb.city_id)
216
+ refute_nil(suburb.suburb_id)
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestHasOneThrough < ActiveSupport::TestCase
4
+ fixtures :users, :rooms
5
+
6
+ def test_no_cpk
7
+ # This test makes sure we don't break anything in standard rails by using CPK
8
+ user = User.find(1)
9
+ assert_nil user.moderator
10
+ assert_nil user.admin
11
+
12
+ admin = Admin.create!(user: user)
13
+ assert_equal admin, user.admin
14
+ assert_equal 1, user.moderator.id
15
+ assert_equal 1, admin.id
16
+ end
17
+
18
+ def test_has_one_through
19
+ room = Room.find([1,1])
20
+ assert_nil room.staff_room
21
+ assert_nil room.staff_room_key
22
+
23
+ key = StaffRoomKey.create!(room: room, key_no: '1234')
24
+ assert_equal key, room.staff_room_key
25
+ assert_equal 1, room.staff_room.dorm_id
26
+ assert_equal 1, room.staff_room.room_id
27
+ assert_equal 1, key.dorm_id
28
+ assert_equal 1, key.room_id
29
+ end
30
+ end
@@ -64,4 +64,27 @@ class TestNestedAttributes < ActiveSupport::TestCase
64
64
  assert_equal(reference_code.code_label, 'XX')
65
65
  assert_equal(reference_code.abbreviation, 'Xx')
66
66
  end
67
+
68
+ def test_nested_atttribute_update_4
69
+ code_id = 1003
70
+
71
+ reference_type = reference_types(:name_prefix)
72
+ reference_type.update :reference_codes_attributes => [{
73
+ :reference_code => code_id,
74
+ :code_label => 'XX',
75
+ :abbreviation => 'Xx'
76
+ }]
77
+ assert_not_nil ReferenceCode.find_by_reference_code(code_id)
78
+ reference_code = ReferenceCode.find_by_reference_code(code_id)
79
+ # directly pass :id as a array
80
+ reference_type.update :reference_codes_attributes => [{
81
+ :id => [reference_type.reference_type_id, code_id],
82
+ :code_label => 'AAA',
83
+ :abbreviation => 'Aaa'
84
+ }]
85
+
86
+ reference_code = ReferenceCode.find_by_reference_code(code_id)
87
+ assert_kind_of(ReferenceCode, reference_code)
88
+ assert_equal(reference_code.code_label, 'AAA')
89
+ end
67
90
  end
@@ -40,4 +40,10 @@ class TestPolymorphic < ActiveSupport::TestCase
40
40
  article.user_commentators = []
41
41
  assert_equal(0, article.comments.size)
42
42
  end
43
+
44
+ def test_polymorphic_has_many_with_polymorphic_name
45
+ comments = UserWithPolymorphicName.find(1).comments
46
+ assert_equal 1, comments[0].person_id
47
+ assert_equal "User1", comments[0].person_type
48
+ end
43
49
  end