composite_primary_keys 7.0.13 → 7.0.14
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 +615 -608
- data/lib/composite_primary_keys.rb +110 -110
- data/lib/composite_primary_keys/associations/association.rb +23 -23
- data/lib/composite_primary_keys/associations/association_scope.rb +77 -77
- data/lib/composite_primary_keys/associations/has_and_belongs_to_many_association.rb +59 -59
- data/lib/composite_primary_keys/associations/has_many_association.rb +56 -56
- data/lib/composite_primary_keys/associations/join_dependency.rb +89 -89
- data/lib/composite_primary_keys/associations/join_dependency/join_part.rb +38 -38
- data/lib/composite_primary_keys/associations/preloader/association.rb +78 -78
- data/lib/composite_primary_keys/associations/preloader/has_and_belongs_to_many.rb +46 -46
- data/lib/composite_primary_keys/attribute_methods/dirty.rb +26 -26
- data/lib/composite_primary_keys/attribute_methods/read.rb +34 -34
- data/lib/composite_primary_keys/attribute_methods/write.rb +36 -36
- data/lib/composite_primary_keys/base.rb +0 -6
- data/lib/composite_primary_keys/composite_arrays.rb +30 -30
- data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +4 -2
- data/lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb +17 -0
- data/lib/composite_primary_keys/core.rb +47 -47
- data/lib/composite_primary_keys/persistence.rb +60 -60
- data/lib/composite_primary_keys/relation.rb +56 -56
- data/lib/composite_primary_keys/relation/calculations.rb +75 -65
- data/lib/composite_primary_keys/relation/finder_methods.rb +196 -196
- data/lib/composite_primary_keys/sanitization.rb +52 -52
- data/lib/composite_primary_keys/validations/uniqueness.rb +37 -39
- data/lib/composite_primary_keys/version.rb +8 -8
- data/tasks/databases/sqlserver.rake +40 -27
- data/test/connections/databases.example.yml +18 -18
- data/test/connections/native_sqlserver/connection.rb +14 -11
- data/test/fixtures/db_definitions/mysql.sql +208 -208
- data/test/fixtures/db_definitions/postgresql.sql +210 -210
- data/test/fixtures/db_definitions/sqlite.sql +197 -197
- data/test/fixtures/db_definitions/sqlserver.drop.sql +94 -91
- data/test/fixtures/db_definitions/sqlserver.sql +232 -226
- data/test/fixtures/employee.rb +5 -5
- data/test/test_associations.rb +275 -275
- data/test/test_attributes.rb +60 -60
- data/test/test_create.rb +112 -112
- data/test/test_delete.rb +152 -148
- data/test/test_delete_all.rb +21 -21
- data/test/test_enum.rb +20 -20
- data/test/test_equal.rb +1 -1
- data/test/test_tutorial_example.rb +21 -21
- metadata +3 -2
@@ -1,56 +1,56 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class HasManyAssociation
|
4
|
-
def delete_records(records, method)
|
5
|
-
if method == :destroy
|
6
|
-
records.each(&:destroy!)
|
7
|
-
update_counter(-records.length) unless inverse_updates_counter_cache?
|
8
|
-
else
|
9
|
-
if records == :all || !reflection.klass.primary_key
|
10
|
-
scope = self.scope
|
11
|
-
else
|
12
|
-
# CPK
|
13
|
-
# scope = self.scope.where(reflection.klass.primary_key => records)
|
14
|
-
table = Arel::Table.new(reflection.table_name)
|
15
|
-
and_conditions = records.map do |record|
|
16
|
-
eq_conditions = Array(reflection.association_primary_key).map do |name|
|
17
|
-
table[name].eq(record[name])
|
18
|
-
end
|
19
|
-
Arel::Nodes::And.new(eq_conditions)
|
20
|
-
end
|
21
|
-
|
22
|
-
condition = and_conditions.shift
|
23
|
-
and_conditions.each do |and_condition|
|
24
|
-
condition = condition.or(and_condition)
|
25
|
-
end
|
26
|
-
|
27
|
-
scope = self.scope.where(condition)
|
28
|
-
end
|
29
|
-
|
30
|
-
if method == :delete_all
|
31
|
-
update_counter(-scope.delete_all)
|
32
|
-
else
|
33
|
-
# CPK
|
34
|
-
# update_counter(-scope.update_all(reflection.foreign_key => nil))
|
35
|
-
update_hash = Array(reflection.foreign_key).inject(Hash.new) do |hash, key|
|
36
|
-
hash[key] = nil
|
37
|
-
hash
|
38
|
-
end
|
39
|
-
update_counter(-scope.update_all(update_hash))
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def foreign_key_present?
|
45
|
-
if reflection.klass.primary_key
|
46
|
-
# CPK
|
47
|
-
#owner.attribute_present?(reflection.association_primary_key)
|
48
|
-
owner.attribute_present?(reflection.association_primary_key)
|
49
|
-
Array(reflection.klass.primary_key).all? {|key| owner.attribute_present?(key)}
|
50
|
-
else
|
51
|
-
false
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class HasManyAssociation
|
4
|
+
def delete_records(records, method)
|
5
|
+
if method == :destroy
|
6
|
+
records.each(&:destroy!)
|
7
|
+
update_counter(-records.length) unless inverse_updates_counter_cache?
|
8
|
+
else
|
9
|
+
if records == :all || !reflection.klass.primary_key
|
10
|
+
scope = self.scope
|
11
|
+
else
|
12
|
+
# CPK
|
13
|
+
# scope = self.scope.where(reflection.klass.primary_key => records)
|
14
|
+
table = Arel::Table.new(reflection.table_name)
|
15
|
+
and_conditions = records.map do |record|
|
16
|
+
eq_conditions = Array(reflection.association_primary_key).map do |name|
|
17
|
+
table[name].eq(record[name])
|
18
|
+
end
|
19
|
+
Arel::Nodes::And.new(eq_conditions)
|
20
|
+
end
|
21
|
+
|
22
|
+
condition = and_conditions.shift
|
23
|
+
and_conditions.each do |and_condition|
|
24
|
+
condition = condition.or(and_condition)
|
25
|
+
end
|
26
|
+
|
27
|
+
scope = self.scope.where(condition)
|
28
|
+
end
|
29
|
+
|
30
|
+
if method == :delete_all
|
31
|
+
update_counter(-scope.delete_all)
|
32
|
+
else
|
33
|
+
# CPK
|
34
|
+
# update_counter(-scope.update_all(reflection.foreign_key => nil))
|
35
|
+
update_hash = Array(reflection.foreign_key).inject(Hash.new) do |hash, key|
|
36
|
+
hash[key] = nil
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
update_counter(-scope.update_all(update_hash))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def foreign_key_present?
|
45
|
+
if reflection.klass.primary_key
|
46
|
+
# CPK
|
47
|
+
#owner.attribute_present?(reflection.association_primary_key)
|
48
|
+
owner.attribute_present?(reflection.association_primary_key)
|
49
|
+
Array(reflection.klass.primary_key).all? {|key| owner.attribute_present?(key)}
|
50
|
+
else
|
51
|
+
false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,89 +1,89 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class JoinDependency
|
4
|
-
class Aliases # :nodoc:
|
5
|
-
def column_alias(node, column)
|
6
|
-
# CPK
|
7
|
-
#@alias_cache[node][column]
|
8
|
-
if column.kind_of?(Array)
|
9
|
-
column.map do |a_column|
|
10
|
-
@alias_cache[node][a_column]
|
11
|
-
end
|
12
|
-
else
|
13
|
-
@alias_cache[node][column]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def instantiate(result_set, aliases)
|
19
|
-
primary_key = aliases.column_alias(join_root, join_root.primary_key)
|
20
|
-
type_caster = result_set.column_type primary_key
|
21
|
-
|
22
|
-
seen = Hash.new { |h,parent_klass|
|
23
|
-
h[parent_klass] = Hash.new { |i,parent_id|
|
24
|
-
i[parent_id] = Hash.new { |j,child_klass| j[child_klass] = {} }
|
25
|
-
}
|
26
|
-
}
|
27
|
-
|
28
|
-
model_cache = Hash.new { |h,klass| h[klass] = {} }
|
29
|
-
parents = model_cache[join_root]
|
30
|
-
column_aliases = aliases.column_aliases join_root
|
31
|
-
|
32
|
-
result_set.each { |row_hash|
|
33
|
-
# CPK
|
34
|
-
#primary_id = type_caster.type_cast row_hash[primary_key]
|
35
|
-
primary_id = if primary_key.kind_of?(Array)
|
36
|
-
primary_key.map {|key| type_caster.type_cast row_hash[key]}
|
37
|
-
else
|
38
|
-
type_caster.type_cast row_hash[primary_key]
|
39
|
-
end
|
40
|
-
parent = parents[primary_id] ||= join_root.instantiate(row_hash, column_aliases)
|
41
|
-
construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
|
42
|
-
}
|
43
|
-
|
44
|
-
parents.values
|
45
|
-
end
|
46
|
-
|
47
|
-
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
|
48
|
-
primary_id = ar_parent.id
|
49
|
-
|
50
|
-
parent.children.each do |node|
|
51
|
-
if node.reflection.collection?
|
52
|
-
other = ar_parent.association(node.reflection.name)
|
53
|
-
other.loaded!
|
54
|
-
else
|
55
|
-
if ar_parent.association_cache.key?(node.reflection.name)
|
56
|
-
model = ar_parent.association(node.reflection.name).target
|
57
|
-
construct(model, node, row, rs, seen, model_cache, aliases)
|
58
|
-
next
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
key = aliases.column_alias(node, node.primary_key)
|
63
|
-
|
64
|
-
# CPK
|
65
|
-
if key.is_a?(Array)
|
66
|
-
id = Array(key).map do |column_alias|
|
67
|
-
value = row[column_alias]
|
68
|
-
end
|
69
|
-
# At least the first value in the key has to be set. Should we require all values to be set?
|
70
|
-
next if id.first.nil?
|
71
|
-
else
|
72
|
-
id = row[key]
|
73
|
-
next if id.nil?
|
74
|
-
end
|
75
|
-
|
76
|
-
model = seen[parent.base_klass][primary_id][node.base_klass][id]
|
77
|
-
|
78
|
-
if model
|
79
|
-
construct(model, node, row, rs, seen, model_cache, aliases)
|
80
|
-
else
|
81
|
-
model = construct_model(ar_parent, node, row, model_cache, id, aliases)
|
82
|
-
seen[parent.base_klass][primary_id][node.base_klass][id] = model
|
83
|
-
construct(model, node, row, rs, seen, model_cache, aliases)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class JoinDependency
|
4
|
+
class Aliases # :nodoc:
|
5
|
+
def column_alias(node, column)
|
6
|
+
# CPK
|
7
|
+
#@alias_cache[node][column]
|
8
|
+
if column.kind_of?(Array)
|
9
|
+
column.map do |a_column|
|
10
|
+
@alias_cache[node][a_column]
|
11
|
+
end
|
12
|
+
else
|
13
|
+
@alias_cache[node][column]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def instantiate(result_set, aliases)
|
19
|
+
primary_key = aliases.column_alias(join_root, join_root.primary_key)
|
20
|
+
type_caster = result_set.column_type primary_key
|
21
|
+
|
22
|
+
seen = Hash.new { |h,parent_klass|
|
23
|
+
h[parent_klass] = Hash.new { |i,parent_id|
|
24
|
+
i[parent_id] = Hash.new { |j,child_klass| j[child_klass] = {} }
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
model_cache = Hash.new { |h,klass| h[klass] = {} }
|
29
|
+
parents = model_cache[join_root]
|
30
|
+
column_aliases = aliases.column_aliases join_root
|
31
|
+
|
32
|
+
result_set.each { |row_hash|
|
33
|
+
# CPK
|
34
|
+
#primary_id = type_caster.type_cast row_hash[primary_key]
|
35
|
+
primary_id = if primary_key.kind_of?(Array)
|
36
|
+
primary_key.map {|key| type_caster.type_cast row_hash[key]}
|
37
|
+
else
|
38
|
+
type_caster.type_cast row_hash[primary_key]
|
39
|
+
end
|
40
|
+
parent = parents[primary_id] ||= join_root.instantiate(row_hash, column_aliases)
|
41
|
+
construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
|
42
|
+
}
|
43
|
+
|
44
|
+
parents.values
|
45
|
+
end
|
46
|
+
|
47
|
+
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
|
48
|
+
primary_id = ar_parent.id
|
49
|
+
|
50
|
+
parent.children.each do |node|
|
51
|
+
if node.reflection.collection?
|
52
|
+
other = ar_parent.association(node.reflection.name)
|
53
|
+
other.loaded!
|
54
|
+
else
|
55
|
+
if ar_parent.association_cache.key?(node.reflection.name)
|
56
|
+
model = ar_parent.association(node.reflection.name).target
|
57
|
+
construct(model, node, row, rs, seen, model_cache, aliases)
|
58
|
+
next
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
key = aliases.column_alias(node, node.primary_key)
|
63
|
+
|
64
|
+
# CPK
|
65
|
+
if key.is_a?(Array)
|
66
|
+
id = Array(key).map do |column_alias|
|
67
|
+
value = row[column_alias]
|
68
|
+
end
|
69
|
+
# At least the first value in the key has to be set. Should we require all values to be set?
|
70
|
+
next if id.first.nil?
|
71
|
+
else
|
72
|
+
id = row[key]
|
73
|
+
next if id.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
model = seen[parent.base_klass][primary_id][node.base_klass][id]
|
77
|
+
|
78
|
+
if model
|
79
|
+
construct(model, node, row, rs, seen, model_cache, aliases)
|
80
|
+
else
|
81
|
+
model = construct_model(ar_parent, node, row, model_cache, id, aliases)
|
82
|
+
seen[parent.base_klass][primary_id][node.base_klass][id] = model
|
83
|
+
construct(model, node, row, rs, seen, model_cache, aliases)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -1,39 +1,39 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class JoinDependency
|
4
|
-
class JoinPart
|
5
|
-
def aliased_primary_key
|
6
|
-
# CPK
|
7
|
-
# "#{aliased_prefix}_r0"
|
8
|
-
|
9
|
-
base_klass.composite? ?
|
10
|
-
primary_key.inject([]) {|aliased_keys, key| aliased_keys << "#{ aliased_prefix }_r#{aliased_keys.length}"} :
|
11
|
-
"#{ aliased_prefix }_r0"
|
12
|
-
end
|
13
|
-
|
14
|
-
def record_id(row)
|
15
|
-
# CPK
|
16
|
-
# row[aliased_primary_key]
|
17
|
-
base_klass.composite? ?
|
18
|
-
aliased_primary_key.map {|key| row[key]}.to_composite_keys :
|
19
|
-
row[aliased_primary_key]
|
20
|
-
end
|
21
|
-
|
22
|
-
def column_names_with_alias
|
23
|
-
unless @column_names_with_alias
|
24
|
-
@column_names_with_alias = []
|
25
|
-
|
26
|
-
# CPK
|
27
|
-
#([primary_key] + (column_names - [primary_key])).each_with_index do |column_name, i|
|
28
|
-
keys = base_klass.composite? ? primary_key.map(&:to_s) : [primary_key]
|
29
|
-
|
30
|
-
(keys + (column_names - keys)).each_with_index do |column_name, i|
|
31
|
-
@column_names_with_alias << [column_name, "#{aliased_prefix}_r#{i}"]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
@column_names_with_alias
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class JoinDependency
|
4
|
+
class JoinPart
|
5
|
+
def aliased_primary_key
|
6
|
+
# CPK
|
7
|
+
# "#{aliased_prefix}_r0"
|
8
|
+
|
9
|
+
base_klass.composite? ?
|
10
|
+
primary_key.inject([]) {|aliased_keys, key| aliased_keys << "#{ aliased_prefix }_r#{aliased_keys.length}"} :
|
11
|
+
"#{ aliased_prefix }_r0"
|
12
|
+
end
|
13
|
+
|
14
|
+
def record_id(row)
|
15
|
+
# CPK
|
16
|
+
# row[aliased_primary_key]
|
17
|
+
base_klass.composite? ?
|
18
|
+
aliased_primary_key.map {|key| row[key]}.to_composite_keys :
|
19
|
+
row[aliased_primary_key]
|
20
|
+
end
|
21
|
+
|
22
|
+
def column_names_with_alias
|
23
|
+
unless @column_names_with_alias
|
24
|
+
@column_names_with_alias = []
|
25
|
+
|
26
|
+
# CPK
|
27
|
+
#([primary_key] + (column_names - [primary_key])).each_with_index do |column_name, i|
|
28
|
+
keys = base_klass.composite? ? primary_key.map(&:to_s) : [primary_key]
|
29
|
+
|
30
|
+
(keys + (column_names - keys)).each_with_index do |column_name, i|
|
31
|
+
@column_names_with_alias << [column_name, "#{aliased_prefix}_r#{i}"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
@column_names_with_alias
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
39
|
end
|
@@ -1,78 +1,78 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class Preloader
|
4
|
-
class Association
|
5
|
-
def query_scope(ids)
|
6
|
-
# CPK
|
7
|
-
# scope.where(association_key.in(ids))
|
8
|
-
|
9
|
-
if reflection.foreign_key.is_a?(Array)
|
10
|
-
predicate = cpk_in_predicate(table, reflection.foreign_key, ids)
|
11
|
-
scope.where(predicate)
|
12
|
-
else
|
13
|
-
scope.where(association_key.in(ids))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def associated_records_by_owner(preloader)
|
18
|
-
# CPK
|
19
|
-
owners_map = owners_by_key
|
20
|
-
#owner_keys = owners_map.keys.compact
|
21
|
-
owner_keys = owners.map do |owner|
|
22
|
-
Array(owner_key_name).map do |owner_key|
|
23
|
-
owner[owner_key]
|
24
|
-
end
|
25
|
-
end.compact.uniq
|
26
|
-
|
27
|
-
# Each record may have multiple owners, and vice-versa
|
28
|
-
records_by_owner = owners.each_with_object({}) do |owner,h|
|
29
|
-
h[owner] = []
|
30
|
-
end
|
31
|
-
|
32
|
-
if owner_keys.any?
|
33
|
-
# Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
|
34
|
-
# Make several smaller queries if necessary or make one query if the adapter supports it
|
35
|
-
sliced = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
|
36
|
-
|
37
|
-
records = load_slices sliced
|
38
|
-
records.each do |record, owner_key|
|
39
|
-
owners_map[owner_key].each do |owner|
|
40
|
-
records_by_owner[owner] << record
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
records_by_owner
|
46
|
-
end
|
47
|
-
|
48
|
-
def load_slices(slices)
|
49
|
-
@preloaded_records = slices.flat_map { |slice|
|
50
|
-
records_for(slice)
|
51
|
-
}
|
52
|
-
|
53
|
-
@preloaded_records.map { |record|
|
54
|
-
# CPK
|
55
|
-
#[record, record[association_key_name]]
|
56
|
-
owner_key = Array(association_key_name).map do |key_name|
|
57
|
-
record[key_name]
|
58
|
-
end.join(CompositePrimaryKeys::ID_SEP)
|
59
|
-
[record, owner_key]
|
60
|
-
}
|
61
|
-
end
|
62
|
-
|
63
|
-
def owners_by_key
|
64
|
-
@owners_by_key ||= owners.group_by do |owner|
|
65
|
-
# CPK
|
66
|
-
# key = owner[owner_key_name]
|
67
|
-
key = Array(owner_key_name).map do |key_name|
|
68
|
-
owner[key_name]
|
69
|
-
end
|
70
|
-
# CPK
|
71
|
-
# key && key.to_s
|
72
|
-
key && key.join(CompositePrimaryKeys::ID_SEP)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class Preloader
|
4
|
+
class Association
|
5
|
+
def query_scope(ids)
|
6
|
+
# CPK
|
7
|
+
# scope.where(association_key.in(ids))
|
8
|
+
|
9
|
+
if reflection.foreign_key.is_a?(Array)
|
10
|
+
predicate = cpk_in_predicate(table, reflection.foreign_key, ids)
|
11
|
+
scope.where(predicate)
|
12
|
+
else
|
13
|
+
scope.where(association_key.in(ids))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def associated_records_by_owner(preloader)
|
18
|
+
# CPK
|
19
|
+
owners_map = owners_by_key
|
20
|
+
#owner_keys = owners_map.keys.compact
|
21
|
+
owner_keys = owners.map do |owner|
|
22
|
+
Array(owner_key_name).map do |owner_key|
|
23
|
+
owner[owner_key]
|
24
|
+
end
|
25
|
+
end.compact.uniq
|
26
|
+
|
27
|
+
# Each record may have multiple owners, and vice-versa
|
28
|
+
records_by_owner = owners.each_with_object({}) do |owner,h|
|
29
|
+
h[owner] = []
|
30
|
+
end
|
31
|
+
|
32
|
+
if owner_keys.any?
|
33
|
+
# Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
|
34
|
+
# Make several smaller queries if necessary or make one query if the adapter supports it
|
35
|
+
sliced = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
|
36
|
+
|
37
|
+
records = load_slices sliced
|
38
|
+
records.each do |record, owner_key|
|
39
|
+
owners_map[owner_key].each do |owner|
|
40
|
+
records_by_owner[owner] << record
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
records_by_owner
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_slices(slices)
|
49
|
+
@preloaded_records = slices.flat_map { |slice|
|
50
|
+
records_for(slice)
|
51
|
+
}
|
52
|
+
|
53
|
+
@preloaded_records.map { |record|
|
54
|
+
# CPK
|
55
|
+
#[record, record[association_key_name]]
|
56
|
+
owner_key = Array(association_key_name).map do |key_name|
|
57
|
+
record[key_name]
|
58
|
+
end.join(CompositePrimaryKeys::ID_SEP)
|
59
|
+
[record, owner_key]
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def owners_by_key
|
64
|
+
@owners_by_key ||= owners.group_by do |owner|
|
65
|
+
# CPK
|
66
|
+
# key = owner[owner_key_name]
|
67
|
+
key = Array(owner_key_name).map do |key_name|
|
68
|
+
owner[key_name]
|
69
|
+
end
|
70
|
+
# CPK
|
71
|
+
# key && key.to_s
|
72
|
+
key && key.join(CompositePrimaryKeys::ID_SEP)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|