composite_primary_keys 13.0.3 → 14.0.4
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 +4 -4
- data/History.rdoc +17 -0
- data/README.rdoc +1 -0
- data/lib/composite_primary_keys/associations/preloader/association.rb +15 -0
- data/lib/composite_primary_keys/autosave_association.rb +60 -60
- data/lib/composite_primary_keys/composite_predicates.rb +1 -0
- data/lib/composite_primary_keys/persistence.rb +21 -7
- data/lib/composite_primary_keys/relation/calculations.rb +7 -1
- data/lib/composite_primary_keys/version.rb +2 -2
- data/lib/composite_primary_keys.rb +1 -1
- data/test/abstract_unit.rb +5 -1
- data/test/fixtures/department.rb +4 -0
- data/test/test_associations.rb +10 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7f4289f2367e4fc8315bd9055e077e7daa2f3ca842bbb1c40e5755241379416
|
4
|
+
data.tar.gz: 5f247da837ba1da9f64ba23efaa9cbe9aade3f12f2f9c879736106b9c14570ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01fc103302338a90c5b914e3da13fab9bfa4ca1a8d37a5f182de3755e3893321094fc018dbda672351a43cda77a0c73ef00cb7a63adeafe5b8688335f26fed64
|
7
|
+
data.tar.gz: fb900706022a8d2ccfb4169e18292c6e412c9d20b1ccea6e3f25c83ddfbea993546605e34ea8addf152cd1a3f13133186a480253a3542e697e7324879bcc2662
|
data/History.rdoc
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
== 14.0.4 (2022-02-13)
|
2
|
+
* Fix for changed method in Rails 7.0.2 (Yota)
|
3
|
+
|
4
|
+
== 14.0.3 (2022-01-09)
|
5
|
+
* Remove override on ActiveRecord::Base#to_param. That method has moved to Integration
|
6
|
+
so no longer works. #541. (Charlie Savage)
|
7
|
+
* Check if an assocation is polymorhpic. Fixes #558.
|
8
|
+
|
9
|
+
== 14.0.2 (2022-01-09)
|
10
|
+
* Fix scoped associations take #2 (Charlie Savage)
|
11
|
+
|
12
|
+
== 14.0.1 (2022-01-9)
|
13
|
+
* Fix mistake in Gemfile (Charlie Savage)
|
14
|
+
|
15
|
+
== 14.0.0 (2022-01-9)
|
16
|
+
* Update to ActiveRecord 7.0 (Sammy Larbi)
|
17
|
+
|
1
18
|
== 13.0.3 (2022-01-09)
|
2
19
|
* Remove override on ActiveRecord::Base#to_param. That method has moved to Integration
|
3
20
|
so no longer works. #541. (Charlie Savage)
|
data/README.rdoc
CHANGED
@@ -20,6 +20,7 @@ Every major version of ActiveRecord has included numerous internal changes. As
|
|
20
20
|
CPK has to be rewritten for each version of ActiveRecord. To help keep
|
21
21
|
things straight, here is the mapping:
|
22
22
|
|
23
|
+
Version 14.x is designed to work with ActiveRecord 7.0.x
|
23
24
|
Version 13.x is designed to work with ActiveRecord 6.1.x
|
24
25
|
Version 12.x is designed to work with ActiveRecord 6.0.x
|
25
26
|
Version 11.x is designed to work with ActiveRecord 5.2.x
|
@@ -2,6 +2,20 @@ module ActiveRecord
|
|
2
2
|
module Associations
|
3
3
|
class Preloader
|
4
4
|
class Association
|
5
|
+
|
6
|
+
class LoaderQuery
|
7
|
+
def load_records_for_keys(keys, &block)
|
8
|
+
# CPK
|
9
|
+
if association_key_name.is_a?(Array)
|
10
|
+
predicate = cpk_in_predicate(scope.klass.arel_table, association_key_name, keys)
|
11
|
+
scope.where(predicate).load(&block)
|
12
|
+
else
|
13
|
+
scope.where(association_key_name => keys).load(&block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO: is records_for needed anymore? Rails' implementation has changed significantly
|
5
19
|
def records_for(ids)
|
6
20
|
records = if association_key_name.is_a?(Array)
|
7
21
|
predicate = cpk_in_predicate(klass.arel_table, association_key_name, ids)
|
@@ -33,6 +47,7 @@ module ActiveRecord
|
|
33
47
|
end
|
34
48
|
end
|
35
49
|
|
50
|
+
# TODO: is records_by_owner needed anymore? Rails' implementation has changed significantly
|
36
51
|
def records_by_owner
|
37
52
|
@records_by_owner ||= preloaded_records.each_with_object({}) do |record, result|
|
38
53
|
key = if association_key_name.is_a?(Array)
|
@@ -1,60 +1,60 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module AutosaveAssociation
|
3
|
-
def save_has_one_association(reflection)
|
4
|
-
association = association_instance_get(reflection.name)
|
5
|
-
record = association && association.load_target
|
6
|
-
|
7
|
-
if record && !record.destroyed?
|
8
|
-
autosave = reflection.options[:autosave]
|
9
|
-
|
10
|
-
if autosave && record.marked_for_destruction?
|
11
|
-
record.destroy
|
12
|
-
elsif autosave != false
|
13
|
-
# CPK
|
14
|
-
#key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
|
15
|
-
key = reflection.options[:primary_key] ? self[reflection.options[:primary_key]] : id
|
16
|
-
|
17
|
-
if (autosave && record.changed_for_autosave?) || new_record? ||
|
18
|
-
unless reflection.through_reflection
|
19
|
-
record[reflection.foreign_key] = key
|
20
|
-
if inverse_reflection = reflection.inverse_of
|
21
|
-
record.association(inverse_reflection.name).loaded!
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
saved = record.save(validate: !autosave)
|
26
|
-
raise ActiveRecord::Rollback if !saved && autosave
|
27
|
-
saved
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def save_belongs_to_association(reflection)
|
34
|
-
association = association_instance_get(reflection.name)
|
35
|
-
return unless association && association.loaded? && !association.stale_target?
|
36
|
-
|
37
|
-
record = association.load_target
|
38
|
-
if record && !record.destroyed?
|
39
|
-
autosave = reflection.options[:autosave]
|
40
|
-
|
41
|
-
if autosave && record.marked_for_destruction?
|
42
|
-
self[reflection.foreign_key] = nil
|
43
|
-
record.destroy
|
44
|
-
elsif autosave != false
|
45
|
-
saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
|
46
|
-
|
47
|
-
if association.updated?
|
48
|
-
# CPK
|
49
|
-
# association_id = record.send(reflection.options[:primary_key] || :id)
|
50
|
-
association_id = reflection.options[:primary_key] ? record[reflection.options[:primary_key]] : record.id
|
51
|
-
self[reflection.foreign_key] = association_id
|
52
|
-
association.loaded!
|
53
|
-
end
|
54
|
-
|
55
|
-
saved if autosave
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module AutosaveAssociation
|
3
|
+
def save_has_one_association(reflection)
|
4
|
+
association = association_instance_get(reflection.name)
|
5
|
+
record = association && association.load_target
|
6
|
+
|
7
|
+
if record && !record.destroyed?
|
8
|
+
autosave = reflection.options[:autosave]
|
9
|
+
|
10
|
+
if autosave && record.marked_for_destruction?
|
11
|
+
record.destroy
|
12
|
+
elsif autosave != false
|
13
|
+
# CPK
|
14
|
+
#key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
|
15
|
+
key = reflection.options[:primary_key] ? self[reflection.options[:primary_key]] : id
|
16
|
+
|
17
|
+
if (autosave && record.changed_for_autosave?) || new_record? || _record_changed?(reflection, record, key)
|
18
|
+
unless reflection.through_reflection
|
19
|
+
record[reflection.foreign_key] = key
|
20
|
+
if inverse_reflection = reflection.inverse_of
|
21
|
+
record.association(inverse_reflection.name).loaded!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
saved = record.save(validate: !autosave)
|
26
|
+
raise ActiveRecord::Rollback if !saved && autosave
|
27
|
+
saved
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def save_belongs_to_association(reflection)
|
34
|
+
association = association_instance_get(reflection.name)
|
35
|
+
return unless association && association.loaded? && !association.stale_target?
|
36
|
+
|
37
|
+
record = association.load_target
|
38
|
+
if record && !record.destroyed?
|
39
|
+
autosave = reflection.options[:autosave]
|
40
|
+
|
41
|
+
if autosave && record.marked_for_destruction?
|
42
|
+
self[reflection.foreign_key] = nil
|
43
|
+
record.destroy
|
44
|
+
elsif autosave != false
|
45
|
+
saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
|
46
|
+
|
47
|
+
if association.updated?
|
48
|
+
# CPK
|
49
|
+
# association_id = record.send(reflection.options[:primary_key] || :id)
|
50
|
+
association_id = reflection.options[:primary_key] ? record[reflection.options[:primary_key]] : record.id
|
51
|
+
self[reflection.foreign_key] = association_id
|
52
|
+
association.loaded!
|
53
|
+
end
|
54
|
+
|
55
|
+
saved if autosave
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -62,6 +62,7 @@ end
|
|
62
62
|
ActiveRecord::Associations::AssociationScope.send(:include, CompositePrimaryKeys::Predicates)
|
63
63
|
ActiveRecord::Associations::JoinDependency::JoinAssociation.send(:include, CompositePrimaryKeys::Predicates)
|
64
64
|
ActiveRecord::Associations::Preloader::Association.send(:include, CompositePrimaryKeys::Predicates)
|
65
|
+
ActiveRecord::Associations::Preloader::Association::LoaderQuery.send(:include, CompositePrimaryKeys::Predicates)
|
65
66
|
ActiveRecord::Associations::HasManyAssociation.send(:include, CompositePrimaryKeys::Predicates)
|
66
67
|
ActiveRecord::Associations::HasManyThroughAssociation.send(:include, CompositePrimaryKeys::Predicates)
|
67
68
|
ActiveRecord::Base.send(:extend, CompositePrimaryKeys::Predicates)
|
@@ -30,11 +30,18 @@ module ActiveRecord
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
constraints =
|
33
|
+
constraints = constraints.map { |name, value| predicate_builder[name, value] }
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
default_constraint = build_default_constraint
|
36
|
+
constraints << default_constraint if default_constraint
|
37
|
+
|
38
|
+
if current_scope = self.global_current_scope
|
39
|
+
constraints << current_scope.where_clause.ast
|
40
|
+
end
|
41
|
+
|
42
|
+
um = Arel::UpdateManager.new(arel_table)
|
43
|
+
um.set(values.transform_keys { |name| arel_table[name] })
|
44
|
+
um.wheres = constraints
|
38
45
|
|
39
46
|
connection.update(um, "#{self} Update")
|
40
47
|
end
|
@@ -48,10 +55,16 @@ module ActiveRecord
|
|
48
55
|
end
|
49
56
|
end
|
50
57
|
|
51
|
-
constraints =
|
58
|
+
constraints = constraints.map { |name, value| predicate_builder[name, value] }
|
59
|
+
|
60
|
+
default_constraint = build_default_constraint
|
61
|
+
constraints << default_constraint if default_constraint
|
62
|
+
|
63
|
+
if current_scope = self.global_current_scope
|
64
|
+
constraints << current_scope.where_clause.ast
|
65
|
+
end
|
52
66
|
|
53
|
-
dm = Arel::DeleteManager.new
|
54
|
-
dm.from(arel_table)
|
67
|
+
dm = Arel::DeleteManager.new(arel_table)
|
55
68
|
dm.wheres = constraints
|
56
69
|
|
57
70
|
connection.delete(dm, "#{self} Destroy")
|
@@ -73,6 +86,7 @@ module ActiveRecord
|
|
73
86
|
end
|
74
87
|
|
75
88
|
@new_record = false
|
89
|
+
@previously_new_record = true
|
76
90
|
|
77
91
|
yield(self) if block_given?
|
78
92
|
|
@@ -42,7 +42,13 @@ module CompositePrimaryKeys
|
|
42
42
|
|
43
43
|
result = skip_query_cache_if_necessary { @klass.connection.select_all(query_builder) }
|
44
44
|
|
45
|
-
|
45
|
+
if operation != "count"
|
46
|
+
type = column.try(:type_caster) ||
|
47
|
+
lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value
|
48
|
+
type = type.subtype if ::ActiveRecord::Enum::EnumType === type
|
49
|
+
end
|
50
|
+
|
51
|
+
type_cast_calculated_value(result.cast_values.first, operation, type) do |value|
|
46
52
|
type = column.try(:type_caster) ||
|
47
53
|
# CPK
|
48
54
|
# lookup_cast_type_from_join_dependencies(column_name.to_s) || Type.default_value
|
data/test/abstract_unit.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
spec_name = ENV['ADAPTER'] || '
|
1
|
+
spec_name = ENV['ADAPTER'] || 'postgresql'
|
2
2
|
require 'bundler'
|
3
3
|
require 'minitest/autorun'
|
4
4
|
|
@@ -21,6 +21,10 @@ ActiveRecord::Base.configurations = {test: spec}
|
|
21
21
|
|
22
22
|
# Tell ActiveRecord where to find models
|
23
23
|
ActiveSupport::Dependencies.autoload_paths << File.join(PROJECT_ROOT, 'test', 'fixtures')
|
24
|
+
Dir[File.join(PROJECT_ROOT, 'test', 'fixtures', '*.rb')].each do |file_path|
|
25
|
+
require_file = file_path.sub(PROJECT_ROOT, '..').sub('.rb', '')
|
26
|
+
require_relative require_file
|
27
|
+
end
|
24
28
|
|
25
29
|
I18n.config.enforce_available_locales = true
|
26
30
|
|
data/test/fixtures/department.rb
CHANGED
@@ -13,4 +13,8 @@ class Department < ActiveRecord::Base
|
|
13
13
|
:primary_key => [:id, :location_id],
|
14
14
|
:foreign_key => [:department_id, :location_id]
|
15
15
|
|
16
|
+
has_one :head_without_autosave, :class_name => 'Employee',
|
17
|
+
# We intentionally redefine primary key for test purposes. #455
|
18
|
+
:primary_key => [:id, :location_id],
|
19
|
+
:foreign_key => [:department_id, :location_id]
|
16
20
|
end
|
data/test/test_associations.rb
CHANGED
@@ -124,6 +124,15 @@ class TestAssociations < ActiveSupport::TestCase
|
|
124
124
|
assert_equal('Sarah1', department.head.name)
|
125
125
|
end
|
126
126
|
|
127
|
+
def test_has_no_autosave
|
128
|
+
department = departments(:engineering)
|
129
|
+
assert_equal('Sarah', department.head_without_autosave.name)
|
130
|
+
|
131
|
+
department.head_without_autosave.name = 'Sarah1'
|
132
|
+
department.save!
|
133
|
+
assert_equal('Sarah1', department.head_without_autosave.name)
|
134
|
+
end
|
135
|
+
|
127
136
|
def test_has_many_association_is_not_cached_to_where_it_returns_the_wrong_ones
|
128
137
|
engineering = departments(:engineering)
|
129
138
|
engineering_employees = engineering.employees
|
@@ -343,7 +352,7 @@ class TestAssociations < ActiveSupport::TestCase
|
|
343
352
|
assert_equal([3,2], memberships[1].id)
|
344
353
|
end
|
345
354
|
|
346
|
-
def
|
355
|
+
def test_scoped_has_many_with_primary_key_with_associations
|
347
356
|
memberships = Membership.joins(:active_statuses)
|
348
357
|
assert_equal(2, memberships.length)
|
349
358
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composite_primary_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 14.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Savage
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 7.0.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 7.0.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -209,7 +209,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
209
209
|
requirements:
|
210
210
|
- - ">="
|
211
211
|
- !ruby/object:Gem::Version
|
212
|
-
version: 2.
|
212
|
+
version: 2.7.0
|
213
213
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
214
214
|
requirements:
|
215
215
|
- - ">="
|