composite_primary_keys 12.0.9 → 13.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +15 -1
  3. data/README.rdoc +1 -0
  4. data/Rakefile +37 -37
  5. data/lib/composite_primary_keys/active_model/attribute_assignment.rb +19 -19
  6. data/lib/composite_primary_keys/arel/sqlserver.rb +37 -37
  7. data/lib/composite_primary_keys/arel/to_sql.rb +18 -18
  8. data/lib/composite_primary_keys/associations/association.rb +23 -23
  9. data/lib/composite_primary_keys/associations/association_scope.rb +66 -68
  10. data/lib/composite_primary_keys/associations/collection_association.rb +31 -31
  11. data/lib/composite_primary_keys/associations/foreign_association.rb +15 -15
  12. data/lib/composite_primary_keys/associations/has_many_association.rb +35 -35
  13. data/lib/composite_primary_keys/associations/{join_dependency.rb → join_association.rb} +137 -103
  14. data/lib/composite_primary_keys/associations/through_association.rb +25 -25
  15. data/lib/composite_primary_keys/attribute_methods/primary_key.rb +0 -2
  16. data/lib/composite_primary_keys/attribute_methods/read.rb +30 -30
  17. data/lib/composite_primary_keys/attribute_methods/write.rb +35 -35
  18. data/lib/composite_primary_keys/attribute_methods.rb +21 -9
  19. data/lib/composite_primary_keys/autosave_association.rb +60 -60
  20. data/lib/composite_primary_keys/base.rb +141 -141
  21. data/lib/composite_primary_keys/composite_arrays.rb +86 -86
  22. data/lib/composite_primary_keys/composite_predicates.rb +2 -1
  23. data/lib/composite_primary_keys/composite_relation.rb +29 -29
  24. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +37 -37
  25. data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +10 -10
  26. data/lib/composite_primary_keys/connection_adapters/postgresql/database_statements.rb +26 -26
  27. data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +44 -44
  28. data/lib/composite_primary_keys/core.rb +48 -48
  29. data/lib/composite_primary_keys/counter_cache.rb +15 -15
  30. data/lib/composite_primary_keys/fixtures.rb +21 -21
  31. data/lib/composite_primary_keys/nested_attributes.rb +1 -1
  32. data/lib/composite_primary_keys/persistence.rb +3 -2
  33. data/lib/composite_primary_keys/reflection.rb +91 -29
  34. data/lib/composite_primary_keys/relation/batches.rb +15 -7
  35. data/lib/composite_primary_keys/relation/calculations.rb +46 -23
  36. data/lib/composite_primary_keys/relation/finder_methods.rb +235 -235
  37. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +39 -20
  38. data/lib/composite_primary_keys/relation/query_methods.rb +42 -42
  39. data/lib/composite_primary_keys/relation/where_clause.rb +18 -23
  40. data/lib/composite_primary_keys/relation.rb +197 -193
  41. data/lib/composite_primary_keys/sanitization.rb +42 -42
  42. data/lib/composite_primary_keys/table_metadata.rb +11 -0
  43. data/lib/composite_primary_keys/transactions.rb +34 -34
  44. data/lib/composite_primary_keys/validations/uniqueness.rb +31 -31
  45. data/lib/composite_primary_keys/version.rb +2 -2
  46. data/lib/composite_primary_keys.rb +4 -2
  47. data/scripts/console.rb +48 -48
  48. data/scripts/txt2html +76 -76
  49. data/scripts/txt2js +65 -65
  50. data/tasks/databases/mysql.rake +40 -40
  51. data/tasks/databases/oracle.rake +41 -41
  52. data/tasks/databases/postgresql.rake +38 -38
  53. data/tasks/databases/sqlite.rake +25 -25
  54. data/tasks/databases/sqlserver.rake +43 -43
  55. data/tasks/website.rake +18 -18
  56. data/test/README_tests.rdoc +56 -56
  57. data/test/connections/connection_spec.rb +27 -27
  58. data/test/connections/databases.ci.yml +22 -22
  59. data/test/connections/databases.example.yml +40 -40
  60. data/test/connections/databases.yml +40 -39
  61. data/test/fixtures/article.rb +10 -10
  62. data/test/fixtures/articles.yml +7 -7
  63. data/test/fixtures/capitol.rb +3 -3
  64. data/test/fixtures/capitols.yml +16 -16
  65. data/test/fixtures/comment.rb +5 -5
  66. data/test/fixtures/comments.yml +17 -17
  67. data/test/fixtures/db_definitions/db2-create-tables.sql +112 -112
  68. data/test/fixtures/db_definitions/db2-drop-tables.sql +16 -16
  69. data/test/fixtures/db_definitions/mysql.sql +180 -180
  70. data/test/fixtures/db_definitions/oracle.drop.sql +41 -41
  71. data/test/fixtures/db_definitions/oracle.sql +199 -199
  72. data/test/fixtures/db_definitions/postgresql.sql +182 -182
  73. data/test/fixtures/db_definitions/sqlite.sql +169 -169
  74. data/test/fixtures/db_definitions/sqlserver.sql +176 -176
  75. data/test/fixtures/departments.yml +19 -15
  76. data/test/fixtures/dorm.rb +2 -2
  77. data/test/fixtures/dorms.yml +4 -4
  78. data/test/fixtures/employee.rb +5 -5
  79. data/test/fixtures/employees.yml +33 -28
  80. data/test/fixtures/group.rb +2 -2
  81. data/test/fixtures/groups.yml +6 -6
  82. data/test/fixtures/membership.rb +2 -0
  83. data/test/fixtures/membership_status.rb +2 -2
  84. data/test/fixtures/membership_statuses.yml +16 -16
  85. data/test/fixtures/memberships.yml +10 -10
  86. data/test/fixtures/product.rb +9 -9
  87. data/test/fixtures/product_tariff.rb +5 -5
  88. data/test/fixtures/product_tariffs.yml +14 -14
  89. data/test/fixtures/products.yml +11 -11
  90. data/test/fixtures/reading.rb +4 -4
  91. data/test/fixtures/readings.yml +10 -10
  92. data/test/fixtures/reference_code.rb +7 -7
  93. data/test/fixtures/reference_codes.yml +28 -28
  94. data/test/fixtures/reference_type.rb +12 -12
  95. data/test/fixtures/reference_types.yml +9 -9
  96. data/test/fixtures/restaurant.rb +9 -9
  97. data/test/fixtures/restaurants.yml +14 -14
  98. data/test/fixtures/restaurants_suburb.rb +2 -2
  99. data/test/fixtures/restaurants_suburbs.yml +10 -10
  100. data/test/fixtures/room.rb +11 -11
  101. data/test/fixtures/room_assignment.rb +13 -13
  102. data/test/fixtures/room_assignments.yml +24 -24
  103. data/test/fixtures/room_attribute.rb +2 -2
  104. data/test/fixtures/room_attribute_assignment.rb +4 -4
  105. data/test/fixtures/room_attribute_assignments.yml +4 -4
  106. data/test/fixtures/room_attributes.yml +2 -2
  107. data/test/fixtures/rooms.yml +12 -12
  108. data/test/fixtures/street.rb +2 -2
  109. data/test/fixtures/streets.yml +16 -16
  110. data/test/fixtures/student.rb +3 -3
  111. data/test/fixtures/students.yml +15 -15
  112. data/test/fixtures/suburb.rb +5 -5
  113. data/test/fixtures/suburbs.yml +14 -14
  114. data/test/fixtures/tariff.rb +5 -5
  115. data/test/fixtures/tariffs.yml +14 -14
  116. data/test/fixtures/topic_sources.yml +3 -3
  117. data/test/fixtures/topics.yml +8 -8
  118. data/test/fixtures/user.rb +11 -11
  119. data/test/fixtures/users.yml +10 -10
  120. data/test/plugins/pagination.rb +405 -405
  121. data/test/plugins/pagination_helper.rb +135 -135
  122. data/test/test_associations.rb +14 -0
  123. data/test/test_attribute_methods.rb +63 -63
  124. data/test/test_attributes.rb +75 -60
  125. data/test/test_calculations.rb +49 -42
  126. data/test/test_callbacks.rb +99 -99
  127. data/test/test_composite_arrays.rb +38 -38
  128. data/test/test_counter_cache.rb +30 -30
  129. data/test/test_create.rb +218 -206
  130. data/test/test_delete.rb +188 -179
  131. data/test/test_dumpable.rb +15 -15
  132. data/test/test_dup.rb +37 -37
  133. data/test/test_equal.rb +26 -26
  134. data/test/test_exists.rb +39 -39
  135. data/test/test_find.rb +170 -164
  136. data/test/test_habtm.rb +141 -141
  137. data/test/test_ids.rb +112 -112
  138. data/test/test_miscellaneous.rb +32 -32
  139. data/test/test_nested_attributes.rb +67 -67
  140. data/test/test_optimistic.rb +18 -18
  141. data/test/test_pagination.rb +35 -35
  142. data/test/test_polymorphic.rb +43 -43
  143. data/test/test_predicates.rb +59 -59
  144. data/test/test_preload.rb +102 -102
  145. data/test/test_santiago.rb +23 -23
  146. data/test/test_touch.rb +23 -23
  147. data/test/test_tutorial_example.rb +25 -25
  148. data/test/test_update.rb +102 -96
  149. data/test/test_validations.rb +13 -13
  150. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2465cca0fa83a628e24f3221e88095690295c99b2bf46818bd2ebd76df8300b5
4
- data.tar.gz: a22c2b61575c26e23e51b314c05c158663c26ce7a9c64fb56019d596edc6a844
3
+ metadata.gz: eeb7ac69a866392d1d19aec7ae67f99af052e72e5585375c2cb73990f442cc28
4
+ data.tar.gz: 6552f1e74d6ab9a40aadd66ea78e8d6c489e6d793a47cc52ab2582f60dfbced7
5
5
  SHA512:
6
- metadata.gz: 3147006b49f98c3d1e88dbec56590fad63c13506634427361e14e06d611e75666c89c48c3e9151d174dc075d850a238285be6bc62739d8971d7bf190bc6e9db9
7
- data.tar.gz: 34d811c5ab6afb7d5b4b9dc871b2df660f42abaf146ffc7faa60c9d4d2edfb8c1a8fa6e49b40488a6090a7bb64218fafb6b0e965744b4daa0d11c0fc34605abf
6
+ metadata.gz: 1b0bd53df9177d3569e4646124ff2aaf6bacf4d83a78f287a9e954ed388a37ed4872f4024204e34f7402b7989b401586c53636a551d745e5aaf4871927bb66fb
7
+ data.tar.gz: 8c2eacaaff041c6c4255aed0402f63038d6e0d781665208cbb9b3bdbcc86666087f69822400384f9dfc44215c23be46ddc1c3c69b7ee0008db636d8ff1e0a29c
data/History.rdoc CHANGED
@@ -1,3 +1,17 @@
1
+ == 13.0.2 (2022-01-09)
2
+ * Fix scoped associations take #2 (Charlie Savage)
3
+
4
+ == 13.0.1 (2021-11-14)
5
+ * Fix invalid sql generation for some cases of scoped associations (Ryan Mulligan)
6
+ * Fix unintentional connection to database (Kazuhiro Masuda)
7
+ * Zip values then keys - fixes #548 (Charlie Savage)
8
+
9
+ == 13.0.0 (2021-05-09)
10
+ * Update to ActiveRecord 6.1 (Javier Julio, Charlie Savage, Sammy Larbi)
11
+
12
+ == 12.0.10 (2021-05-09)
13
+ * Support using the #id method on records with primary keys that also have an :id attribute.
14
+
1
15
  == 12.0.9 (2021-02-22)
2
16
  * Third time is hopefully the charm on MySQL/MariaDB auto increment fix
3
17
 
@@ -511,7 +525,7 @@ by replacing quoted identifiers with all-caps equivalents on Oracle (Rhett Sutph
511
525
  * Update Oracle tests (Rhett Sutphin)
512
526
 
513
527
  == 4.1.1 2011-08-31
514
- * Support for AR 3.1.1
528
+ * Support for AR 3.1.1
515
529
  * Make polymorphic belongs_to work in rails 3.1.1 (Tom Hughes)
516
530
  * Eliminate relative paths from the test suite (Rhett Sutphin)
517
531
  * Minor improvements to the CPK test runner w/o relative path changes (Rhett Sutphin)
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 13.x is designed to work with ActiveRecord 6.1.x
23
24
  Version 12.x is designed to work with ActiveRecord 6.0.x
24
25
  Version 11.x is designed to work with ActiveRecord 5.2.x
25
26
  Version 10.x is designed to work with ActiveRecord 5.1.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,19 +1,19 @@
1
- module ActiveModel
2
- module AttributeAssignment
3
- def _assign_attribute(k, v)
4
- # CPK. This is super ugly, but if a table has a composite key where one of the fields is named :id we need
5
- # to handle it as a single value. Otherwise, we would call the id=(value) method which is expecting
6
- # and array of values.
7
- if k == 'id' && self.kind_of?(ActiveRecord::Base) && self.composite? && !self.column_for_attribute(k).null
8
- self._write_attribute(k, v)
9
- else
10
- setter = :"#{k}="
11
- if respond_to?(setter)
12
- public_send(setter, v)
13
- else
14
- raise UnknownAttributeError.new(self, k)
15
- end
16
- end
17
- end
18
- end
19
- end
1
+ module ActiveModel
2
+ module AttributeAssignment
3
+ def _assign_attribute(k, v)
4
+ # CPK. This is super ugly, but if a table has a composite key where one of the fields is named :id we need
5
+ # to handle it as a single value. Otherwise, we would call the id=(value) method which is expecting
6
+ # and array of values.
7
+ if k == 'id' && !v.kind_of?(Array) && self.kind_of?(ActiveRecord::Base) && self.composite? && !self.column_for_attribute(k).null
8
+ self._write_attribute(k, v)
9
+ else
10
+ setter = :"#{k}="
11
+ if respond_to?(setter)
12
+ public_send(setter, v)
13
+ else
14
+ raise UnknownAttributeError.new(self, k)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ 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,69 +1,67 @@
1
- module ActiveRecord
2
- module Associations
3
- class AssociationScope
4
- def self.get_bind_values(owner, chain)
5
- binds = []
6
- last_reflection = chain.last
7
-
8
- # CPK
9
- # binds << last_reflection.join_id_for(owner)
10
- values = last_reflection.join_id_for(owner)
11
- binds += Array(values)
12
-
13
- if last_reflection.type
14
- binds << owner.class.polymorphic_name
15
- end
16
-
17
- chain.each_cons(2).each do |reflection, next_reflection|
18
- if reflection.type
19
- binds << next_reflection.klass.polymorphic_name
20
- end
21
- end
22
- binds
23
- end
24
-
25
- def last_chain_scope(scope, reflection, owner)
26
- join_keys = reflection.join_keys
27
- key = join_keys.key
28
- foreign_key = join_keys.foreign_key
29
-
30
- table = reflection.aliased_table
31
-
32
- # CPK
33
- # value = transform_value(owner[foreign_key])
34
- # scope = apply_scope(scope, table, key, value)
35
- Array(key).zip(Array(foreign_key)).each do |a_join_key, a_foreign_key|
36
- value = transform_value(owner[a_foreign_key])
37
- scope = apply_scope(scope, table, a_join_key, value)
38
- end
39
-
40
- if reflection.type
41
- polymorphic_type = transform_value(owner.class.polymorphic_name)
42
- scope = apply_scope(scope, table, reflection.type, polymorphic_type)
43
- end
44
-
45
- scope
46
- end
47
-
48
- def next_chain_scope(scope, reflection, next_reflection)
49
- join_keys = reflection.join_keys
50
- key = join_keys.key
51
- foreign_key = join_keys.foreign_key
52
-
53
- table = reflection.aliased_table
54
- foreign_table = next_reflection.aliased_table
55
-
56
- # CPK
57
- # constraint = table[key].eq(foreign_table[foreign_key])
58
- constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
59
-
60
- if reflection.type
61
- value = transform_value(next_reflection.klass.polymorphic_name)
62
- scope = apply_scope(scope, table, reflection.type, value)
63
- end
64
-
65
- scope.joins!(join(foreign_table, constraint))
66
- end
67
- end
68
- end
1
+ module ActiveRecord
2
+ module Associations
3
+ class AssociationScope
4
+ def self.get_bind_values(owner, chain)
5
+ binds = []
6
+ last_reflection = chain.last
7
+
8
+ # CPK
9
+ # binds << last_reflection.join_id_for(owner)
10
+ values = last_reflection.join_id_for(owner)
11
+ binds += Array(values)
12
+
13
+ if last_reflection.type
14
+ binds << owner.class.polymorphic_name
15
+ end
16
+
17
+ chain.each_cons(2).each do |reflection, next_reflection|
18
+ if reflection.type
19
+ binds << next_reflection.klass.polymorphic_name
20
+ end
21
+ end
22
+ binds
23
+ end
24
+
25
+ def last_chain_scope(scope, reflection, owner)
26
+ key = reflection.join_primary_key
27
+ foreign_key = reflection.join_foreign_key
28
+
29
+ table = reflection.aliased_table
30
+
31
+ # CPK
32
+ # value = transform_value(owner[foreign_key])
33
+ # scope = apply_scope(scope, table, key, value)
34
+ Array(key).zip(Array(foreign_key)).each do |a_join_key, a_foreign_key|
35
+ value = transform_value(owner[a_foreign_key])
36
+ scope = apply_scope(scope, table, a_join_key, value)
37
+ end
38
+
39
+ if reflection.type
40
+ polymorphic_type = transform_value(owner.class.polymorphic_name)
41
+ scope = apply_scope(scope, table, reflection.type, polymorphic_type)
42
+ end
43
+
44
+ scope
45
+ end
46
+
47
+ def next_chain_scope(scope, reflection, next_reflection)
48
+ key = reflection.join_primary_key
49
+ foreign_key = reflection.join_foreign_key
50
+
51
+ table = reflection.aliased_table
52
+ foreign_table = next_reflection.aliased_table
53
+
54
+ # CPK
55
+ # constraint = table[key].eq(foreign_table[foreign_key])
56
+ constraint = cpk_join_predicate(table, key, foreign_table, foreign_key)
57
+
58
+ if reflection.type
59
+ value = transform_value(next_reflection.klass.polymorphic_name)
60
+ scope = apply_scope(scope, table, reflection.type, value)
61
+ end
62
+
63
+ scope.joins!(join(foreign_table, constraint))
64
+ end
65
+ end
66
+ end
69
67
  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