composite_primary_keys 13.0.2 → 13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eeb7ac69a866392d1d19aec7ae67f99af052e72e5585375c2cb73990f442cc28
4
- data.tar.gz: 6552f1e74d6ab9a40aadd66ea78e8d6c489e6d793a47cc52ab2582f60dfbced7
3
+ metadata.gz: 875a5dc3886b5b887bbcb77bdcb0bfa40ad377e5084fd1bcdf3a71b5c226dbc3
4
+ data.tar.gz: 9cad15004b91f80917564f623855836217c2ce8e745eb5e6fc47464f10c7cf0c
5
5
  SHA512:
6
- metadata.gz: 1b0bd53df9177d3569e4646124ff2aaf6bacf4d83a78f287a9e954ed388a37ed4872f4024204e34f7402b7989b401586c53636a551d745e5aaf4871927bb66fb
7
- data.tar.gz: 8c2eacaaff041c6c4255aed0402f63038d6e0d781665208cbb9b3bdbcc86666087f69822400384f9dfc44215c23be46ddc1c3c69b7ee0008db636d8ff1e0a29c
6
+ metadata.gz: f771c6c4266eb770f685c7fc0960c344c10b7666a24240c59b456afa2c4c52c058e530e8e3d1ddfb4575468eb5eaf30a77b141216820eb028d774fc9f9593326
7
+ data.tar.gz: 33d2e087cdfc10ea336038a5ffabdb5dd878133ba11ed874ee2d6bd7cf5e572f9acf8b3a996bf04b402c161ffe49d2237ae7284266b58e6eed98b53a890ca7e5
data/History.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ == 13.0.4
2
+ * Fix previously_new_record? not being set to true after create
3
+
4
+ == 13.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
+
1
9
  == 13.0.2 (2022-01-09)
2
10
  * Fix scoped associations take #2 (Charlie Savage)
3
11
 
@@ -1,32 +1,32 @@
1
- module CompositePrimaryKeys
2
- module CollectionAssociation
3
- def ids_writer(ids)
4
- primary_key = reflection.association_primary_key
5
- pk_type = klass.type_for_attribute(primary_key)
6
- ids = Array(ids).reject(&:blank?)
7
- ids.map! { |i| pk_type.cast(i) }
8
-
9
- # CPK-
10
- if primary_key.is_a?(Array)
11
- predicate = CompositePrimaryKeys::Predicates.cpk_in_predicate(klass.arel_table, reflection.association_primary_key, ids)
12
- records = klass.where(predicate).index_by do |r|
13
- reflection.association_primary_key.map{ |k| r.send(k) }
14
- end.values_at(*ids)
15
- else
16
- records = klass.where(primary_key => ids).index_by do |r|
17
- r.public_send(primary_key)
18
- end.values_at(*ids).compact
19
- end
20
-
21
- if records.size != ids.size
22
- found_ids = records.map { |record| record.public_send(primary_key) }
23
- not_found_ids = ids - found_ids
24
- klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key, not_found_ids)
25
- else
26
- replace(records)
27
- end
28
- end
29
- end
30
- end
31
-
1
+ module CompositePrimaryKeys
2
+ module CollectionAssociation
3
+ def ids_writer(ids)
4
+ primary_key = reflection.association_primary_key
5
+ pk_type = klass.type_for_attribute(primary_key)
6
+ ids = Array(ids).reject(&:blank?)
7
+ ids.map! { |i| pk_type.cast(i) }
8
+
9
+ # CPK-
10
+ if primary_key.is_a?(Array)
11
+ predicate = CompositePrimaryKeys::Predicates.cpk_in_predicate(klass.arel_table, reflection.association_primary_key, ids)
12
+ records = klass.where(predicate).index_by do |r|
13
+ reflection.association_primary_key.map{ |k| r.send(k) }
14
+ end.values_at(*ids)
15
+ else
16
+ records = klass.where(primary_key => ids).index_by do |r|
17
+ r.public_send(primary_key)
18
+ end.values_at(*ids).compact
19
+ end
20
+
21
+ if records.size != ids.size
22
+ found_ids = records.map { |record| record.public_send(primary_key) }
23
+ not_found_ids = ids - found_ids
24
+ klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key, not_found_ids)
25
+ else
26
+ replace(records)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
32
  ActiveRecord::Associations::CollectionAssociation.prepend CompositePrimaryKeys::CollectionAssociation
@@ -1,137 +1,137 @@
1
- module ActiveRecord
2
- module Associations
3
- class JoinDependency
4
-
5
- class JoinAssociation < JoinPart # :nodoc:
6
- private
7
- def append_constraints(join, constraints)
8
- if join.is_a?(Arel::Nodes::StringJoin)
9
- join_string = Arel::Nodes::And.new(constraints.unshift join.left)
10
- join.left = Arel.sql(base_klass.connection.visitor.compile(join_string))
11
- else
12
- right = join.right
13
- # CPK
14
- if right.expr.is_a?(Arel::Nodes::And) && right.expr.children.empty?
15
- right.expr = Arel::Nodes::And.new(constraints)
16
- else
17
- right.expr = Arel::Nodes::And.new(constraints.unshift right.expr)
18
- end
19
- end
20
- end
21
- end
22
-
23
- class Aliases # :nodoc:
24
- def column_alias(node, column)
25
- # CPK
26
- #@alias_cache[node][column]
27
- if column.kind_of?(Array)
28
- column.map do |a_column|
29
- @alias_cache[node][a_column]
30
- end
31
- else
32
- @alias_cache[node][column]
33
- end
34
- end
35
- end
36
-
37
- def instantiate(result_set, strict_loading_value, &block)
38
- primary_key = aliases.column_alias(join_root, join_root.primary_key)
39
-
40
- seen = Hash.new { |i, parent|
41
- i[parent] = Hash.new { |j, child_class|
42
- j[child_class] = {}
43
- }
44
- }.compare_by_identity
45
-
46
- model_cache = Hash.new { |h, klass| h[klass] = {} }
47
- parents = model_cache[join_root]
48
-
49
- column_aliases = aliases.column_aliases(join_root)
50
- column_names = []
51
-
52
- result_set.columns.each do |name|
53
- column_names << name unless /\At\d+_r\d+\z/.match?(name)
54
- end
55
-
56
- if column_names.empty?
57
- column_types = {}
58
- else
59
- column_types = result_set.column_types
60
- unless column_types.empty?
61
- attribute_types = join_root.attribute_types
62
- column_types = column_types.slice(*column_names).delete_if { |k, _| attribute_types.key?(k) }
63
- end
64
- column_aliases += column_names.map! { |name| Aliases::Column.new(name, name) }
65
- end
66
-
67
- message_bus = ActiveSupport::Notifications.instrumenter
68
-
69
- payload = {
70
- record_count: result_set.length,
71
- class_name: join_root.base_klass.name
72
- }
73
-
74
- message_bus.instrument("instantiation.active_record", payload) do
75
- result_set.each { |row_hash|
76
- # CPK
77
- # parent_key = primary_key ? row_hash[primary_key] : row_hash
78
- parent_key = if primary_key.kind_of?(Array)
79
- primary_key.map {|key| row_hash[key]}
80
- else
81
- primary_key ? row_hash[primary_key] : row_hash
82
- end
83
-
84
- parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, column_types, &block)
85
- construct(parent, join_root, row_hash, seen, model_cache, strict_loading_value)
86
- }
87
- end
88
-
89
- parents.values
90
- end
91
-
92
- def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
93
- return if ar_parent.nil?
94
-
95
- parent.children.each do |node|
96
- if node.reflection.collection?
97
- other = ar_parent.association(node.reflection.name)
98
- other.loaded!
99
- elsif ar_parent.association_cached?(node.reflection.name)
100
- model = ar_parent.association(node.reflection.name).target
101
- construct(model, node, row, seen, model_cache, strict_loading_value)
102
- next
103
- end
104
-
105
- key = aliases.column_alias(node, node.primary_key)
106
- # CPK
107
- if key.is_a?(Array)
108
- id = Array(key).map do |column_alias|
109
- row[column_alias]
110
- end
111
- # At least the first value in the key has to be set. Should we require all values to be set?
112
- id = nil if id.first.nil?
113
- else # original
114
- id = row[key]
115
- end
116
-
117
- if id.nil?
118
- nil_association = ar_parent.association(node.reflection.name)
119
- nil_association.loaded!
120
- next
121
- end
122
-
123
- model = seen[ar_parent][node][id]
124
-
125
- if model
126
- construct(model, node, row, seen, model_cache, strict_loading_value)
127
- else
128
- model = construct_model(ar_parent, node, row, model_cache, id, strict_loading_value)
129
-
130
- seen[ar_parent][node][id] = model
131
- construct(model, node, row, seen, model_cache, strict_loading_value)
132
- end
133
- end
134
- end
135
- end
136
- end
137
- end
1
+ module ActiveRecord
2
+ module Associations
3
+ class JoinDependency
4
+
5
+ class JoinAssociation < JoinPart # :nodoc:
6
+ private
7
+ def append_constraints(join, constraints)
8
+ if join.is_a?(Arel::Nodes::StringJoin)
9
+ join_string = Arel::Nodes::And.new(constraints.unshift join.left)
10
+ join.left = Arel.sql(base_klass.connection.visitor.compile(join_string))
11
+ else
12
+ right = join.right
13
+ # CPK
14
+ if right.expr.is_a?(Arel::Nodes::And) && right.expr.children.empty?
15
+ right.expr = Arel::Nodes::And.new(constraints)
16
+ else
17
+ right.expr = Arel::Nodes::And.new(constraints.unshift right.expr)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Aliases # :nodoc:
24
+ def column_alias(node, column)
25
+ # CPK
26
+ #@alias_cache[node][column]
27
+ if column.kind_of?(Array)
28
+ column.map do |a_column|
29
+ @alias_cache[node][a_column]
30
+ end
31
+ else
32
+ @alias_cache[node][column]
33
+ end
34
+ end
35
+ end
36
+
37
+ def instantiate(result_set, strict_loading_value, &block)
38
+ primary_key = aliases.column_alias(join_root, join_root.primary_key)
39
+
40
+ seen = Hash.new { |i, parent|
41
+ i[parent] = Hash.new { |j, child_class|
42
+ j[child_class] = {}
43
+ }
44
+ }.compare_by_identity
45
+
46
+ model_cache = Hash.new { |h, klass| h[klass] = {} }
47
+ parents = model_cache[join_root]
48
+
49
+ column_aliases = aliases.column_aliases(join_root)
50
+ column_names = []
51
+
52
+ result_set.columns.each do |name|
53
+ column_names << name unless /\At\d+_r\d+\z/.match?(name)
54
+ end
55
+
56
+ if column_names.empty?
57
+ column_types = {}
58
+ else
59
+ column_types = result_set.column_types
60
+ unless column_types.empty?
61
+ attribute_types = join_root.attribute_types
62
+ column_types = column_types.slice(*column_names).delete_if { |k, _| attribute_types.key?(k) }
63
+ end
64
+ column_aliases += column_names.map! { |name| Aliases::Column.new(name, name) }
65
+ end
66
+
67
+ message_bus = ActiveSupport::Notifications.instrumenter
68
+
69
+ payload = {
70
+ record_count: result_set.length,
71
+ class_name: join_root.base_klass.name
72
+ }
73
+
74
+ message_bus.instrument("instantiation.active_record", payload) do
75
+ result_set.each { |row_hash|
76
+ # CPK
77
+ # parent_key = primary_key ? row_hash[primary_key] : row_hash
78
+ parent_key = if primary_key.kind_of?(Array)
79
+ primary_key.map {|key| row_hash[key]}
80
+ else
81
+ primary_key ? row_hash[primary_key] : row_hash
82
+ end
83
+
84
+ parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, column_types, &block)
85
+ construct(parent, join_root, row_hash, seen, model_cache, strict_loading_value)
86
+ }
87
+ end
88
+
89
+ parents.values
90
+ end
91
+
92
+ def construct(ar_parent, parent, row, seen, model_cache, strict_loading_value)
93
+ return if ar_parent.nil?
94
+
95
+ parent.children.each do |node|
96
+ if node.reflection.collection?
97
+ other = ar_parent.association(node.reflection.name)
98
+ other.loaded!
99
+ elsif ar_parent.association_cached?(node.reflection.name)
100
+ model = ar_parent.association(node.reflection.name).target
101
+ construct(model, node, row, seen, model_cache, strict_loading_value)
102
+ next
103
+ end
104
+
105
+ key = aliases.column_alias(node, node.primary_key)
106
+ # CPK
107
+ if key.is_a?(Array)
108
+ id = Array(key).map do |column_alias|
109
+ row[column_alias]
110
+ end
111
+ # At least the first value in the key has to be set. Should we require all values to be set?
112
+ id = nil if id.first.nil?
113
+ else # original
114
+ id = row[key]
115
+ end
116
+
117
+ if id.nil?
118
+ nil_association = ar_parent.association(node.reflection.name)
119
+ nil_association.loaded!
120
+ next
121
+ end
122
+
123
+ model = seen[ar_parent][node][id]
124
+
125
+ if model
126
+ construct(model, node, row, seen, model_cache, strict_loading_value)
127
+ else
128
+ model = construct_model(ar_parent, node, row, model_cache, id, strict_loading_value)
129
+
130
+ seen[ar_parent][node][id] = model
131
+ construct(model, node, row, seen, model_cache, strict_loading_value)
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -1,25 +1,24 @@
1
- module ActiveRecord
2
- module Associations
3
- module ThroughAssociation
4
- alias :original_construct_join_attributes :construct_join_attributes
5
-
6
- def construct_join_attributes(*records)
7
- # CPK
8
- is_composite = self.source_reflection.polymorphic? ? source_reflection.active_record.composite? : source_reflection.klass.composite?
9
- if is_composite
10
- ensure_mutable
11
-
12
- ids = records.map do |record|
13
- source_reflection.association_primary_key(reflection.klass).map do |key|
14
- record.send(key)
15
- end
16
- end
17
-
18
- cpk_in_predicate(through_association.scope.klass.arel_table, source_reflection.foreign_key, ids)
19
- else
20
- original_construct_join_attributes(*records)
21
- end
22
- end
23
- end
24
- end
25
- end
1
+ module ActiveRecord
2
+ module Associations
3
+ module ThroughAssociation
4
+ alias :original_construct_join_attributes :construct_join_attributes
5
+
6
+ def construct_join_attributes(*records)
7
+ # CPK
8
+ if !self.source_reflection.polymorphic? && source_reflection.klass.composite?
9
+ ensure_mutable
10
+
11
+ ids = records.map do |record|
12
+ source_reflection.association_primary_key(reflection.klass).map do |key|
13
+ record.send(key)
14
+ end
15
+ end
16
+
17
+ cpk_in_predicate(through_association.scope.klass.arel_table, source_reflection.foreign_key, ids)
18
+ else
19
+ original_construct_join_attributes(*records)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -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? || 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
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