composite_primary_keys 13.0.1 → 14.0.1
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 +8 -2
- data/README.rdoc +1 -0
- data/Rakefile +37 -37
- data/lib/composite_primary_keys/arel/sqlserver.rb +37 -37
- data/lib/composite_primary_keys/arel/to_sql.rb +18 -18
- data/lib/composite_primary_keys/associations/association.rb +23 -23
- data/lib/composite_primary_keys/associations/collection_association.rb +31 -31
- data/lib/composite_primary_keys/associations/foreign_association.rb +15 -15
- data/lib/composite_primary_keys/associations/has_many_association.rb +35 -35
- data/lib/composite_primary_keys/associations/preloader/association.rb +68 -53
- data/lib/composite_primary_keys/associations/through_association.rb +25 -25
- data/lib/composite_primary_keys/autosave_association.rb +60 -60
- data/lib/composite_primary_keys/composite_arrays.rb +86 -86
- data/lib/composite_primary_keys/composite_predicates.rb +71 -70
- data/lib/composite_primary_keys/composite_relation.rb +29 -29
- data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +10 -10
- data/lib/composite_primary_keys/connection_adapters/postgresql/database_statements.rb +26 -26
- data/lib/composite_primary_keys/counter_cache.rb +15 -15
- data/lib/composite_primary_keys/fixtures.rb +21 -21
- data/lib/composite_primary_keys/persistence.rb +21 -7
- data/lib/composite_primary_keys/relation/calculations.rb +7 -1
- data/lib/composite_primary_keys/sanitization.rb +42 -42
- data/lib/composite_primary_keys/transactions.rb +34 -34
- data/lib/composite_primary_keys/validations/uniqueness.rb +31 -31
- data/lib/composite_primary_keys/version.rb +1 -1
- data/lib/composite_primary_keys.rb +1 -1
- data/scripts/console.rb +48 -48
- data/scripts/txt2html +76 -76
- data/scripts/txt2js +65 -65
- data/tasks/databases/mysql.rake +40 -40
- data/tasks/databases/oracle.rake +41 -41
- data/tasks/databases/postgresql.rake +38 -38
- data/tasks/databases/sqlite.rake +25 -25
- data/tasks/databases/sqlserver.rake +43 -43
- data/tasks/website.rake +18 -18
- data/test/README_tests.rdoc +56 -56
- data/test/abstract_unit.rb +5 -1
- data/test/connections/connection_spec.rb +27 -27
- data/test/connections/databases.example.yml +40 -40
- data/test/connections/databases.yml +40 -39
- data/test/fixtures/article.rb +10 -10
- data/test/fixtures/articles.yml +7 -7
- data/test/fixtures/capitol.rb +3 -3
- data/test/fixtures/capitols.yml +16 -16
- data/test/fixtures/comment.rb +5 -5
- data/test/fixtures/comments.yml +17 -17
- data/test/fixtures/dorm.rb +2 -2
- data/test/fixtures/dorms.yml +4 -4
- data/test/fixtures/employee.rb +5 -5
- data/test/fixtures/group.rb +2 -2
- data/test/fixtures/groups.yml +6 -6
- data/test/fixtures/membership_status.rb +2 -2
- data/test/fixtures/membership_statuses.yml +16 -16
- data/test/fixtures/memberships.yml +10 -10
- data/test/fixtures/product.rb +9 -9
- data/test/fixtures/product_tariff.rb +5 -5
- data/test/fixtures/product_tariffs.yml +14 -14
- data/test/fixtures/products.yml +11 -11
- data/test/fixtures/reading.rb +4 -4
- data/test/fixtures/readings.yml +10 -10
- data/test/fixtures/reference_code.rb +7 -7
- data/test/fixtures/reference_codes.yml +28 -28
- data/test/fixtures/reference_type.rb +12 -12
- data/test/fixtures/reference_types.yml +9 -9
- data/test/fixtures/restaurant.rb +9 -9
- data/test/fixtures/restaurants.yml +14 -14
- data/test/fixtures/restaurants_suburb.rb +2 -2
- data/test/fixtures/room.rb +11 -11
- data/test/fixtures/room_assignment.rb +13 -13
- data/test/fixtures/room_assignments.yml +24 -24
- data/test/fixtures/room_attribute.rb +2 -2
- data/test/fixtures/room_attribute_assignment.rb +4 -4
- data/test/fixtures/room_attribute_assignments.yml +4 -4
- data/test/fixtures/room_attributes.yml +2 -2
- data/test/fixtures/rooms.yml +12 -12
- data/test/fixtures/street.rb +2 -2
- data/test/fixtures/student.rb +3 -3
- data/test/fixtures/students.yml +15 -15
- data/test/fixtures/suburb.rb +5 -5
- data/test/fixtures/tariff.rb +5 -5
- data/test/fixtures/tariffs.yml +14 -14
- data/test/fixtures/topic_sources.yml +3 -3
- data/test/fixtures/topics.yml +8 -8
- data/test/fixtures/users.yml +10 -10
- data/test/plugins/pagination.rb +405 -405
- data/test/plugins/pagination_helper.rb +135 -135
- data/test/test_attribute_methods.rb +63 -63
- data/test/test_callbacks.rb +99 -99
- data/test/test_composite_arrays.rb +38 -38
- data/test/test_counter_cache.rb +30 -30
- data/test/test_dumpable.rb +15 -15
- data/test/test_dup.rb +37 -37
- data/test/test_equal.rb +26 -26
- data/test/test_habtm.rb +141 -141
- data/test/test_miscellaneous.rb +32 -32
- data/test/test_optimistic.rb +18 -18
- data/test/test_pagination.rb +35 -35
- data/test/test_polymorphic.rb +43 -43
- data/test/test_predicates.rb +59 -59
- data/test/test_preload.rb +102 -102
- data/test/test_santiago.rb +23 -23
- data/test/test_touch.rb +23 -23
- data/test/test_tutorial_example.rb +25 -25
- data/test/test_validations.rb +13 -13
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4310258f29b867cf484cb8dbebfe1f7a7d41810f2dac5f90049c534f1c0a908b
|
4
|
+
data.tar.gz: 970906ceae8ac95925d5ee694541b09844f3104309eaed5864f9b1faff7fb43e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78878c2b2fa9612e8e141b5b1d39679a03046aed63e7c19e7ad71b6b8372327cfcb9a5bb659d88fda5cbb405e5bf7199c742b0468041a9509406ce54764d4e10
|
7
|
+
data.tar.gz: 79e78cb7cf9a336821cb02dad8d1cf43aece81e25b18c4ebadac1b584be1d6bd06a7a43b7840c918323efb69d8b0c9783c215595f04a37dc083079ba4e0cc50e
|
data/History.rdoc
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
==
|
1
|
+
== 14.0.1 (2022-01-9)
|
2
|
+
* Fix mistake in Gemfile (Charlie Savage)
|
3
|
+
|
4
|
+
== 14.0.0 (2022-01-9)
|
5
|
+
* Update to ActiveRecord 7.0 (Sammy Larbi)
|
6
|
+
|
7
|
+
== 13.0.1 (2021-11-14)
|
2
8
|
* Fix invalid sql generation for some cases of scoped associations (Ryan Mulligan)
|
3
9
|
* Fix unintentional connection to database (Kazuhiro Masuda)
|
4
10
|
* Zip values then keys - fixes #548 (Charlie Savage)
|
5
11
|
|
6
|
-
== 13.0.0
|
12
|
+
== 13.0.0 (2021-5-9)
|
7
13
|
* Update to ActiveRecord 6.1 (Javier Julio, Charlie Savage, Sammy Larbi)
|
8
14
|
|
9
15
|
== 12.0.10 (2021-05-09)
|
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
|
data/Rakefile
CHANGED
@@ -1,37 +1,37 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'rake/clean'
|
4
|
-
require 'rake/testtask'
|
5
|
-
require 'rubygems/package_task'
|
6
|
-
|
7
|
-
# Set global variable so other tasks can access them
|
8
|
-
::PROJECT_ROOT = File.expand_path(".")
|
9
|
-
::GEM_NAME = 'composite_primary_keys'
|
10
|
-
|
11
|
-
require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
|
12
|
-
require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
|
13
|
-
|
14
|
-
# Read the spec file
|
15
|
-
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
16
|
-
|
17
|
-
# Setup Rake tasks for managing the gem
|
18
|
-
Gem::PackageTask.new(spec).define
|
19
|
-
|
20
|
-
# Now load in other task files
|
21
|
-
Dir.glob('tasks/**/*.rake').each do |rake_file|
|
22
|
-
load File.join(File.dirname(__FILE__), rake_file)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Set up test tasks for each supported connection adapter
|
26
|
-
%w(mysql sqlite oracle oracle_enhanced postgresql ibm_db sqlserver).each do |adapter|
|
27
|
-
namespace adapter do
|
28
|
-
desc "Run tests using the #{adapter} adapter"
|
29
|
-
task "test" do
|
30
|
-
ENV["ADAPTER"] = adapter
|
31
|
-
Rake::TestTask.new("subtest_#{adapter}") do |t|
|
32
|
-
t.libs << "test"
|
33
|
-
end
|
34
|
-
Rake::Task["subtest_#{adapter}"].invoke
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rubygems/package_task'
|
6
|
+
|
7
|
+
# Set global variable so other tasks can access them
|
8
|
+
::PROJECT_ROOT = File.expand_path(".")
|
9
|
+
::GEM_NAME = 'composite_primary_keys'
|
10
|
+
|
11
|
+
require File.join(PROJECT_ROOT, 'lib', 'composite_primary_keys')
|
12
|
+
require File.join(PROJECT_ROOT, 'test', 'connections', 'connection_spec')
|
13
|
+
|
14
|
+
# Read the spec file
|
15
|
+
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
16
|
+
|
17
|
+
# Setup Rake tasks for managing the gem
|
18
|
+
Gem::PackageTask.new(spec).define
|
19
|
+
|
20
|
+
# Now load in other task files
|
21
|
+
Dir.glob('tasks/**/*.rake').each do |rake_file|
|
22
|
+
load File.join(File.dirname(__FILE__), rake_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set up test tasks for each supported connection adapter
|
26
|
+
%w(mysql sqlite oracle oracle_enhanced postgresql ibm_db sqlserver).each do |adapter|
|
27
|
+
namespace adapter do
|
28
|
+
desc "Run tests using the #{adapter} adapter"
|
29
|
+
task "test" do
|
30
|
+
ENV["ADAPTER"] = adapter
|
31
|
+
Rake::TestTask.new("subtest_#{adapter}") do |t|
|
32
|
+
t.libs << "test"
|
33
|
+
end
|
34
|
+
Rake::Task["subtest_#{adapter}"].invoke
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,37 +1,37 @@
|
|
1
|
-
module Arel
|
2
|
-
module Visitors
|
3
|
-
class SQLServer < Arel::Visitors::ToSql
|
4
|
-
def make_Fetch_Possible_And_Deterministic o
|
5
|
-
return if o.limit.nil? && o.offset.nil?
|
6
|
-
t = table_From_Statement o
|
7
|
-
pk = primary_Key_From_Table t
|
8
|
-
return unless pk
|
9
|
-
if o.orders.empty?
|
10
|
-
# Prefer deterministic vs a simple `(SELECT NULL)` expr.
|
11
|
-
# CPK
|
12
|
-
#o.orders = [pk.asc]
|
13
|
-
o.orders = pk.map {|a_pk| a_pk.asc}
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def primary_Key_From_Table t
|
18
|
-
return unless t
|
19
|
-
column_name = @connection.schema_cache.primary_keys(t.name) ||
|
20
|
-
@connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
|
21
|
-
|
22
|
-
# CPK
|
23
|
-
# column_name ? t[column_name] : nil
|
24
|
-
case column_name
|
25
|
-
when Array
|
26
|
-
column_name.map do |name|
|
27
|
-
t[name]
|
28
|
-
end
|
29
|
-
when NilClass
|
30
|
-
nil
|
31
|
-
else
|
32
|
-
[t[column_name]]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class SQLServer < Arel::Visitors::ToSql
|
4
|
+
def make_Fetch_Possible_And_Deterministic o
|
5
|
+
return if o.limit.nil? && o.offset.nil?
|
6
|
+
t = table_From_Statement o
|
7
|
+
pk = primary_Key_From_Table t
|
8
|
+
return unless pk
|
9
|
+
if o.orders.empty?
|
10
|
+
# Prefer deterministic vs a simple `(SELECT NULL)` expr.
|
11
|
+
# CPK
|
12
|
+
#o.orders = [pk.asc]
|
13
|
+
o.orders = pk.map {|a_pk| a_pk.asc}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def primary_Key_From_Table t
|
18
|
+
return unless t
|
19
|
+
column_name = @connection.schema_cache.primary_keys(t.name) ||
|
20
|
+
@connection.schema_cache.columns_hash(t.name).first.try(:second).try(:name)
|
21
|
+
|
22
|
+
# CPK
|
23
|
+
# column_name ? t[column_name] : nil
|
24
|
+
case column_name
|
25
|
+
when Array
|
26
|
+
column_name.map do |name|
|
27
|
+
t[name]
|
28
|
+
end
|
29
|
+
when NilClass
|
30
|
+
nil
|
31
|
+
else
|
32
|
+
[t[column_name]]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
|
-
module Arel
|
2
|
-
module Visitors
|
3
|
-
class ToSql
|
4
|
-
def visit_CompositePrimaryKeys_CompositeKeys o, collector
|
5
|
-
values = o.map do |key|
|
6
|
-
case key
|
7
|
-
when Arel::Attributes::Attribute
|
8
|
-
"#{key.relation.name}.#{key.name}"
|
9
|
-
else
|
10
|
-
key
|
11
|
-
end
|
12
|
-
end
|
13
|
-
collector << "(#{values.join(', ')})"
|
14
|
-
collector
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class ToSql
|
4
|
+
def visit_CompositePrimaryKeys_CompositeKeys o, collector
|
5
|
+
values = o.map do |key|
|
6
|
+
case key
|
7
|
+
when Arel::Attributes::Attribute
|
8
|
+
"#{key.relation.name}.#{key.name}"
|
9
|
+
else
|
10
|
+
key
|
11
|
+
end
|
12
|
+
end
|
13
|
+
collector << "(#{values.join(', ')})"
|
14
|
+
collector
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,23 +1,23 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class Association
|
4
|
-
def creation_attributes
|
5
|
-
attributes = {}
|
6
|
-
|
7
|
-
if (reflection.has_one? || reflection.collection?) && !options[:through]
|
8
|
-
# CPK
|
9
|
-
# attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
|
10
|
-
Array(reflection.foreign_key).zip(Array(reflection.active_record_primary_key)).each do |key1, key2|
|
11
|
-
attributes[key1] = owner[key2]
|
12
|
-
end
|
13
|
-
|
14
|
-
if reflection.options[:as]
|
15
|
-
attributes[reflection.type] = owner.class.base_class.name
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
attributes
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class Association
|
4
|
+
def creation_attributes
|
5
|
+
attributes = {}
|
6
|
+
|
7
|
+
if (reflection.has_one? || reflection.collection?) && !options[:through]
|
8
|
+
# CPK
|
9
|
+
# attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
|
10
|
+
Array(reflection.foreign_key).zip(Array(reflection.active_record_primary_key)).each do |key1, key2|
|
11
|
+
attributes[key1] = owner[key2]
|
12
|
+
end
|
13
|
+
|
14
|
+
if reflection.options[:as]
|
15
|
+
attributes[reflection.type] = owner.class.base_class.name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
attributes
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -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,15 +1,15 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveRecord::Associations
|
4
|
-
module ForeignAssociation # :nodoc:
|
5
|
-
def foreign_key_present?
|
6
|
-
if reflection.klass.primary_key
|
7
|
-
# CPK
|
8
|
-
# owner.attribute_present?(reflection.active_record_primary_key)
|
9
|
-
Array(reflection.active_record_primary_key).all? {|key| owner.attribute_present?(key)}
|
10
|
-
else
|
11
|
-
false
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord::Associations
|
4
|
+
module ForeignAssociation # :nodoc:
|
5
|
+
def foreign_key_present?
|
6
|
+
if reflection.klass.primary_key
|
7
|
+
# CPK
|
8
|
+
# owner.attribute_present?(reflection.active_record_primary_key)
|
9
|
+
Array(reflection.active_record_primary_key).all? {|key| owner.attribute_present?(key)}
|
10
|
+
else
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,35 +1,35 @@
|
|
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 reflection.inverse_updates_counter_cache?
|
8
|
-
# CPK
|
9
|
-
elsif self.reflection.klass.composite?
|
10
|
-
predicate = cpk_in_predicate(self.scope.table, self.reflection.klass.primary_keys, records.map(&:id))
|
11
|
-
scope = self.scope.where(predicate)
|
12
|
-
update_counter(-delete_count(method, scope))
|
13
|
-
else
|
14
|
-
scope = self.scope.where(reflection.klass.primary_key => records)
|
15
|
-
update_counter(-delete_count(method, scope))
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def delete_count(method, scope)
|
20
|
-
if method == :delete_all
|
21
|
-
scope.delete_all
|
22
|
-
else
|
23
|
-
# CPK
|
24
|
-
# scope.update_all(nullified_owner_attributes)
|
25
|
-
conds = Array(reflection.foreign_key).inject(Hash.new) do |mem, key|
|
26
|
-
mem[key] = nil
|
27
|
-
mem
|
28
|
-
end
|
29
|
-
conds[reflection.type] = nil if reflection.type.present?
|
30
|
-
scope.update_all(conds)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
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 reflection.inverse_updates_counter_cache?
|
8
|
+
# CPK
|
9
|
+
elsif self.reflection.klass.composite?
|
10
|
+
predicate = cpk_in_predicate(self.scope.table, self.reflection.klass.primary_keys, records.map(&:id))
|
11
|
+
scope = self.scope.where(predicate)
|
12
|
+
update_counter(-delete_count(method, scope))
|
13
|
+
else
|
14
|
+
scope = self.scope.where(reflection.klass.primary_key => records)
|
15
|
+
update_counter(-delete_count(method, scope))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete_count(method, scope)
|
20
|
+
if method == :delete_all
|
21
|
+
scope.delete_all
|
22
|
+
else
|
23
|
+
# CPK
|
24
|
+
# scope.update_all(nullified_owner_attributes)
|
25
|
+
conds = Array(reflection.foreign_key).inject(Hash.new) do |mem, key|
|
26
|
+
mem[key] = nil
|
27
|
+
mem
|
28
|
+
end
|
29
|
+
conds[reflection.type] = nil if reflection.type.present?
|
30
|
+
scope.update_all(conds)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,53 +1,68 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class Preloader
|
4
|
-
class Association
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
key =
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class Preloader
|
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
|
19
|
+
def records_for(ids)
|
20
|
+
records = if association_key_name.is_a?(Array)
|
21
|
+
predicate = cpk_in_predicate(klass.arel_table, association_key_name, ids)
|
22
|
+
scope.where(predicate)
|
23
|
+
else
|
24
|
+
scope.where(association_key_name => ids)
|
25
|
+
end
|
26
|
+
records.load do |record|
|
27
|
+
# Processing only the first owner
|
28
|
+
# because the record is modified but not an owner
|
29
|
+
owner = owners_by_key[convert_key(record[association_key_name])].first
|
30
|
+
association = owner.association(reflection.name)
|
31
|
+
association.set_inverse_instance(record)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def owners_by_key
|
36
|
+
@owners_by_key ||= owners.each_with_object({}) do |owner, result|
|
37
|
+
# CPK
|
38
|
+
# key = convert_key(owner[owner_key_name])
|
39
|
+
key = if owner_key_name.is_a?(Array)
|
40
|
+
Array(owner_key_name).map do |key_name|
|
41
|
+
convert_key(owner[key_name])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
convert_key(owner[owner_key_name])
|
45
|
+
end
|
46
|
+
(result[key] ||= []) << owner if key
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# TODO: is records_by_owner needed anymore? Rails' implementation has changed significantly
|
51
|
+
def records_by_owner
|
52
|
+
@records_by_owner ||= preloaded_records.each_with_object({}) do |record, result|
|
53
|
+
key = if association_key_name.is_a?(Array)
|
54
|
+
Array(record[association_key_name]).map do |key|
|
55
|
+
convert_key(key)
|
56
|
+
end
|
57
|
+
else
|
58
|
+
convert_key(record[association_key_name])
|
59
|
+
end
|
60
|
+
owners_by_key[key].each do |owner|
|
61
|
+
(result[owner] ||= []) << record
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -1,25 +1,25 @@
|
|
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
|
+
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
|