composite_primary_keys 13.0.8 → 13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8604d48445aede0e7f6d39ad32090ea2ed0f8d7cd58ab633a3d0c013ee1ab3b8
4
- data.tar.gz: a71f857e9125065b7c635170c341ce4a9285f6942c8989dac9cfa201f428a062
3
+ metadata.gz: 7a669eb0a0494f42052831fcbe76de73b149c431ab64e8544e4e16770629379f
4
+ data.tar.gz: 022bd9e17155073ee11a6f2a4fd082771a9bd58d3a58e53e73283b5b7d3c76f1
5
5
  SHA512:
6
- metadata.gz: fb13f66165419e9ca60e9b1b3283ff174947d3d2d07d1b7e29a62cb0feae97bbe5abc3179d41f330f76d2837d27c837875a01039f1c9e2969769293c4617b7d2
7
- data.tar.gz: 14790bef238c5f4e6360a5613db1bd22e3333bc06a062bc6047212b077d02828bb6d1acdda436f8a4106bc1e82dc6fe4ef96d2e05f5f3dd72beb86bf0c4ae0a1
6
+ metadata.gz: b437679d051728600686978837e23b0835031c3ad9702506d172636d3a47d06d2653d68e5c8fcb3934e50b87cb61b8df852be8039ce1a0dcd8aef1dee6cfae0b
7
+ data.tar.gz: 8ac2b3d595ee688434c9d0e38b262292f0fd6fa15854c6538e97d834bab0ae81e7edb1e3bfcaa12d1a63ae0dcc8d4d29bab6382fa762397522e4685f8a0ea194
data/History.rdoc CHANGED
@@ -1,3 +1,7 @@
1
+ == 13.0.8 (2024-12-19)
2
+ * Fix `update_all` to update loaded associations (Piotr Kowalski)
3
+ * Fix object comparison for models with composite keys (Piotr Kowalski)
4
+
1
5
  == 13.0.8 (2023-11-24)
2
6
  Fix `polymorphic_name` support (Vladimir Kochnev)
3
7
 
@@ -16,6 +16,29 @@ module ActiveRecord
16
16
  super
17
17
  end
18
18
 
19
+ def primary_key_values_present?
20
+ if self.composite?
21
+ id.all? {|key| !key.nil?}
22
+ else
23
+ !id.nil?
24
+ end
25
+ end
26
+
27
+ def ==(comparison_object)
28
+ super ||
29
+ comparison_object.instance_of?(self.class) &&
30
+ primary_key_values_present? &&
31
+ comparison_object.id == id
32
+ end
33
+
34
+ def hash
35
+ if primary_key_values_present?
36
+ self.class.hash ^ id.hash
37
+ else
38
+ super
39
+ end
40
+ end
41
+
19
42
  module ClassMethods
20
43
  def find(*ids) # :nodoc:
21
44
  # We don't have cache keys for this stuff yet
@@ -19,23 +19,22 @@ module ActiveRecord
19
19
  def update_all(updates)
20
20
  raise ArgumentError, "Empty list of attributes to change" if updates.blank?
21
21
 
22
- if eager_loading?
23
- relation = apply_join_dependency
24
- return relation.update_all(updates)
25
- end
22
+ arel = eager_loading? ? apply_join_dependency.arel : build_arel
23
+ arel.source.left = table
26
24
 
27
25
  stmt = Arel::UpdateManager.new
28
- stmt.table(arel.join_sources.empty? ? table : arel.source)
26
+ stmt.table(arel.source)
29
27
  stmt.key = table[primary_key]
30
28
 
31
29
  # CPK
32
- if @klass.composite?
30
+ if klass.composite?
33
31
  stmt = Arel::UpdateManager.new
34
32
  stmt.table(arel_table)
35
33
  cpk_subquery(stmt)
36
34
  else
37
35
  stmt.wheres = arel.constraints
38
36
  end
37
+
39
38
  stmt.take(arel.limit)
40
39
  stmt.offset(arel.offset)
41
40
  stmt.order(*arel.orders)
@@ -52,7 +51,7 @@ module ActiveRecord
52
51
  stmt.set Arel.sql(klass.sanitize_sql_for_assignment(updates, table.name))
53
52
  end
54
53
 
55
- @klass.connection.update stmt, "#{@klass} Update All"
54
+ klass.connection.update(stmt, "#{klass} Update All").tap { reset }
56
55
  end
57
56
 
58
57
  def delete_all
@@ -64,17 +63,15 @@ module ActiveRecord
64
63
  raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
65
64
  end
66
65
 
67
- if eager_loading?
68
- relation = apply_join_dependency
69
- return relation.delete_all
70
- end
66
+ arel = eager_loading? ? apply_join_dependency.arel : build_arel
67
+ arel.source.left = table
71
68
 
72
69
  stmt = Arel::DeleteManager.new
73
- stmt.from(arel.join_sources.empty? ? table : arel.source)
70
+ stmt.from(arel.source)
74
71
  stmt.key = table[primary_key]
75
72
 
76
73
  # CPK
77
- if @klass.composite?
74
+ if klass.composite?
78
75
  stmt = Arel::DeleteManager.new
79
76
  stmt.from(arel_table)
80
77
  cpk_subquery(stmt)
@@ -86,7 +83,7 @@ module ActiveRecord
86
83
  stmt.offset(arel.offset)
87
84
  stmt.order(*arel.orders)
88
85
 
89
- affected = @klass.connection.delete(stmt, "#{@klass} Destroy")
86
+ affected = klass.connection.delete(stmt, "#{klass} Destroy")
90
87
 
91
88
  reset
92
89
  affected
@@ -2,7 +2,7 @@ module CompositePrimaryKeys
2
2
  module VERSION
3
3
  MAJOR = 13
4
4
  MINOR = 0
5
- TINY = 8
5
+ TINY = 9
6
6
  STRING = [MAJOR, MINOR, TINY].join('.')
7
7
  end
8
8
  end
data/test/test_equal.rb CHANGED
@@ -1,26 +1,55 @@
1
1
  require File.expand_path('../abstract_unit', __FILE__)
2
2
 
3
3
  class TestEqual < ActiveSupport::TestCase
4
- fixtures :capitols
4
+ fixtures :restaurants, :products
5
5
 
6
- def test_new
7
- assert_equal(Capitol.new, Capitol.new)
6
+ ############################################################
7
+ ### Tests for Product model with single primary key (id) ###
8
+ ############################################################
9
+
10
+ def test_single_same
11
+ first = Product.find(1)
12
+ second = Product.find(1)
13
+ assert_equal(first, second)
14
+ end
15
+
16
+ def test_different
17
+ first = Product.find(1)
18
+ second = Product.find(2)
19
+ assert_not_equal(first, second)
20
+ end
21
+
22
+ def test_two_new_objects_are_not_equal
23
+ assert_not_equal(Product.new, Product.new)
8
24
  end
9
25
 
10
- def test_same_new
11
- it = Capitol.new
26
+ def test_same_new_object_is_equal_to_itself
27
+ it = Product.new
12
28
  assert_equal(it, it)
13
29
  end
14
30
 
15
- def test_same
16
- first = Capitol.find(['Canada', 'Ottawa'])
17
- second = Capitol.find(['Canada', 'Ottawa'])
31
+ #####################################################################################
32
+ ### Tests for Restaurant model with composite primary key (franchise_id, store_id) ##
33
+ #####################################################################################
34
+
35
+ def test_composite_same
36
+ first = Restaurant.find([1, 1])
37
+ second = Restaurant.find([1, 1])
18
38
  assert_equal(first, second)
19
39
  end
20
40
 
21
- def test_different
22
- first = Capitol.find(['Mexico', 'Mexico City'])
23
- second = Capitol.find(['Canada', 'Ottawa'])
41
+ def test_composite_different
42
+ first = Restaurant.find([1, 1])
43
+ second = Restaurant.find([2, 2])
24
44
  assert_not_equal(first, second)
25
45
  end
46
+
47
+ def test_composite_two_new_objects_are_not_equal
48
+ assert_not_equal(Restaurant.new, Restaurant.new)
49
+ end
50
+
51
+ def test_composite_same_new_object_is_equal_to_itself
52
+ it = Restaurant.new
53
+ assert_equal(it, it)
54
+ end
26
55
  end
data/test/test_hash.rb ADDED
@@ -0,0 +1,73 @@
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestHash < ActiveSupport::TestCase
4
+ fixtures :restaurants, :products
5
+
6
+ ############################################################
7
+ ### Tests for Product model with single primary key (id) ###
8
+ ############################################################
9
+
10
+ def test_single_same_object_has_the_same_hash
11
+ first = Product.find(1)
12
+ second = Product.find(1)
13
+ assert_equal(first.hash, second.hash)
14
+ end
15
+
16
+ def test_single_different_objects_have_different_hashes
17
+ first = Product.find(1)
18
+ second = Product.find(2)
19
+ assert_not_equal(first.hash, second.hash)
20
+ end
21
+
22
+ def test_single_persisted_object_hash_is_based_on_primary_key
23
+ first = Product.find(1)
24
+ second = Product.find(1)
25
+
26
+ assert_equal(first.hash, second.hash)
27
+ first.name = 'new name'
28
+ assert_equal(first.hash, second.hash)
29
+ end
30
+
31
+ def test_single_two_new_objects_have_different_hashes
32
+ assert_not_equal(Product.new.hash, Product.new.hash)
33
+ end
34
+
35
+ def test_single_same_new_object_has_the_same_hash
36
+ it = Product.new
37
+ assert_equal(it.hash, it.hash)
38
+ end
39
+
40
+ #####################################################################################
41
+ ### Tests for Restaurant model with composite primary key (franchise_id, store_id) ##
42
+ #####################################################################################
43
+
44
+ def test_composite_same_object_has_the_same_hash
45
+ first = Restaurant.find([1, 1])
46
+ second = Restaurant.find([1, 1])
47
+ assert_equal(first.hash, second.hash)
48
+ end
49
+
50
+ def test_composite_different_objects_have_different_hashes
51
+ first = Restaurant.find([1, 1])
52
+ second = Restaurant.find([2, 2])
53
+ assert_not_equal(first.hash, second.hash)
54
+ end
55
+
56
+ def test_composite_persisted_object_hash_is_based_on_primary_key
57
+ first = Restaurant.find([1, 1])
58
+ second = Restaurant.find([1, 1])
59
+
60
+ assert_equal(first.hash, second.hash)
61
+ first.name = 'new name'
62
+ assert_equal(first.hash, second.hash)
63
+ end
64
+
65
+ def test_composite_two_new_objects_have_different_hashes
66
+ assert_not_equal(Restaurant.new.hash, Restaurant.new.hash)
67
+ end
68
+
69
+ def test_composite_same_new_object_has_the_same_hash
70
+ it = Restaurant.new
71
+ assert_equal(it.hash, it.hash)
72
+ end
73
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestRelation < ActiveSupport::TestCase
4
+ fixtures :users, :readings
5
+
6
+ def test_update_all_updates_db_records
7
+ user = User.find(1)
8
+ assert_equal [4, 5], user.readings.map(&:rating)
9
+
10
+ user.readings.update_all(rating: 3)
11
+
12
+ # Reload to check that the records were updated in the DB
13
+ user.readings.reload
14
+ assert_equal [3, 3], user.readings.map(&:rating)
15
+ end
16
+
17
+ def test_update_all_updates_loaded_association
18
+ user = User.find(1)
19
+ assert_equal [4, 5], user.readings.map(&:rating)
20
+
21
+ user.readings.update_all(rating: 3)
22
+
23
+ # No reload to check that not only the records were updated in the DB
24
+ # but also in the loaded association
25
+ assert_equal [3, 3], user.readings.map(&:rating)
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composite_primary_keys
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.0.8
4
+ version: 13.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charlie Savage
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-11-24 00:00:00.000000000 Z
10
+ date: 2024-12-19 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activerecord
@@ -39,7 +38,6 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
40
  description: Composite key support for ActiveRecord
42
- email:
43
41
  executables: []
44
42
  extensions: []
45
43
  extra_rdoc_files: []
@@ -184,6 +182,7 @@ files:
184
182
  - test/test_exists.rb
185
183
  - test/test_find.rb
186
184
  - test/test_habtm.rb
185
+ - test/test_hash.rb
187
186
  - test/test_ids.rb
188
187
  - test/test_miscellaneous.rb
189
188
  - test/test_nested_attributes.rb
@@ -192,6 +191,7 @@ files:
192
191
  - test/test_polymorphic.rb
193
192
  - test/test_predicates.rb
194
193
  - test/test_preload.rb
194
+ - test/test_relation.rb
195
195
  - test/test_santiago.rb
196
196
  - test/test_serialize.rb
197
197
  - test/test_touch.rb
@@ -202,7 +202,6 @@ homepage: https://github.com/composite-primary-keys/composite_primary_keys
202
202
  licenses:
203
203
  - MIT
204
204
  metadata: {}
205
- post_install_message:
206
205
  rdoc_options: []
207
206
  require_paths:
208
207
  - lib
@@ -217,8 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
216
  - !ruby/object:Gem::Version
218
217
  version: '0'
219
218
  requirements: []
220
- rubygems_version: 3.4.21
221
- signing_key:
219
+ rubygems_version: 3.6.1
222
220
  specification_version: 4
223
221
  summary: Composite key support for ActiveRecord
224
222
  test_files:
@@ -239,6 +237,7 @@ test_files:
239
237
  - test/test_exists.rb
240
238
  - test/test_find.rb
241
239
  - test/test_habtm.rb
240
+ - test/test_hash.rb
242
241
  - test/test_ids.rb
243
242
  - test/test_miscellaneous.rb
244
243
  - test/test_nested_attributes.rb
@@ -247,6 +246,7 @@ test_files:
247
246
  - test/test_polymorphic.rb
248
247
  - test/test_predicates.rb
249
248
  - test/test_preload.rb
249
+ - test/test_relation.rb
250
250
  - test/test_santiago.rb
251
251
  - test/test_serialize.rb
252
252
  - test/test_touch.rb