activerecord 5.0.7 → 5.1.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (219) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +657 -2080
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record/aggregations.rb +244 -244
  8. data/lib/active_record/association_relation.rb +5 -5
  9. data/lib/active_record/associations/alias_tracker.rb +10 -11
  10. data/lib/active_record/associations/association.rb +23 -5
  11. data/lib/active_record/associations/association_scope.rb +95 -81
  12. data/lib/active_record/associations/belongs_to_association.rb +7 -4
  13. data/lib/active_record/associations/builder/belongs_to.rb +30 -16
  14. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  16. data/lib/active_record/associations/collection_association.rb +36 -205
  17. data/lib/active_record/associations/collection_proxy.rb +132 -63
  18. data/lib/active_record/associations/has_many_association.rb +10 -19
  19. data/lib/active_record/associations/has_many_through_association.rb +12 -4
  20. data/lib/active_record/associations/has_one_association.rb +24 -28
  21. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  22. data/lib/active_record/associations/join_dependency/join_association.rb +4 -28
  23. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  24. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  25. data/lib/active_record/associations/join_dependency.rb +121 -118
  26. data/lib/active_record/associations/preloader/association.rb +64 -64
  27. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  28. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  29. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  30. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  31. data/lib/active_record/associations/preloader/through_association.rb +41 -41
  32. data/lib/active_record/associations/preloader.rb +94 -94
  33. data/lib/active_record/associations/singular_association.rb +8 -25
  34. data/lib/active_record/associations/through_association.rb +2 -5
  35. data/lib/active_record/associations.rb +1591 -1562
  36. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute_assignment.rb +61 -61
  39. data/lib/active_record/attribute_decorators.rb +35 -13
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +229 -46
  42. data/lib/active_record/attribute_methods/primary_key.rb +74 -73
  43. data/lib/active_record/attribute_methods/read.rb +39 -35
  44. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  46. data/lib/active_record/attribute_methods/write.rb +30 -33
  47. data/lib/active_record/attribute_methods.rb +56 -65
  48. data/lib/active_record/attribute_mutation_tracker.rb +63 -11
  49. data/lib/active_record/attribute_set/builder.rb +27 -33
  50. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  51. data/lib/active_record/attribute_set.rb +9 -6
  52. data/lib/active_record/attributes.rb +22 -22
  53. data/lib/active_record/autosave_association.rb +18 -13
  54. data/lib/active_record/base.rb +24 -22
  55. data/lib/active_record/callbacks.rb +56 -14
  56. data/lib/active_record/coders/yaml_column.rb +9 -11
  57. data/lib/active_record/collection_cache_key.rb +3 -4
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +330 -284
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +39 -37
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +32 -27
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -51
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +10 -20
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +74 -79
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +120 -100
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +49 -43
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +165 -135
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +404 -424
  70. data/lib/active_record/connection_adapters/column.rb +26 -4
  71. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  72. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -28
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +7 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +23 -27
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +32 -53
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +19 -9
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  90. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  91. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
  92. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  96. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +32 -30
  97. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  99. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -35
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +182 -222
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +6 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +7 -5
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +198 -167
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -19
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +32 -0
  116. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +184 -167
  117. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  118. data/lib/active_record/connection_handling.rb +14 -26
  119. data/lib/active_record/core.rb +109 -93
  120. data/lib/active_record/counter_cache.rb +60 -13
  121. data/lib/active_record/define_callbacks.rb +20 -0
  122. data/lib/active_record/dynamic_matchers.rb +80 -79
  123. data/lib/active_record/enum.rb +8 -6
  124. data/lib/active_record/errors.rb +64 -15
  125. data/lib/active_record/explain.rb +1 -2
  126. data/lib/active_record/explain_registry.rb +1 -1
  127. data/lib/active_record/explain_subscriber.rb +7 -4
  128. data/lib/active_record/fixture_set/file.rb +11 -8
  129. data/lib/active_record/fixtures.rb +66 -53
  130. data/lib/active_record/gem_version.rb +1 -1
  131. data/lib/active_record/inheritance.rb +93 -79
  132. data/lib/active_record/integration.rb +7 -7
  133. data/lib/active_record/internal_metadata.rb +3 -16
  134. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  135. data/lib/active_record/locking/optimistic.rb +69 -74
  136. data/lib/active_record/locking/pessimistic.rb +10 -1
  137. data/lib/active_record/log_subscriber.rb +23 -28
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +100 -47
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/migration.rb +153 -155
  142. data/lib/active_record/model_schema.rb +94 -107
  143. data/lib/active_record/nested_attributes.rb +200 -199
  144. data/lib/active_record/null_relation.rb +11 -34
  145. data/lib/active_record/persistence.rb +65 -50
  146. data/lib/active_record/query_cache.rb +2 -6
  147. data/lib/active_record/querying.rb +3 -4
  148. data/lib/active_record/railtie.rb +16 -17
  149. data/lib/active_record/railties/controller_runtime.rb +6 -2
  150. data/lib/active_record/railties/databases.rake +105 -133
  151. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  152. data/lib/active_record/readonly_attributes.rb +2 -2
  153. data/lib/active_record/reflection.rb +154 -108
  154. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  155. data/lib/active_record/relation/batches.rb +80 -51
  156. data/lib/active_record/relation/calculations.rb +169 -162
  157. data/lib/active_record/relation/delegation.rb +32 -31
  158. data/lib/active_record/relation/finder_methods.rb +197 -231
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  161. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  162. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  163. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  165. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  166. data/lib/active_record/relation/predicate_builder.rb +92 -89
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +255 -293
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +80 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/relation.rb +93 -119
  174. data/lib/active_record/result.rb +41 -32
  175. data/lib/active_record/runtime_registry.rb +3 -3
  176. data/lib/active_record/sanitization.rb +176 -192
  177. data/lib/active_record/schema.rb +3 -3
  178. data/lib/active_record/schema_dumper.rb +15 -38
  179. data/lib/active_record/schema_migration.rb +8 -4
  180. data/lib/active_record/scoping/default.rb +90 -90
  181. data/lib/active_record/scoping/named.rb +11 -11
  182. data/lib/active_record/scoping.rb +6 -6
  183. data/lib/active_record/secure_token.rb +2 -2
  184. data/lib/active_record/statement_cache.rb +13 -15
  185. data/lib/active_record/store.rb +31 -32
  186. data/lib/active_record/suppressor.rb +2 -1
  187. data/lib/active_record/table_metadata.rb +9 -5
  188. data/lib/active_record/tasks/database_tasks.rb +65 -55
  189. data/lib/active_record/tasks/mysql_database_tasks.rb +76 -73
  190. data/lib/active_record/tasks/postgresql_database_tasks.rb +72 -47
  191. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  192. data/lib/active_record/timestamp.rb +46 -25
  193. data/lib/active_record/touch_later.rb +1 -2
  194. data/lib/active_record/transactions.rb +97 -109
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +13 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/internal/abstract_json.rb +4 -0
  199. data/lib/active_record/type/serialized.rb +14 -8
  200. data/lib/active_record/type/text.rb +9 -0
  201. data/lib/active_record/type/time.rb +0 -1
  202. data/lib/active_record/type/type_map.rb +11 -15
  203. data/lib/active_record/type/unsigned_integer.rb +15 -0
  204. data/lib/active_record/type.rb +17 -13
  205. data/lib/active_record/type_caster/connection.rb +8 -6
  206. data/lib/active_record/type_caster/map.rb +3 -1
  207. data/lib/active_record/type_caster.rb +2 -2
  208. data/lib/active_record/validations/associated.rb +1 -1
  209. data/lib/active_record/validations/presence.rb +2 -2
  210. data/lib/active_record/validations/uniqueness.rb +8 -39
  211. data/lib/active_record/validations.rb +4 -4
  212. data/lib/active_record/version.rb +1 -1
  213. data/lib/active_record.rb +20 -20
  214. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  215. data/lib/rails/generators/active_record/migration.rb +1 -1
  216. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  217. data/lib/rails/generators/active_record.rb +4 -4
  218. metadata +24 -13
  219. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -8,20 +8,20 @@ module ActiveRecord
8
8
  end
9
9
 
10
10
  def create
11
- raise DatabaseAlreadyExists if File.exist?(configuration['database'])
11
+ raise DatabaseAlreadyExists if File.exist?(configuration["database"])
12
12
 
13
13
  establish_connection configuration
14
14
  connection
15
15
  end
16
16
 
17
17
  def drop
18
- require 'pathname'
19
- path = Pathname.new configuration['database']
18
+ require "pathname"
19
+ path = Pathname.new configuration["database"]
20
20
  file = path.absolute? ? path.to_s : File.join(root, path)
21
21
 
22
22
  FileUtils.rm(file)
23
23
  rescue Errno::ENOENT => error
24
- raise NoDatabaseError.new(error.message, error)
24
+ raise NoDatabaseError.new(error.message)
25
25
  end
26
26
 
27
27
  def purge
@@ -35,25 +35,27 @@ module ActiveRecord
35
35
  connection.encoding
36
36
  end
37
37
 
38
- def structure_dump(filename)
39
- dbfile = configuration['database']
40
- `sqlite3 #{dbfile} .schema > #{filename}`
38
+ def structure_dump(filename, extra_flags)
39
+ dbfile = configuration["database"]
40
+ flags = extra_flags.join(" ") if extra_flags
41
+ `sqlite3 #{flags} #{dbfile} .schema > #{filename}`
41
42
  end
42
43
 
43
- def structure_load(filename)
44
- dbfile = configuration['database']
45
- `sqlite3 #{dbfile} < "#{filename}"`
44
+ def structure_load(filename, extra_flags)
45
+ dbfile = configuration["database"]
46
+ flags = extra_flags.join(" ") if extra_flags
47
+ `sqlite3 #{flags} #{dbfile} < "#{filename}"`
46
48
  end
47
49
 
48
50
  private
49
51
 
50
- def configuration
51
- @configuration
52
- end
52
+ def configuration
53
+ @configuration
54
+ end
53
55
 
54
- def root
55
- @root
56
- end
56
+ def root
57
+ @root
58
+ end
57
59
  end
58
60
  end
59
61
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveRecord
2
3
  # = Active Record \Timestamp
3
4
  #
@@ -51,15 +52,48 @@ module ActiveRecord
51
52
  clear_timestamp_attributes
52
53
  end
53
54
 
55
+ class_methods do
56
+ def touch_attributes_with_time(*names, time: nil)
57
+ attribute_names = timestamp_attributes_for_update_in_model
58
+ attribute_names |= names.map(&:to_s)
59
+ time ||= current_time_from_proper_timezone
60
+ attribute_names.each_with_object({}) { |attr_name, result| result[attr_name] = time }
61
+ end
62
+
63
+ private
64
+ def timestamp_attributes_for_create_in_model
65
+ timestamp_attributes_for_create.select { |c| column_names.include?(c) }
66
+ end
67
+
68
+ def timestamp_attributes_for_update_in_model
69
+ timestamp_attributes_for_update.select { |c| column_names.include?(c) }
70
+ end
71
+
72
+ def all_timestamp_attributes_in_model
73
+ timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
74
+ end
75
+
76
+ def timestamp_attributes_for_create
77
+ ["created_at", "created_on"]
78
+ end
79
+
80
+ def timestamp_attributes_for_update
81
+ ["updated_at", "updated_on"]
82
+ end
83
+
84
+ def current_time_from_proper_timezone
85
+ default_timezone == :utc ? Time.now.utc : Time.now
86
+ end
87
+ end
88
+
54
89
  private
55
90
 
56
91
  def _create_record
57
- if self.record_timestamps
92
+ if record_timestamps
58
93
  current_time = current_time_from_proper_timezone
59
94
 
60
- all_timestamp_attributes.each do |column|
61
- column = column.to_s
62
- if has_attribute?(column) && !attribute_present?(column)
95
+ all_timestamp_attributes_in_model.each do |column|
96
+ if !attribute_present?(column)
63
97
  write_attribute(column, current_time)
64
98
  end
65
99
  end
@@ -73,8 +107,7 @@ module ActiveRecord
73
107
  current_time = current_time_from_proper_timezone
74
108
 
75
109
  timestamp_attributes_for_update_in_model.each do |column|
76
- column = column.to_s
77
- next if attribute_changed?(column)
110
+ next if will_save_change_to_attribute?(column)
78
111
  write_attribute(column, current_time)
79
112
  end
80
113
  end
@@ -82,34 +115,26 @@ module ActiveRecord
82
115
  end
83
116
 
84
117
  def should_record_timestamps?
85
- self.record_timestamps && (!partial_writes? || changed?)
118
+ record_timestamps && (!partial_writes? || has_changes_to_save?)
86
119
  end
87
120
 
88
121
  def timestamp_attributes_for_create_in_model
89
- timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) }
122
+ self.class.send(:timestamp_attributes_for_create_in_model)
90
123
  end
91
124
 
92
125
  def timestamp_attributes_for_update_in_model
93
- timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) }
126
+ self.class.send(:timestamp_attributes_for_update_in_model)
94
127
  end
95
128
 
96
129
  def all_timestamp_attributes_in_model
97
- timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
130
+ self.class.send(:all_timestamp_attributes_in_model)
98
131
  end
99
132
 
100
- def timestamp_attributes_for_update
101
- [:updated_at, :updated_on]
102
- end
103
-
104
- def timestamp_attributes_for_create
105
- [:created_at, :created_on]
106
- end
107
-
108
- def all_timestamp_attributes
109
- timestamp_attributes_for_create + timestamp_attributes_for_update
133
+ def current_time_from_proper_timezone
134
+ self.class.send(:current_time_from_proper_timezone)
110
135
  end
111
136
 
112
- def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update)
137
+ def max_updated_column_timestamp(timestamp_names = self.class.send(:timestamp_attributes_for_update))
113
138
  timestamp_names
114
139
  .map { |attr| self[attr] }
115
140
  .compact
@@ -117,10 +142,6 @@ module ActiveRecord
117
142
  .max
118
143
  end
119
144
 
120
- def current_time_from_proper_timezone
121
- self.class.default_timezone == :utc ? Time.now.utc : Time.now
122
- end
123
-
124
145
  # Clear attributes and changed_attributes
125
146
  def clear_timestamp_attributes
126
147
  all_timestamp_attributes_in_model.each do |attribute_name|
@@ -25,7 +25,7 @@ module ActiveRecord
25
25
  # touch the parents as we are not calling the after_save callbacks
26
26
  self.class.reflect_on_all_associations(:belongs_to).each do |r|
27
27
  if touch = r.options[:touch]
28
- ActiveRecord::Associations::Builder::BelongsTo.touch_record(self, r.foreign_key, r.name, touch, :touch_later)
28
+ ActiveRecord::Associations::Builder::BelongsTo.touch_record(self, changes_to_save, r.foreign_key, r.name, touch, :touch_later)
29
29
  end
30
30
  end
31
31
  end
@@ -58,6 +58,5 @@ module ActiveRecord
58
58
  def belongs_to_touch_method
59
59
  :touch_later
60
60
  end
61
-
62
61
  end
63
62
  end
@@ -11,7 +11,6 @@ module ActiveRecord
11
11
  :before_commit_without_transaction_enrollment,
12
12
  :commit_without_transaction_enrollment,
13
13
  :rollback_without_transaction_enrollment,
14
- terminator: deprecated_false_terminator,
15
14
  scope: [:kind, :name]
16
15
  end
17
16
 
@@ -189,8 +188,8 @@ module ActiveRecord
189
188
  #
190
189
  # === Caveats
191
190
  #
192
- # If you're on MySQL, then do not use DDL operations in nested transactions
193
- # blocks that are emulated with savepoints. That is, do not execute statements
191
+ # If you're on MySQL, then do not use Data Definition Language(DDL) operations in nested
192
+ # transactions blocks that are emulated with savepoints. That is, do not execute statements
194
193
  # like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
195
194
  # releases all savepoints upon executing a DDL operation. When +transaction+
196
195
  # is finished and tries to release the savepoint it created earlier, a
@@ -274,35 +273,25 @@ module ActiveRecord
274
273
  set_callback(:rollback_without_transaction_enrollment, :after, *args, &block)
275
274
  end
276
275
 
277
- def raise_in_transactional_callbacks
278
- ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks is deprecated and will be removed without replacement.')
279
- true
280
- end
281
-
282
- def raise_in_transactional_callbacks=(value)
283
- ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.')
284
- value
285
- end
286
-
287
276
  private
288
277
 
289
- def set_options_for_callbacks!(args, enforced_options = {})
290
- options = args.extract_options!.merge!(enforced_options)
291
- args << options
278
+ def set_options_for_callbacks!(args, enforced_options = {})
279
+ options = args.extract_options!.merge!(enforced_options)
280
+ args << options
292
281
 
293
- if options[:on]
294
- fire_on = Array(options[:on])
295
- assert_valid_transaction_action(fire_on)
296
- options[:if] = Array(options[:if])
297
- options[:if] << "transaction_include_any_action?(#{fire_on})"
282
+ if options[:on]
283
+ fire_on = Array(options[:on])
284
+ assert_valid_transaction_action(fire_on)
285
+ options[:if] = Array(options[:if])
286
+ options[:if].unshift("transaction_include_any_action?(#{fire_on})")
287
+ end
298
288
  end
299
- end
300
289
 
301
- def assert_valid_transaction_action(actions)
302
- if (actions - ACTIONS).any?
303
- raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS}"
290
+ def assert_valid_transaction_action(actions)
291
+ if (actions - ACTIONS).any?
292
+ raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS}"
293
+ end
304
294
  end
305
- end
306
295
  end
307
296
 
308
297
  # See ActiveRecord::Transactions::ClassMethods for detailed documentation.
@@ -407,103 +396,102 @@ module ActiveRecord
407
396
  end
408
397
  end
409
398
 
410
- protected
411
-
412
- # Save the new record state and id of a record so it can be restored later if a transaction fails.
413
- def remember_transaction_record_state #:nodoc:
414
- @_start_transaction_state[:id] = id
415
- @_start_transaction_state.reverse_merge!(
416
- new_record: @new_record,
417
- destroyed: @destroyed,
418
- frozen?: frozen?,
419
- )
420
- @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
421
- end
399
+ private
422
400
 
423
- # Clear the new record state and id of a record.
424
- def clear_transaction_record_state #:nodoc:
425
- @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
426
- force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
427
- end
401
+ # Save the new record state and id of a record so it can be restored later if a transaction fails.
402
+ def remember_transaction_record_state
403
+ @_start_transaction_state[:id] = id
404
+ @_start_transaction_state.reverse_merge!(
405
+ new_record: @new_record,
406
+ destroyed: @destroyed,
407
+ frozen?: frozen?,
408
+ )
409
+ @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
410
+ end
428
411
 
429
- # Force to clear the transaction record state.
430
- def force_clear_transaction_record_state #:nodoc:
431
- @_start_transaction_state.clear
432
- end
412
+ # Clear the new record state and id of a record.
413
+ def clear_transaction_record_state
414
+ @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
415
+ force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
416
+ end
433
417
 
434
- # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
435
- def restore_transaction_record_state(force = false) #:nodoc:
436
- unless @_start_transaction_state.empty?
437
- transaction_level = (@_start_transaction_state[:level] || 0) - 1
438
- if transaction_level < 1 || force
439
- restore_state = @_start_transaction_state
440
- thaw
441
- @new_record = restore_state[:new_record]
442
- @destroyed = restore_state[:destroyed]
443
- pk = self.class.primary_key
444
- if pk && read_attribute(pk) != restore_state[:id]
445
- write_attribute(pk, restore_state[:id])
418
+ # Force to clear the transaction record state.
419
+ def force_clear_transaction_record_state
420
+ @_start_transaction_state.clear
421
+ end
422
+
423
+ # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
424
+ def restore_transaction_record_state(force = false)
425
+ unless @_start_transaction_state.empty?
426
+ transaction_level = (@_start_transaction_state[:level] || 0) - 1
427
+ if transaction_level < 1 || force
428
+ restore_state = @_start_transaction_state
429
+ thaw
430
+ @new_record = restore_state[:new_record]
431
+ @destroyed = restore_state[:destroyed]
432
+ pk = self.class.primary_key
433
+ if pk && read_attribute(pk) != restore_state[:id]
434
+ write_attribute(pk, restore_state[:id])
435
+ end
436
+ freeze if restore_state[:frozen?]
446
437
  end
447
- freeze if restore_state[:frozen?]
448
438
  end
449
439
  end
450
- end
451
440
 
452
- # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
453
- def transaction_record_state(state) #:nodoc:
454
- @_start_transaction_state[state]
455
- end
441
+ # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
442
+ def transaction_record_state(state)
443
+ @_start_transaction_state[state]
444
+ end
456
445
 
457
- # Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
458
- def transaction_include_any_action?(actions) #:nodoc:
459
- actions.any? do |action|
460
- case action
461
- when :create
462
- transaction_record_state(:new_record)
463
- when :destroy
464
- destroyed?
465
- when :update
466
- !(transaction_record_state(:new_record) || destroyed?)
446
+ # Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
447
+ def transaction_include_any_action?(actions)
448
+ actions.any? do |action|
449
+ case action
450
+ when :create
451
+ transaction_record_state(:new_record)
452
+ when :destroy
453
+ defined?(@_trigger_destroy_callback) && @_trigger_destroy_callback
454
+ when :update
455
+ !(transaction_record_state(:new_record) || destroyed?) &&
456
+ (defined?(@_trigger_update_callback) && @_trigger_update_callback)
457
+ end
467
458
  end
468
459
  end
469
- end
470
-
471
- private
472
460
 
473
- def set_transaction_state(state) # :nodoc:
474
- @transaction_state = state
475
- end
461
+ def set_transaction_state(state)
462
+ @transaction_state = state
463
+ end
476
464
 
477
- def has_transactional_callbacks? # :nodoc:
478
- !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
479
- end
465
+ def has_transactional_callbacks?
466
+ !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
467
+ end
480
468
 
481
- # Updates the attributes on this particular Active Record object so that
482
- # if it's associated with a transaction, then the state of the Active Record
483
- # object will be updated to reflect the current state of the transaction
484
- #
485
- # The +@transaction_state+ variable stores the states of the associated
486
- # transaction. This relies on the fact that a transaction can only be in
487
- # one rollback or commit (otherwise a list of states would be required)
488
- # Each Active Record object inside of a transaction carries that transaction's
489
- # TransactionState.
490
- #
491
- # This method checks to see if the ActiveRecord object's state reflects
492
- # the TransactionState, and rolls back or commits the Active Record object
493
- # as appropriate.
494
- #
495
- # Since Active Record objects can be inside multiple transactions, this
496
- # method recursively goes through the parent of the TransactionState and
497
- # checks if the Active Record object reflects the state of the object.
498
- def sync_with_transaction_state
499
- update_attributes_from_transaction_state(@transaction_state)
500
- end
469
+ # Updates the attributes on this particular Active Record object so that
470
+ # if it's associated with a transaction, then the state of the Active Record
471
+ # object will be updated to reflect the current state of the transaction.
472
+ #
473
+ # The +@transaction_state+ variable stores the states of the associated
474
+ # transaction. This relies on the fact that a transaction can only be in
475
+ # one rollback or commit (otherwise a list of states would be required).
476
+ # Each Active Record object inside of a transaction carries that transaction's
477
+ # TransactionState.
478
+ #
479
+ # This method checks to see if the ActiveRecord object's state reflects
480
+ # the TransactionState, and rolls back or commits the Active Record object
481
+ # as appropriate.
482
+ #
483
+ # Since Active Record objects can be inside multiple transactions, this
484
+ # method recursively goes through the parent of the TransactionState and
485
+ # checks if the Active Record object reflects the state of the object.
486
+ def sync_with_transaction_state
487
+ update_attributes_from_transaction_state(@transaction_state)
488
+ end
501
489
 
502
- def update_attributes_from_transaction_state(transaction_state)
503
- if transaction_state && transaction_state.finalized?
504
- restore_transaction_record_state if transaction_state.rolledback?
505
- clear_transaction_record_state
490
+ def update_attributes_from_transaction_state(transaction_state)
491
+ if transaction_state && transaction_state.finalized?
492
+ restore_transaction_record_state if transaction_state.rolledback?
493
+ clear_transaction_record_state
494
+ end
506
495
  end
507
- end
508
496
  end
509
497
  end
@@ -1,4 +1,4 @@
1
- require 'active_model/type/registry'
1
+ require "active_model/type/registry"
2
2
 
3
3
  module ActiveRecord
4
4
  # :stopdoc:
@@ -10,15 +10,15 @@ module ActiveRecord
10
10
 
11
11
  private
12
12
 
13
- def registration_klass
14
- Registration
15
- end
13
+ def registration_klass
14
+ Registration
15
+ end
16
16
 
17
- def find_registration(symbol, *args)
18
- registrations
19
- .select { |registration| registration.matches?(symbol, *args) }
20
- .max
21
- end
17
+ def find_registration(symbol, *args)
18
+ registrations
19
+ .select { |registration| registration.matches?(symbol, *args) }
20
+ .max
21
+ end
22
22
  end
23
23
 
24
24
  class Registration
@@ -50,44 +50,46 @@ module ActiveRecord
50
50
  priority <=> other.priority
51
51
  end
52
52
 
53
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
54
+ # Workaround for Ruby 2.2 "private attribute?" warning.
53
55
  protected
54
56
 
55
- attr_reader :name, :block, :adapter, :override
56
-
57
- def priority
58
- result = 0
59
- if adapter
60
- result |= 1
61
- end
62
- if override
63
- result |= 2
57
+ attr_reader :name, :block, :adapter, :override
58
+
59
+ def priority
60
+ result = 0
61
+ if adapter
62
+ result |= 1
63
+ end
64
+ if override
65
+ result |= 2
66
+ end
67
+ result
64
68
  end
65
- result
66
- end
67
69
 
68
- def priority_except_adapter
69
- priority & 0b111111100
70
- end
70
+ def priority_except_adapter
71
+ priority & 0b111111100
72
+ end
71
73
 
72
74
  private
73
75
 
74
- def matches_adapter?(adapter: nil, **)
75
- (self.adapter.nil? || adapter == self.adapter)
76
- end
76
+ def matches_adapter?(adapter: nil, **)
77
+ (self.adapter.nil? || adapter == self.adapter)
78
+ end
77
79
 
78
- def conflicts_with?(other)
79
- same_priority_except_adapter?(other) &&
80
- has_adapter_conflict?(other)
81
- end
80
+ def conflicts_with?(other)
81
+ same_priority_except_adapter?(other) &&
82
+ has_adapter_conflict?(other)
83
+ end
82
84
 
83
- def same_priority_except_adapter?(other)
84
- priority_except_adapter == other.priority_except_adapter
85
- end
85
+ def same_priority_except_adapter?(other)
86
+ priority_except_adapter == other.priority_except_adapter
87
+ end
86
88
 
87
- def has_adapter_conflict?(other)
88
- (override.nil? && other.adapter) ||
89
- (adapter && other.override.nil?)
90
- end
89
+ def has_adapter_conflict?(other)
90
+ (override.nil? && other.adapter) ||
91
+ (adapter && other.override.nil?)
92
+ end
91
93
  end
92
94
 
93
95
  class DecorationRegistration < Registration
@@ -110,17 +112,19 @@ module ActiveRecord
110
112
  super | 4
111
113
  end
112
114
 
115
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
116
+ # Workaround for Ruby 2.2 "private attribute?" warning.
113
117
  protected
114
118
 
115
- attr_reader :options, :klass
119
+ attr_reader :options, :klass
116
120
 
117
121
  private
118
122
 
119
- def matches_options?(**kwargs)
120
- options.all? do |key, value|
121
- kwargs[key] == value
123
+ def matches_options?(**kwargs)
124
+ options.all? do |key, value|
125
+ kwargs[key] == value
126
+ end
122
127
  end
123
- end
124
128
  end
125
129
  end
126
130
 
@@ -0,0 +1,13 @@
1
+ module ActiveRecord
2
+ module Type
3
+ class DecimalWithoutScale < ActiveModel::Type::BigInteger # :nodoc:
4
+ def type
5
+ :decimal
6
+ end
7
+
8
+ def type_cast_for_schema(value)
9
+ value.to_s.inspect
10
+ end
11
+ end
12
+ end
13
+ end
@@ -15,9 +15,9 @@ module ActiveRecord
15
15
 
16
16
  private
17
17
 
18
- def perform_fetch(type, *args, &block)
19
- @mapping.fetch(type, block).call(type, *args)
20
- end
18
+ def perform_fetch(type, *args, &block)
19
+ @mapping.fetch(type, block).call(type, *args)
20
+ end
21
21
  end
22
22
  end
23
23
  end
@@ -24,6 +24,10 @@ module ActiveRecord
24
24
  end
25
25
  end
26
26
 
27
+ def changed_in_place?(raw_old_value, new_value)
28
+ deserialize(raw_old_value) != new_value
29
+ end
30
+
27
31
  def accessor
28
32
  ActiveRecord::Store::StringKeyedHashAccessor
29
33
  end
@@ -1,6 +1,8 @@
1
1
  module ActiveRecord
2
2
  module Type
3
3
  class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:
4
+ undef to_yaml if method_defined?(:to_yaml)
5
+
4
6
  include ActiveModel::Type::Helpers::Mutable
5
7
 
6
8
  attr_reader :subtype, :coder
@@ -43,21 +45,25 @@ module ActiveRecord
43
45
 
44
46
  def assert_valid_value(value)
45
47
  if coder.respond_to?(:assert_valid_value)
46
- coder.assert_valid_value(value)
48
+ coder.assert_valid_value(value, action: "serialize")
47
49
  end
48
50
  end
49
51
 
52
+ def force_equality?(value)
53
+ coder.respond_to?(:object_class) && value.is_a?(coder.object_class)
54
+ end
55
+
50
56
  private
51
57
 
52
- def default_value?(value)
53
- value == coder.load(nil)
54
- end
58
+ def default_value?(value)
59
+ value == coder.load(nil)
60
+ end
55
61
 
56
- def encoded(value)
57
- unless default_value?(value)
58
- coder.dump(value)
62
+ def encoded(value)
63
+ unless default_value?(value)
64
+ coder.dump(value)
65
+ end
59
66
  end
60
- end
61
67
  end
62
68
  end
63
69
  end