composite_primary_keys 12.0.2 → 12.0.3

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +13 -0
  3. data/README.rdoc +3 -2
  4. data/lib/composite_primary_keys.rb +56 -56
  5. data/lib/composite_primary_keys/active_model/attribute_assignment.rb +19 -0
  6. data/lib/composite_primary_keys/arel/sqlserver.rb +1 -3
  7. data/lib/composite_primary_keys/associations/through_association.rb +2 -1
  8. data/lib/composite_primary_keys/attribute_methods.rb +1 -1
  9. data/lib/composite_primary_keys/attribute_methods/primary_key.rb +13 -0
  10. data/lib/composite_primary_keys/base.rb +11 -0
  11. data/lib/composite_primary_keys/composite_arrays.rb +0 -8
  12. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +8 -3
  13. data/lib/composite_primary_keys/connection_adapters/mysql/database_statements.rb +24 -0
  14. data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +29 -11
  15. data/lib/composite_primary_keys/persistence.rb +2 -2
  16. data/lib/composite_primary_keys/relation.rb +36 -27
  17. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +1 -1
  18. data/lib/composite_primary_keys/version.rb +1 -1
  19. data/test/abstract_unit.rb +3 -2
  20. data/test/fixtures/article.rb +4 -0
  21. data/test/fixtures/articles.yml +4 -3
  22. data/test/fixtures/comment.rb +1 -3
  23. data/test/fixtures/comments.yml +10 -9
  24. data/test/fixtures/db_definitions/db2-create-tables.sql +0 -14
  25. data/test/fixtures/db_definitions/db2-drop-tables.sql +1 -3
  26. data/test/fixtures/db_definitions/mysql.sql +6 -43
  27. data/test/fixtures/db_definitions/oracle.drop.sql +3 -9
  28. data/test/fixtures/db_definitions/oracle.sql +12 -48
  29. data/test/fixtures/db_definitions/postgresql.sql +7 -44
  30. data/test/fixtures/db_definitions/sqlite.sql +6 -42
  31. data/test/fixtures/db_definitions/sqlserver.sql +5 -41
  32. data/test/fixtures/department.rb +8 -3
  33. data/test/fixtures/departments.yml +4 -4
  34. data/test/fixtures/readings.yml +2 -2
  35. data/test/fixtures/restaurants_suburbs.yml +1 -1
  36. data/test/fixtures/streets.yml +2 -2
  37. data/test/fixtures/suburbs.yml +2 -2
  38. data/test/fixtures/user.rb +3 -2
  39. data/test/test_associations.rb +30 -23
  40. data/test/test_create.rb +15 -18
  41. data/test/test_delete.rb +3 -3
  42. data/test/test_exists.rb +5 -5
  43. data/test/test_find.rb +2 -2
  44. data/test/test_habtm.rb +2 -2
  45. data/test/test_ids.rb +2 -6
  46. data/test/test_nested_attributes.rb +0 -57
  47. data/test/test_polymorphic.rb +29 -13
  48. data/test/test_preload.rb +4 -3
  49. data/test/test_serialize.rb +2 -2
  50. data/test/test_update.rb +19 -1
  51. metadata +5 -19
  52. data/test/fixtures/hack.rb +0 -5
  53. data/test/fixtures/hacks.yml +0 -3
  54. data/test/fixtures/pk_called_id.rb +0 -5
  55. data/test/fixtures/pk_called_ids.yml +0 -11
  56. data/test/fixtures/reference_code_using_composite_key_alias.rb +0 -8
  57. data/test/fixtures/reference_code_using_simple_key_alias.rb +0 -8
  58. data/test/fixtures/seat.rb +0 -5
  59. data/test/fixtures/seats.yml +0 -9
  60. data/test/fixtures/topic.rb +0 -6
  61. data/test/fixtures/topic_source.rb +0 -7
  62. data/test/test_aliases.rb +0 -18
  63. data/test/test_enum.rb +0 -21
  64. data/test/test_suite.rb +0 -35
@@ -1,17 +1,5 @@
1
1
  USE [composite_primary_keys_unittest];
2
2
 
3
- CREATE TABLE topics (
4
- id [int] IDENTITY(1000,1) NOT NULL,
5
- name [varchar](50) default NULL,
6
- feed_size [int] default NULL
7
- );
8
-
9
- CREATE TABLE topic_sources (
10
- topic_id [int] NOT NULL,
11
- platform [varchar](50) NOT NULL,
12
- keywords [varchar](50) default NULL,
13
- );
14
-
15
3
  CREATE TABLE reference_types (
16
4
  reference_type_id [int] IDENTITY(1000,1) NOT NULL,
17
5
  type_label [varchar](50) NULL,
@@ -102,10 +90,10 @@ CREATE TABLE membership_statuses (
102
90
  );
103
91
 
104
92
  CREATE TABLE departments (
105
- department_id [int] NOT NULL,
93
+ id [int] IDENTITY(100,1) NOT NULL,
106
94
  location_id [int] NOT NULL
107
95
  CONSTRAINT [departments_pk] PRIMARY KEY
108
- ( [department_id], [location_id] )
96
+ ( [id], [location_id] )
109
97
  );
110
98
 
111
99
  CREATE TABLE employees (
@@ -117,15 +105,9 @@ CREATE TABLE employees (
117
105
 
118
106
  CREATE TABLE comments (
119
107
  id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL,
120
- person_id [int] NULL,
121
- shown [int] NULL,
122
- person_type varchar(100) NULL,
123
- hack_id [int] NULL
124
- );
125
-
126
- CREATE TABLE hacks (
127
- id [int] IDENTITY(1000,1) PRIMARY KEY NOT NULL,
128
- name [varchar](50) NOT NULL
108
+ article_id [int] NOT NULL,
109
+ person_id [int] NOT NULL,
110
+ person_type varchar(100) NULL
129
111
  );
130
112
 
131
113
  CREATE TABLE restaurants (
@@ -176,14 +158,6 @@ CREATE TABLE room_assignments (
176
158
  room_id [int] NOT NULL
177
159
  );
178
160
 
179
- CREATE TABLE seats (
180
- flight_number [int] NOT NULL,
181
- seat [int] NOT NULL,
182
- customer [int]
183
- CONSTRAINT [seats_pk] PRIMARY KEY
184
- ( [flight_number], [seat] )
185
- );
186
-
187
161
  CREATE TABLE capitols (
188
162
  country varchar(450) NOT NULL,
189
163
  city varchar(450) NOT NULL
@@ -200,14 +174,4 @@ CREATE TABLE products_restaurants (
200
174
  CREATE TABLE employees_groups (
201
175
  employee_id [int] not null,
202
176
  group_id [int] not null
203
- );
204
-
205
- CREATE TABLE pk_called_ids (
206
- id [int] IDENTITY(1000,1) NOT NULL,
207
- reference_code [int] not null,
208
- code_label [varchar](50) default null,
209
- abbreviation [varchar](50) default null,
210
- description [varchar](50) default null
211
- CONSTRAINT [pk_called_ids_pk] PRIMARY KEY
212
- ( [id], [reference_code] )
213
177
  );
@@ -1,11 +1,16 @@
1
1
  class Department < ActiveRecord::Base
2
- self.primary_keys = :department_id, :location_id
2
+ self.primary_keys = :id, :location_id
3
+
3
4
  has_many :employees,
4
5
  # We intentionally redefine primary key for test purposes. #455
5
- :primary_key => [:department_id, :location_id],
6
+ :primary_key => [:id, :location_id],
6
7
  :foreign_key => [:department_id, :location_id]
8
+
9
+ has_many :comments, :through => :employees
10
+
7
11
  has_one :head, :class_name => 'Employee', :autosave => true, :dependent => :delete,
8
12
  # We intentionally redefine primary key for test purposes. #455
9
- :primary_key => [:department_id, :location_id],
13
+ :primary_key => [:id, :location_id],
10
14
  :foreign_key => [:department_id, :location_id]
15
+
11
16
  end
@@ -1,15 +1,15 @@
1
1
  accounting:
2
- department_id: 1
2
+ id: 1
3
3
  location_id: 1
4
4
 
5
5
  engineering:
6
- department_id: 2
6
+ id: 2
7
7
  location_id: 1
8
8
 
9
9
  human_resources:
10
- department_id: 3
10
+ id: 3
11
11
  location_id: 2
12
12
 
13
13
  offsite_accounting:
14
- department_id: 1
14
+ id: 1
15
15
  location_id: 2
@@ -1,11 +1,11 @@
1
1
  santiago_first:
2
2
  id: 1
3
3
  user_id: 1
4
- article_id: 1
4
+ article: first
5
5
  rating: 4
6
6
 
7
7
  santiago_second:
8
8
  id: 2
9
9
  user_id: 1
10
- article_id: 2
10
+ article: second
11
11
  rating: 5
@@ -8,4 +8,4 @@ b:
8
8
  franchise_id: 1
9
9
  store_id: 1
10
10
  city_id: 2
11
- suburb_id: 1
11
+ suburb_id: 2
@@ -7,11 +7,11 @@ first:
7
7
  second1:
8
8
  id: 2
9
9
  city_id: 2
10
- suburb_id: 1
10
+ suburb_id: 2
11
11
  name: First Street
12
12
 
13
13
  second2:
14
14
  id: 3
15
15
  city_id: 2
16
- suburb_id: 1
16
+ suburb_id: 2
17
17
  name: Second Street
@@ -5,10 +5,10 @@ first:
5
5
 
6
6
  second:
7
7
  city_id: 2
8
- suburb_id: 1
8
+ suburb_id: 2
9
9
  name: Second Suburb
10
10
 
11
11
  no_mcdonalds:
12
12
  city_id: 1
13
- suburb_id: 2
13
+ suburb_id: 3
14
14
  name: Third Suburb
@@ -1,9 +1,10 @@
1
1
  class User < ActiveRecord::Base
2
2
  has_many :readings
3
3
  has_many :articles, :through => :readings
4
+
4
5
  has_many :comments, :as => :person
5
- has_many :hacks, :through => :comments, :source => :hack
6
-
6
+ has_one :first_comment, :as => :person, :class_name => "Comment"
7
+
7
8
  def find_custom_articles
8
9
  articles.where("name = ?", "Article One")
9
10
  end
@@ -96,18 +96,23 @@ class TestAssociations < ActiveSupport::TestCase
96
96
  end
97
97
 
98
98
  def test_has_one_association_primary_key_and_foreign_key_are_present
99
- department = departments(:human_resources)
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)
100
104
 
105
+ department = departments(:human_resources)
101
106
  assert_equal(1, department.employees.count)
102
107
  assert_equal('Mindy', department.employees[0].name)
108
+ assert_equal('Mindy', department.head.name)
103
109
 
104
110
  head = department.create_head(name: 'Rick')
105
- assert_equal(department.department_id, head.department_id)
106
- assert_equal(department.location_id, head.location_id)
111
+ assert_equal(department, head.department)
112
+ assert_equal('Rick', department.head.name)
107
113
 
108
114
  department.reload
109
115
  assert_equal(1, department.employees.count)
110
- assert_equal('Rick', department.employees[0].name)
111
116
  end
112
117
 
113
118
  def test_has_one_autosave
@@ -139,9 +144,10 @@ class TestAssociations < ActiveSupport::TestCase
139
144
 
140
145
  department.reload
141
146
  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)
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)
145
151
  end
146
152
 
147
153
  def test_find_includes_product_tariffs_product
@@ -174,6 +180,13 @@ class TestAssociations < ActiveSupport::TestCase
174
180
  assert_equal(3, tarrifs_length)
175
181
  end
176
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
+
177
190
  def test_new_style_includes_with_conditions
178
191
  product_tariff = ProductTariff.includes(:tariff).where('tariffs.amount < 5').references(:tariffs).first
179
192
  assert_equal(0, product_tariff.tariff.amount)
@@ -203,16 +216,8 @@ class TestAssociations < ActiveSupport::TestCase
203
216
  end
204
217
 
205
218
  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])
219
+ suburb = Suburb.find([2, 2])
213
220
  assert_equal 2, suburb.streets.size
214
-
215
- suburb = Suburb.includes(:first_streets).find([2, 1])
216
221
  assert_equal 1, suburb.first_streets.size
217
222
  end
218
223
 
@@ -239,7 +244,7 @@ class TestAssociations < ActiveSupport::TestCase
239
244
  steve = employees(:steve)
240
245
  steve.department = departments(:engineering)
241
246
  # It was returning this before:
242
- # {"[:department_id, :location_id]"=>[nil, [2, 1]]}
247
+ # {"[:id, :location_id]"=>[nil, [2, 1]]}
243
248
  assert_equal({"department_id"=>[1, 2]}, steve.changes)
244
249
  end
245
250
 
@@ -263,12 +268,12 @@ class TestAssociations < ActiveSupport::TestCase
263
268
  assert_equal user, reading.user
264
269
  end
265
270
 
266
- def test_has_many_build__composite_key
271
+ def test_has_many_build_composite_key
267
272
  department = departments(:engineering)
268
273
  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
274
+ assert_equal(department[:id], employee.department_id)
275
+ assert_equal(department.location_id, employee.location_id)
276
+ assert_equal(department, employee.department)
272
277
  end
273
278
 
274
279
  def test_has_many_with_primary_key
@@ -331,9 +336,11 @@ class TestAssociations < ActiveSupport::TestCase
331
336
  end
332
337
 
333
338
  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)
339
+ memberships = Membership.includes(:statuses).where("membership_statuses.status = ?", 'Active').references(:membership_statuses)
340
+ assert_equal(2, memberships.length)
341
+
336
342
  assert_equal([1,1], memberships[0].id)
343
+ assert_equal([3,2], memberships[1].id)
337
344
  end
338
345
 
339
346
  def test_foreign_key_present_with_null_association_ids
@@ -48,16 +48,21 @@ class TestCreate < ActiveSupport::TestCase
48
48
  end
49
49
  end
50
50
 
51
- # def test_create_generated_keys
52
- # # Not all databases support columns with multiple identity fields
53
- # if defined?(ActiveRecord::ConnectionAdapters::PostgreSQL) ||
54
- # defined?(ActiveRecord::ConnectionAdapters::SQLite3)
55
- #
56
- # suburb = Suburb.create!(:name => 'Capitol Hill')
57
- # refute_nil(suburb.city_id)
58
- # refute_nil(suburb.suburb_id)
59
- # end
60
- # end
51
+ def test_create_with_partial_serial
52
+ attributes = {:location_id => 100}
53
+
54
+ # SQLite does not support an autoincrementing field in a composite key
55
+ if Department.connection.class.name == "ActiveRecord::ConnectionAdapters::SQLite3Adapter"
56
+ attributes[:id] = 100
57
+ end
58
+
59
+ department = Department.new(attributes)
60
+ assert_nil(department.attributes[:id])
61
+
62
+ department.save!
63
+ refute_nil(department.attributes["id"])
64
+ assert_equal(100, department.location_id)
65
+ end
61
66
 
62
67
  def test_create_on_association
63
68
  suburb = Suburb.first
@@ -165,14 +170,6 @@ class TestCreate < ActiveSupport::TestCase
165
170
  assert_equal(assignment2, room.room_assignments[1])
166
171
  end
167
172
 
168
- def test_create_article_invalid_id
169
- error = assert_raises(ActiveRecord::RecordInvalid) do
170
- Article.create!(:id => 1)
171
- end
172
-
173
- assert_equal('Validation failed: Id has already been taken', error.to_s)
174
- end
175
-
176
173
  def test_find_or_create_by
177
174
  suburb = Suburb.find_by(:city_id => 3, :suburb_id => 1)
178
175
  assert_nil(suburb)
@@ -131,13 +131,13 @@ class TestDelete < ActiveSupport::TestCase
131
131
  def test_delete_not_destroy_on_cpk
132
132
  tariff = Tariff.where(tariff_id: 2).first
133
133
  tariff.delete
134
- assert !tariff.persisted?
134
+ refute(tariff.persisted?)
135
135
  end
136
136
 
137
137
  def test_delete_not_destroy_on_non_cpk
138
- article = Article.first
138
+ article = articles(:third)
139
139
  article.delete
140
- assert !article.persisted?
140
+ refute(article.persisted?)
141
141
  end
142
142
 
143
143
  def test_destroy_has_many_delete_all
@@ -1,11 +1,11 @@
1
1
  require File.expand_path('../abstract_unit', __FILE__)
2
2
 
3
3
  class TestExists < ActiveSupport::TestCase
4
- fixtures :articles, :departments, :capitols
4
+ fixtures :articles, :capitols, :departments, :dorms
5
5
 
6
6
  def test_id
7
- assert(Article.exists?(1))
8
- assert(!Article.exists?(-1))
7
+ assert(Dorm.exists?(1))
8
+ refute(Dorm.exists?(-1))
9
9
  end
10
10
 
11
11
  def test_array
@@ -29,8 +29,8 @@ class TestExists < ActiveSupport::TestCase
29
29
  end
30
30
 
31
31
  def test_cpk_array_condition
32
- assert(Department.exists?(['department_id = ? and location_id = ?', 1, 1]))
33
- assert(!Department.exists?(['department_id = ? and location_id = ?', 1, -1]))
32
+ assert(Department.exists?(['id = ? and location_id = ?', 1, 1]))
33
+ assert(!Department.exists?(['id = ? and location_id = ?', 1, -1]))
34
34
  end
35
35
 
36
36
  def test_cpk_array_string_id
@@ -59,7 +59,7 @@ class TestFind < ActiveSupport::TestCase
59
59
  end
60
60
 
61
61
  def test_find_each_with_scope
62
- scoped_departments = Department.where("department_id <> 3")
62
+ scoped_departments = Department.where("id <> 3")
63
63
  scoped_departments.find_each(:batch_size => 2) do |department|
64
64
  assert department.id != 3
65
65
  end
@@ -76,7 +76,7 @@ class TestFind < ActiveSupport::TestCase
76
76
 
77
77
  def test_find_last_suburb
78
78
  suburb = Suburb.last
79
- assert_equal([2,1], suburb.id)
79
+ assert_equal([2,2], suburb.id)
80
80
  end
81
81
 
82
82
  def test_find_last_suburb_with_order
@@ -133,9 +133,9 @@ class TestHabtm < ActiveSupport::TestCase
133
133
 
134
134
  # reload to force reload of associations
135
135
  product_one = Product.find(1)
136
- assert_equal 2, product_one.restaurants.size
136
+ assert_equal(2, product_one.restaurants.size)
137
137
 
138
138
  product_three = Product.find(3)
139
- assert_equal 0, product_three.restaurants.size
139
+ assert_equal(0, product_three.restaurants.size)
140
140
  end
141
141
  end
@@ -4,7 +4,7 @@ class ChildCpkTest < ReferenceCode
4
4
  end
5
5
 
6
6
  class TestIds < ActiveSupport::TestCase
7
- fixtures :reference_types, :reference_codes, :pk_called_ids
7
+ fixtures :reference_types, :reference_codes
8
8
 
9
9
  CLASSES = {
10
10
  :single => {
@@ -18,11 +18,7 @@ class TestIds < ActiveSupport::TestCase
18
18
  :dual_strs => {
19
19
  :class => ReferenceCode,
20
20
  :primary_keys => ['reference_type_id', 'reference_code'],
21
- },
22
- :pk_called_id => {
23
- :class => PkCalledId,
24
- :primary_keys => ['id', 'reference_code'],
25
- },
21
+ }
26
22
  }
27
23
 
28
24
  def setup
@@ -64,61 +64,4 @@ 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
- fixtures :topics, :topic_sources
69
-
70
- def test_nested_attributes_create_with_string_in_primary_key
71
- platform = 'instagram'
72
-
73
- topic = topics(:music)
74
- topic.update :topic_sources_attributes => [{
75
- :platform => platform,
76
- :keywords => 'funk'
77
- }]
78
- assert_not_nil TopicSource.find_by_platform(platform)
79
- end
80
-
81
- def test_nested_attributes_update_with_string_in_primary_key
82
- platform = 'instagram'
83
-
84
- topic = topics(:music)
85
- topic.update :topic_sources_attributes => [{
86
- :platform => platform,
87
- :keywords => 'funk'
88
- }]
89
- assert_not_nil TopicSource.find_by_platform(platform)
90
-
91
- topic_source = TopicSource.find_by_platform(platform)
92
- cpk = CompositePrimaryKeys::CompositeKeys[topic.id, platform]
93
- topic.update :topic_sources_attributes => [{
94
- :id => cpk,
95
- :keywords => 'jazz'
96
- }]
97
-
98
- topic_source = TopicSource.find_by_platform(platform)
99
- assert_kind_of(TopicSource, topic_source)
100
- assert_equal(topic_source.keywords, 'jazz')
101
- end
102
-
103
- def test_nested_attributes_update_with_string_in_primary_key_2
104
- topic = topics(:music)
105
- topic_source = topic_sources(:music_source)
106
-
107
- topic.update(:topic_sources_attributes => [{:id => topic_source.id,
108
- :keywords => 'classical, jazz'}])
109
-
110
- topic_source.reload
111
- assert_equal(topic_source.keywords, 'classical, jazz')
112
- end
113
-
114
- def test_nested_attributes_update_with_string_in_primary_key_3
115
- topic = topics(:music)
116
- topic_source = topic_sources(:music_source)
117
-
118
- topic.update(:topic_sources_attributes => [{:id => topic_source.id.to_s,
119
- :keywords => 'classical, jazz'}])
120
-
121
- topic_source.reload
122
- assert_equal(topic_source.keywords, 'classical, jazz')
123
- end
124
67
  end