composite_primary_keys 12.0.9 → 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.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/History.rdoc +894 -877
  3. data/README.rdoc +182 -180
  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 +137 -103
  14. data/lib/composite_primary_keys/associations/preloader/association.rb +68 -53
  15. data/lib/composite_primary_keys/associations/through_association.rb +25 -25
  16. data/lib/composite_primary_keys/attribute_methods/primary_key.rb +0 -2
  17. data/lib/composite_primary_keys/attribute_methods/read.rb +30 -30
  18. data/lib/composite_primary_keys/attribute_methods/write.rb +35 -35
  19. data/lib/composite_primary_keys/attribute_methods.rb +21 -9
  20. data/lib/composite_primary_keys/autosave_association.rb +60 -60
  21. data/lib/composite_primary_keys/base.rb +141 -141
  22. data/lib/composite_primary_keys/composite_arrays.rb +86 -86
  23. data/lib/composite_primary_keys/composite_predicates.rb +71 -69
  24. data/lib/composite_primary_keys/composite_relation.rb +29 -29
  25. data/lib/composite_primary_keys/connection_adapters/abstract/database_statements.rb +37 -37
  26. data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +10 -10
  27. data/lib/composite_primary_keys/connection_adapters/postgresql/database_statements.rb +26 -26
  28. data/lib/composite_primary_keys/connection_adapters/sqlserver/database_statements.rb +44 -44
  29. data/lib/composite_primary_keys/core.rb +48 -48
  30. data/lib/composite_primary_keys/counter_cache.rb +15 -15
  31. data/lib/composite_primary_keys/fixtures.rb +21 -21
  32. data/lib/composite_primary_keys/nested_attributes.rb +1 -1
  33. data/lib/composite_primary_keys/persistence.rb +96 -81
  34. data/lib/composite_primary_keys/reflection.rb +91 -29
  35. data/lib/composite_primary_keys/relation/batches.rb +15 -7
  36. data/lib/composite_primary_keys/relation/calculations.rb +110 -81
  37. data/lib/composite_primary_keys/relation/finder_methods.rb +235 -235
  38. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +39 -20
  39. data/lib/composite_primary_keys/relation/query_methods.rb +42 -42
  40. data/lib/composite_primary_keys/relation/where_clause.rb +18 -23
  41. data/lib/composite_primary_keys/relation.rb +197 -193
  42. data/lib/composite_primary_keys/sanitization.rb +42 -42
  43. data/lib/composite_primary_keys/table_metadata.rb +11 -0
  44. data/lib/composite_primary_keys/transactions.rb +34 -34
  45. data/lib/composite_primary_keys/validations/uniqueness.rb +31 -31
  46. data/lib/composite_primary_keys/version.rb +8 -8
  47. data/lib/composite_primary_keys.rb +119 -117
  48. data/scripts/console.rb +48 -48
  49. data/scripts/txt2html +76 -76
  50. data/scripts/txt2js +65 -65
  51. data/tasks/databases/mysql.rake +40 -40
  52. data/tasks/databases/oracle.rake +41 -41
  53. data/tasks/databases/postgresql.rake +38 -38
  54. data/tasks/databases/sqlite.rake +25 -25
  55. data/tasks/databases/sqlserver.rake +43 -43
  56. data/tasks/website.rake +18 -18
  57. data/test/README_tests.rdoc +56 -56
  58. data/test/abstract_unit.rb +118 -114
  59. data/test/connections/connection_spec.rb +27 -27
  60. data/test/connections/databases.ci.yml +22 -22
  61. data/test/connections/databases.example.yml +40 -40
  62. data/test/connections/databases.yml +40 -39
  63. data/test/fixtures/article.rb +10 -10
  64. data/test/fixtures/articles.yml +7 -7
  65. data/test/fixtures/capitol.rb +3 -3
  66. data/test/fixtures/capitols.yml +16 -16
  67. data/test/fixtures/comment.rb +5 -5
  68. data/test/fixtures/comments.yml +17 -17
  69. data/test/fixtures/db_definitions/db2-create-tables.sql +112 -112
  70. data/test/fixtures/db_definitions/db2-drop-tables.sql +16 -16
  71. data/test/fixtures/db_definitions/mysql.sql +180 -180
  72. data/test/fixtures/db_definitions/oracle.drop.sql +41 -41
  73. data/test/fixtures/db_definitions/oracle.sql +199 -199
  74. data/test/fixtures/db_definitions/postgresql.sql +182 -182
  75. data/test/fixtures/db_definitions/sqlite.sql +169 -169
  76. data/test/fixtures/db_definitions/sqlserver.sql +176 -176
  77. data/test/fixtures/department.rb +16 -16
  78. data/test/fixtures/departments.yml +19 -15
  79. data/test/fixtures/dorm.rb +2 -2
  80. data/test/fixtures/dorms.yml +4 -4
  81. data/test/fixtures/employee.rb +5 -5
  82. data/test/fixtures/employees.yml +33 -28
  83. data/test/fixtures/group.rb +2 -2
  84. data/test/fixtures/groups.yml +6 -6
  85. data/test/fixtures/membership.rb +8 -6
  86. data/test/fixtures/membership_status.rb +2 -2
  87. data/test/fixtures/membership_statuses.yml +16 -16
  88. data/test/fixtures/memberships.yml +10 -10
  89. data/test/fixtures/product.rb +9 -9
  90. data/test/fixtures/product_tariff.rb +5 -5
  91. data/test/fixtures/product_tariffs.yml +14 -14
  92. data/test/fixtures/products.yml +11 -11
  93. data/test/fixtures/reading.rb +4 -4
  94. data/test/fixtures/readings.yml +10 -10
  95. data/test/fixtures/reference_code.rb +7 -7
  96. data/test/fixtures/reference_codes.yml +28 -28
  97. data/test/fixtures/reference_type.rb +12 -12
  98. data/test/fixtures/reference_types.yml +9 -9
  99. data/test/fixtures/restaurant.rb +9 -9
  100. data/test/fixtures/restaurants.yml +14 -14
  101. data/test/fixtures/restaurants_suburb.rb +2 -2
  102. data/test/fixtures/restaurants_suburbs.yml +10 -10
  103. data/test/fixtures/room.rb +11 -11
  104. data/test/fixtures/room_assignment.rb +13 -13
  105. data/test/fixtures/room_assignments.yml +24 -24
  106. data/test/fixtures/room_attribute.rb +2 -2
  107. data/test/fixtures/room_attribute_assignment.rb +4 -4
  108. data/test/fixtures/room_attribute_assignments.yml +4 -4
  109. data/test/fixtures/room_attributes.yml +2 -2
  110. data/test/fixtures/rooms.yml +12 -12
  111. data/test/fixtures/street.rb +2 -2
  112. data/test/fixtures/streets.yml +16 -16
  113. data/test/fixtures/student.rb +3 -3
  114. data/test/fixtures/students.yml +15 -15
  115. data/test/fixtures/suburb.rb +5 -5
  116. data/test/fixtures/suburbs.yml +14 -14
  117. data/test/fixtures/tariff.rb +5 -5
  118. data/test/fixtures/tariffs.yml +14 -14
  119. data/test/fixtures/topic_sources.yml +3 -3
  120. data/test/fixtures/topics.yml +8 -8
  121. data/test/fixtures/user.rb +11 -11
  122. data/test/fixtures/users.yml +10 -10
  123. data/test/plugins/pagination.rb +405 -405
  124. data/test/plugins/pagination_helper.rb +135 -135
  125. data/test/test_associations.rb +372 -358
  126. data/test/test_attribute_methods.rb +63 -63
  127. data/test/test_attributes.rb +75 -60
  128. data/test/test_calculations.rb +49 -42
  129. data/test/test_callbacks.rb +99 -99
  130. data/test/test_composite_arrays.rb +38 -38
  131. data/test/test_counter_cache.rb +30 -30
  132. data/test/test_create.rb +218 -206
  133. data/test/test_delete.rb +188 -179
  134. data/test/test_dumpable.rb +15 -15
  135. data/test/test_dup.rb +37 -37
  136. data/test/test_equal.rb +26 -26
  137. data/test/test_exists.rb +39 -39
  138. data/test/test_find.rb +170 -164
  139. data/test/test_habtm.rb +141 -141
  140. data/test/test_ids.rb +112 -112
  141. data/test/test_miscellaneous.rb +32 -32
  142. data/test/test_nested_attributes.rb +67 -67
  143. data/test/test_optimistic.rb +18 -18
  144. data/test/test_pagination.rb +35 -35
  145. data/test/test_polymorphic.rb +43 -43
  146. data/test/test_predicates.rb +59 -59
  147. data/test/test_preload.rb +102 -102
  148. data/test/test_santiago.rb +23 -23
  149. data/test/test_touch.rb +23 -23
  150. data/test/test_tutorial_example.rb +25 -25
  151. data/test/test_update.rb +102 -96
  152. data/test/test_validations.rb +13 -13
  153. metadata +7 -6
@@ -1,37 +1,37 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module DatabaseStatements
4
- def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
5
- sql, binds = to_sql_and_binds(arel, binds)
6
- value = exec_insert(sql, name, binds, pk, sequence_name)
7
-
8
- return id_value if id_value
9
-
10
- if pk.is_a?(Array) && !value.empty?
11
- # This is a CPK model and the query result is not empty. Thus we can figure out the new ids for each
12
- # auto incremented field
13
- pk.map {|key| value.first[key]}
14
- elsif pk.is_a?(Array)
15
- # This is CPK, but we don't know what autoincremented fields were updated.
16
- result = Array.new(pk.size)
17
-
18
- # Is there an autoincrementing field?
19
- auto_key = pk.find do |key|
20
- attribute = arel.ast.relation[key]
21
- column = column_for_attribute(attribute)
22
- if column.respond_to?(:auto_increment?)
23
- column.auto_increment?
24
- end
25
- end
26
-
27
- if auto_key
28
- result[pk.index(auto_key)] = last_inserted_id(value)
29
- end
30
- result
31
- else
32
- last_inserted_id(value)
33
- end
34
- end
35
- end
36
- end
37
- end
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module DatabaseStatements
4
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
5
+ sql, binds = to_sql_and_binds(arel, binds)
6
+ value = exec_insert(sql, name, binds, pk, sequence_name)
7
+
8
+ return id_value if id_value
9
+
10
+ if pk.is_a?(Array) && !value.empty?
11
+ # This is a CPK model and the query result is not empty. Thus we can figure out the new ids for each
12
+ # auto incremented field
13
+ pk.map {|key| value.first[key]}
14
+ elsif pk.is_a?(Array)
15
+ # This is CPK, but we don't know what autoincremented fields were updated.
16
+ result = Array.new(pk.size)
17
+
18
+ # Is there an autoincrementing field?
19
+ auto_key = pk.find do |key|
20
+ attribute = arel.ast.relation[key]
21
+ column = column_for_attribute(attribute)
22
+ if column.respond_to?(:auto_increment?)
23
+ column.auto_increment?
24
+ end
25
+ end
26
+
27
+ if auto_key
28
+ result[pk.index(auto_key)] = last_inserted_id(value)
29
+ end
30
+ result
31
+ else
32
+ last_inserted_id(value)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,11 +1,11 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- class AbstractAdapter
4
- def quote_column_names(name)
5
- Array(name).map do |col|
6
- quote_column_name(col.to_s)
7
- end.to_composite_keys.to_s
8
- end
9
- end
10
- end
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class AbstractAdapter
4
+ def quote_column_names(name)
5
+ Array(name).map do |col|
6
+ quote_column_name(col.to_s)
7
+ end.to_composite_keys.to_s
8
+ end
9
+ end
10
+ end
11
11
  end
@@ -1,26 +1,26 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module PostgreSQL
4
- module DatabaseStatements
5
- def sql_for_insert(sql, pk, binds) # :nodoc:
6
- if pk.nil?
7
- # Extract the table from the insert sql. Yuck.
8
- table_ref = extract_table_ref_from_insert_sql(sql)
9
- pk = primary_key(table_ref) if table_ref
10
- end
11
-
12
- # CPK
13
- # if pk = suppress_composite_primary_key(pk)
14
- # sql = "#{sql} RETURNING #{quote_column_name(pk)}"
15
- #end
16
- # NOTE pk can be false.
17
- if pk
18
- sql = "#{sql} RETURNING #{quote_column_names(pk)}"
19
- end
20
-
21
- super
22
- end
23
- end
24
- end
25
- end
26
- end
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module PostgreSQL
4
+ module DatabaseStatements
5
+ def sql_for_insert(sql, pk, binds) # :nodoc:
6
+ if pk.nil?
7
+ # Extract the table from the insert sql. Yuck.
8
+ table_ref = extract_table_ref_from_insert_sql(sql)
9
+ pk = primary_key(table_ref) if table_ref
10
+ end
11
+
12
+ # CPK
13
+ # if pk = suppress_composite_primary_key(pk)
14
+ # sql = "#{sql} RETURNING #{quote_column_name(pk)}"
15
+ #end
16
+ # NOTE pk can be false.
17
+ if pk
18
+ sql = "#{sql} RETURNING #{quote_column_names(pk)}"
19
+ end
20
+
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,44 +1,44 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- module SQLServer
4
- module DatabaseStatements
5
- def sql_for_insert(sql, pk, binds)
6
- if pk.nil?
7
- table_name = query_requires_identity_insert?(sql)
8
- pk = primary_key(table_name)
9
- end
10
-
11
- sql = if pk && use_output_inserted? && !database_prefix_remote_server?
12
- # CPK
13
- #quoted_pk = SQLServer::Utils.extract_identifiers(pk).quoted
14
- quoted_pk = Array(pk).map {|subkey| SQLServer::Utils.extract_identifiers(subkey).quoted}
15
-
16
- table_name ||= get_table_name(sql)
17
- exclude_output_inserted = exclude_output_inserted_table_name?(table_name, sql)
18
- if exclude_output_inserted
19
- id_sql_type = exclude_output_inserted.is_a?(TrueClass) ? "bigint" : exclude_output_inserted
20
- # CPK
21
- # <<~SQL.squish
22
- # DECLARE @ssaIdInsertTable table (#{quoted_pk} #{id_sql_type});
23
- # #{sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk} INTO @ssaIdInsertTable"}
24
- # SELECT CAST(#{quoted_pk.join(',')} AS #{id_sql_type}) FROM @ssaIdInsertTable
25
- # SQL
26
- <<~SQL.squish
27
- DECLARE @ssaIdInsertTable table (#{quoted_pk.map {|subkey| "#{subkey} #{id_sql_type}"}.join(", ")});
28
- #{sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk.join(', INSERTED.')} INTO @ssaIdInsertTable"}
29
- SELECT #{quoted_pk.map {|subkey| "CAST(#{subkey} AS #{id_sql_type}) #{subkey}"}.join(", ")} FROM @ssaIdInsertTable
30
- SQL
31
- else
32
- # CPK
33
- # sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk}"
34
- sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk.join(', INSERTED.')}"
35
- end
36
- else
37
- "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"
38
- end
39
- super
40
- end
41
- end
42
- end
43
- end
44
- end
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module SQLServer
4
+ module DatabaseStatements
5
+ def sql_for_insert(sql, pk, binds)
6
+ if pk.nil?
7
+ table_name = query_requires_identity_insert?(sql)
8
+ pk = primary_key(table_name)
9
+ end
10
+
11
+ sql = if pk && use_output_inserted? && !database_prefix_remote_server?
12
+ # CPK
13
+ #quoted_pk = SQLServer::Utils.extract_identifiers(pk).quoted
14
+ quoted_pk = Array(pk).map {|subkey| SQLServer::Utils.extract_identifiers(subkey).quoted}
15
+
16
+ table_name ||= get_table_name(sql)
17
+ exclude_output_inserted = exclude_output_inserted_table_name?(table_name, sql)
18
+ if exclude_output_inserted
19
+ id_sql_type = exclude_output_inserted.is_a?(TrueClass) ? "bigint" : exclude_output_inserted
20
+ # CPK
21
+ # <<~SQL.squish
22
+ # DECLARE @ssaIdInsertTable table (#{quoted_pk} #{id_sql_type});
23
+ # #{sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk} INTO @ssaIdInsertTable"}
24
+ # SELECT CAST(#{quoted_pk.join(',')} AS #{id_sql_type}) FROM @ssaIdInsertTable
25
+ # SQL
26
+ <<~SQL.squish
27
+ DECLARE @ssaIdInsertTable table (#{quoted_pk.map {|subkey| "#{subkey} #{id_sql_type}"}.join(", ")});
28
+ #{sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk.join(', INSERTED.')} INTO @ssaIdInsertTable"}
29
+ SELECT #{quoted_pk.map {|subkey| "CAST(#{subkey} AS #{id_sql_type}) #{subkey}"}.join(", ")} FROM @ssaIdInsertTable
30
+ SQL
31
+ else
32
+ # CPK
33
+ # sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk}"
34
+ sql.dup.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk.join(', INSERTED.')}"
35
+ end
36
+ else
37
+ "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"
38
+ end
39
+ super
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,49 +1,49 @@
1
- module ActiveRecord
2
- module Core
3
- def initialize_dup(other) # :nodoc:
4
- @attributes = @attributes.deep_dup
5
- # CPK
6
- #@attributes.reset(@primary_key)
7
- Array(self.class.primary_key).each {|key| @attributes.reset(key)}
8
-
9
- _run_initialize_callbacks
10
-
11
- @new_record = true
12
- @destroyed = false
13
- @_start_transaction_state = nil
14
- @transaction_state = nil
15
-
16
- super
17
- end
18
-
19
- module ClassMethods
20
- def find(*ids) # :nodoc:
21
- # We don't have cache keys for this stuff yet
22
- return super unless ids.length == 1
23
- return super if block_given? ||
24
- primary_key.nil? ||
25
- scope_attributes? ||
26
- columns_hash.key?(inheritance_column) && !base_class?
27
-
28
- # CPK
29
- return super if self.composite?
30
-
31
- id = ids.first
32
-
33
- return super if StatementCache.unsupported_value?(id)
34
-
35
- key = primary_key
36
-
37
- statement = cached_find_by_statement(key) { |params|
38
- where(key => params.bind).limit(1)
39
- }
40
-
41
- record = statement.execute([id], connection)&.first
42
- unless record
43
- raise ::ActiveRecord::RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
44
- end
45
- record
46
- end
47
- end
48
- end
1
+ module ActiveRecord
2
+ module Core
3
+ def initialize_dup(other) # :nodoc:
4
+ @attributes = @attributes.deep_dup
5
+ # CPK
6
+ #@attributes.reset(@primary_key)
7
+ Array(self.class.primary_key).each {|key| @attributes.reset(key)}
8
+
9
+ _run_initialize_callbacks
10
+
11
+ @new_record = true
12
+ @destroyed = false
13
+ @_start_transaction_state = nil
14
+ @transaction_state = nil
15
+
16
+ super
17
+ end
18
+
19
+ module ClassMethods
20
+ def find(*ids) # :nodoc:
21
+ # We don't have cache keys for this stuff yet
22
+ return super unless ids.length == 1
23
+ return super if block_given? ||
24
+ primary_key.nil? ||
25
+ scope_attributes? ||
26
+ columns_hash.key?(inheritance_column) && !base_class?
27
+
28
+ # CPK
29
+ return super if self.composite?
30
+
31
+ id = ids.first
32
+
33
+ return super if StatementCache.unsupported_value?(id)
34
+
35
+ key = primary_key
36
+
37
+ statement = cached_find_by_statement(key) { |params|
38
+ where(key => params.bind).limit(1)
39
+ }
40
+
41
+ record = statement.execute([id], connection)&.first
42
+ unless record
43
+ raise ::ActiveRecord::RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
44
+ end
45
+ record
46
+ end
47
+ end
48
+ end
49
49
  end
@@ -1,15 +1,15 @@
1
- module ActiveRecord
2
- module CounterCache
3
- module ClassMethods
4
- def update_counters(id, counters)
5
- # CPK
6
- if self.composite?
7
- predicate = cpk_id_predicate(self.arel_table, primary_key, id)
8
- unscoped.where!(predicate).update_counters(counters)
9
- else
10
- unscoped.where!(primary_key => id).update_counters(counters)
11
- end
12
- end
13
- end
14
- end
15
- end
1
+ module ActiveRecord
2
+ module CounterCache
3
+ module ClassMethods
4
+ def update_counters(id, counters)
5
+ # CPK
6
+ if self.composite?
7
+ predicate = cpk_id_predicate(self.arel_table, primary_key, id)
8
+ unscoped.where!(predicate).update_counters(counters)
9
+ else
10
+ unscoped.where!(primary_key => id).update_counters(counters)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,21 +1,21 @@
1
- module ActiveRecord
2
- class Fixture
3
- def find
4
- raise FixtureClassNotFound, "No class attached to find." unless model_class
5
- model_class.unscoped do
6
- # CPK
7
- #model_class.find(fixture[model_class.primary_key])
8
- ids = self.ids(model_class.primary_key)
9
- model_class.find(ids)
10
- end
11
- end
12
-
13
- def ids(key)
14
- if key.is_a? Array
15
- key.map {|a_key| fixture[a_key.to_s] }
16
- else
17
- fixture[key]
18
- end
19
- end
20
- end
21
- end
1
+ module ActiveRecord
2
+ class Fixture
3
+ def find
4
+ raise FixtureClassNotFound, "No class attached to find." unless model_class
5
+ model_class.unscoped do
6
+ # CPK
7
+ #model_class.find(fixture[model_class.primary_key])
8
+ ids = self.ids(model_class.primary_key)
9
+ model_class.find(ids)
10
+ end
11
+ end
12
+
13
+ def ids(key)
14
+ if key.is_a? Array
15
+ key.map {|a_key| fixture[a_key.to_s] }
16
+ else
17
+ fixture[key]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -70,7 +70,7 @@ module ActiveRecord
70
70
  if target_record
71
71
  existing_record = target_record
72
72
  else
73
- association.add_to_target(existing_record, :skip_callbacks)
73
+ association.add_to_target(existing_record, skip_callbacks: true)
74
74
  end
75
75
 
76
76
  assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
@@ -1,81 +1,96 @@
1
- module ActiveRecord
2
- module Persistence
3
- module ClassMethods
4
- def delete(id_or_array)
5
- # CPK
6
- if self.composite?
7
- id_or_array = if id_or_array.is_a?(CompositePrimaryKeys::CompositeKeys)
8
- [id_or_array]
9
- else
10
- Array(id_or_array)
11
- end
12
-
13
- id_or_array.each do |id|
14
- # Is the passed in id actually a record?
15
- id = id.kind_of?(::ActiveRecord::Base) ? id.id : id
16
- delete_by(cpk_id_predicate(self.arel_table, self.primary_key, id))
17
- end
18
- else
19
- delete_by(primary_key => id_or_array)
20
- end
21
- end
22
-
23
- def _update_record(values, constraints) # :nodoc:
24
- # CPK
25
- if self.composite? && constraints[primary_key]
26
- primary_key_values = constraints.delete(primary_key)
27
- primary_key.each_with_index do |key, i|
28
- constraints[key] = primary_key_values[i]
29
- end
30
- end
31
-
32
- constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
33
-
34
- um = arel_table.where(
35
- constraints.reduce(&:and)
36
- ).compile_update(_substitute_values(values), primary_key)
37
-
38
- connection.update(um, "#{self} Update")
39
- end
40
-
41
- def _delete_record(constraints) # :nodoc:
42
- # CPK
43
- if self.composite? && constraints[primary_key]
44
- primary_key_values = constraints.delete(primary_key)
45
- primary_key.each_with_index do |key, i|
46
- constraints[key] = primary_key_values[i]
47
- end
48
- end
49
-
50
- constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) }
51
-
52
- dm = Arel::DeleteManager.new
53
- dm.from(arel_table)
54
- dm.wheres = constraints
55
-
56
- connection.delete(dm, "#{self} Destroy")
57
- end
58
- end
59
-
60
- def _create_record(attribute_names = self.attribute_names)
61
- attribute_names = attributes_for_create(attribute_names)
62
-
63
- new_id = self.class._insert_record(
64
- attributes_with_values(attribute_names)
65
- )
66
-
67
- # CPK
68
- if self.composite?
69
- self.id = self.id.zip(Array(new_id)).map {|id1, id2| id2.nil? ? id1 : id2}
70
- else
71
- self.id ||= new_id if self.class.primary_key
72
- end
73
-
74
- @new_record = false
75
-
76
- yield(self) if block_given?
77
-
78
- id
79
- end
80
- end
81
- end
1
+ module ActiveRecord
2
+ module Persistence
3
+ module ClassMethods
4
+ def delete(id_or_array)
5
+ # CPK
6
+ if self.composite?
7
+ id_or_array = if id_or_array.is_a?(CompositePrimaryKeys::CompositeKeys)
8
+ [id_or_array]
9
+ else
10
+ Array(id_or_array)
11
+ end
12
+
13
+ # Delete should return the number of deleted records
14
+ id_or_array.map do |id|
15
+ # Is the passed in id actually a record?
16
+ id = id.kind_of?(::ActiveRecord::Base) ? id.id : id
17
+ delete_by(cpk_id_predicate(self.arel_table, self.primary_key, id))
18
+ end.sum
19
+ else
20
+ delete_by(primary_key => id_or_array)
21
+ end
22
+ end
23
+
24
+ def _update_record(values, constraints) # :nodoc:
25
+ # CPK
26
+ if self.composite? && constraints[primary_key]
27
+ primary_key_values = constraints.delete(primary_key)
28
+ primary_key.each_with_index do |key, i|
29
+ constraints[key] = primary_key_values[i]
30
+ end
31
+ end
32
+
33
+ constraints = constraints.map { |name, value| predicate_builder[name, value] }
34
+
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
45
+
46
+ connection.update(um, "#{self} Update")
47
+ end
48
+
49
+ def _delete_record(constraints) # :nodoc:
50
+ # CPK
51
+ if self.composite? && constraints[primary_key]
52
+ primary_key_values = constraints.delete(primary_key)
53
+ primary_key.each_with_index do |key, i|
54
+ constraints[key] = primary_key_values[i]
55
+ end
56
+ end
57
+
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
66
+
67
+ dm = Arel::DeleteManager.new(arel_table)
68
+ dm.wheres = constraints
69
+
70
+ connection.delete(dm, "#{self} Destroy")
71
+ end
72
+ end
73
+
74
+ def _create_record(attribute_names = self.attribute_names)
75
+ attribute_names = attributes_for_create(attribute_names)
76
+
77
+ new_id = self.class._insert_record(
78
+ attributes_with_values(attribute_names)
79
+ )
80
+
81
+ # CPK
82
+ if self.composite?
83
+ self.id = self.id.zip(Array(new_id)).map {|id1, id2| id2.nil? ? id1 : id2}
84
+ else
85
+ self.id ||= new_id if self.class.primary_key
86
+ end
87
+
88
+ @new_record = false
89
+ @previously_new_record = true
90
+
91
+ yield(self) if block_given?
92
+
93
+ id
94
+ end
95
+ end
96
+ end