activerecord 6.0.5.1 → 6.1.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1163 -774
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/active_record/aggregations.rb +5 -5
  6. data/lib/active_record/association_relation.rb +30 -12
  7. data/lib/active_record/associations/alias_tracker.rb +19 -15
  8. data/lib/active_record/associations/association.rb +49 -26
  9. data/lib/active_record/associations/association_scope.rb +18 -20
  10. data/lib/active_record/associations/belongs_to_association.rb +23 -10
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
  12. data/lib/active_record/associations/builder/association.rb +32 -5
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +32 -18
  20. data/lib/active_record/associations/collection_proxy.rb +12 -5
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -2
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +37 -21
  26. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +63 -49
  28. data/lib/active_record/associations/preloader/association.rb +14 -8
  29. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  30. data/lib/active_record/associations/preloader.rb +5 -3
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations.rb +118 -11
  33. data/lib/active_record/attribute_assignment.rb +10 -8
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  35. data/lib/active_record/attribute_methods/dirty.rb +1 -11
  36. data/lib/active_record/attribute_methods/primary_key.rb +6 -2
  37. data/lib/active_record/attribute_methods/query.rb +3 -6
  38. data/lib/active_record/attribute_methods/read.rb +8 -11
  39. data/lib/active_record/attribute_methods/serialization.rb +11 -5
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
  41. data/lib/active_record/attribute_methods/write.rb +12 -20
  42. data/lib/active_record/attribute_methods.rb +64 -54
  43. data/lib/active_record/attributes.rb +33 -8
  44. data/lib/active_record/autosave_association.rb +47 -30
  45. data/lib/active_record/base.rb +2 -14
  46. data/lib/active_record/callbacks.rb +152 -22
  47. data/lib/active_record/coders/yaml_column.rb +16 -6
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +185 -134
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -23
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -8
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -35
  53. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +114 -26
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +228 -83
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +92 -33
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +52 -76
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
  61. data/lib/active_record/connection_adapters/column.rb +15 -1
  62. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  63. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +24 -24
  65. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
  67. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
  68. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  69. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
  70. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +7 -4
  71. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
  73. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  74. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  75. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +14 -53
  77. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  78. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  80. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/quoting.rb +30 -4
  87. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  88. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  90. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  91. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -64
  92. data/lib/active_record/connection_adapters/schema_cache.rb +130 -15
  93. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  94. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +32 -5
  95. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  96. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  97. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  98. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  99. data/lib/active_record/connection_adapters.rb +52 -0
  100. data/lib/active_record/connection_handling.rb +218 -71
  101. data/lib/active_record/core.rb +265 -64
  102. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  103. data/lib/active_record/database_configurations/database_config.rb +52 -9
  104. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  105. data/lib/active_record/database_configurations/url_config.rb +15 -40
  106. data/lib/active_record/database_configurations.rb +125 -85
  107. data/lib/active_record/delegated_type.rb +209 -0
  108. data/lib/active_record/destroy_association_async_job.rb +36 -0
  109. data/lib/active_record/enum.rb +69 -34
  110. data/lib/active_record/errors.rb +47 -12
  111. data/lib/active_record/explain.rb +9 -4
  112. data/lib/active_record/explain_subscriber.rb +1 -1
  113. data/lib/active_record/fixture_set/file.rb +10 -17
  114. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  115. data/lib/active_record/fixture_set/render_context.rb +1 -1
  116. data/lib/active_record/fixture_set/table_row.rb +2 -2
  117. data/lib/active_record/fixtures.rb +58 -9
  118. data/lib/active_record/gem_version.rb +3 -3
  119. data/lib/active_record/inheritance.rb +40 -18
  120. data/lib/active_record/insert_all.rb +38 -5
  121. data/lib/active_record/integration.rb +3 -5
  122. data/lib/active_record/internal_metadata.rb +18 -7
  123. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  124. data/lib/active_record/locking/optimistic.rb +24 -17
  125. data/lib/active_record/locking/pessimistic.rb +6 -2
  126. data/lib/active_record/log_subscriber.rb +27 -8
  127. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  128. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  129. data/lib/active_record/middleware/database_selector.rb +4 -1
  130. data/lib/active_record/migration/command_recorder.rb +47 -27
  131. data/lib/active_record/migration/compatibility.rb +72 -18
  132. data/lib/active_record/migration.rb +114 -84
  133. data/lib/active_record/model_schema.rb +89 -14
  134. data/lib/active_record/nested_attributes.rb +2 -3
  135. data/lib/active_record/no_touching.rb +1 -1
  136. data/lib/active_record/persistence.rb +50 -45
  137. data/lib/active_record/query_cache.rb +15 -5
  138. data/lib/active_record/querying.rb +11 -6
  139. data/lib/active_record/railtie.rb +61 -59
  140. data/lib/active_record/railties/console_sandbox.rb +2 -4
  141. data/lib/active_record/railties/databases.rake +279 -101
  142. data/lib/active_record/readonly_attributes.rb +4 -0
  143. data/lib/active_record/reflection.rb +60 -44
  144. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  145. data/lib/active_record/relation/batches.rb +38 -31
  146. data/lib/active_record/relation/calculations.rb +104 -43
  147. data/lib/active_record/relation/finder_methods.rb +44 -14
  148. data/lib/active_record/relation/from_clause.rb +1 -1
  149. data/lib/active_record/relation/merger.rb +20 -23
  150. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  151. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  152. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
  153. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  154. data/lib/active_record/relation/predicate_builder.rb +61 -38
  155. data/lib/active_record/relation/query_methods.rb +324 -196
  156. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  157. data/lib/active_record/relation/spawn_methods.rb +8 -7
  158. data/lib/active_record/relation/where_clause.rb +111 -61
  159. data/lib/active_record/relation.rb +100 -81
  160. data/lib/active_record/result.rb +41 -33
  161. data/lib/active_record/runtime_registry.rb +2 -2
  162. data/lib/active_record/sanitization.rb +6 -17
  163. data/lib/active_record/schema_dumper.rb +34 -4
  164. data/lib/active_record/schema_migration.rb +2 -8
  165. data/lib/active_record/scoping/default.rb +1 -3
  166. data/lib/active_record/scoping/named.rb +1 -17
  167. data/lib/active_record/secure_token.rb +16 -8
  168. data/lib/active_record/serialization.rb +5 -3
  169. data/lib/active_record/signed_id.rb +116 -0
  170. data/lib/active_record/statement_cache.rb +20 -4
  171. data/lib/active_record/store.rb +8 -3
  172. data/lib/active_record/suppressor.rb +2 -2
  173. data/lib/active_record/table_metadata.rb +42 -51
  174. data/lib/active_record/tasks/database_tasks.rb +140 -113
  175. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  176. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  177. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  178. data/lib/active_record/test_databases.rb +5 -4
  179. data/lib/active_record/test_fixtures.rb +79 -31
  180. data/lib/active_record/timestamp.rb +4 -6
  181. data/lib/active_record/touch_later.rb +21 -21
  182. data/lib/active_record/transactions.rb +19 -66
  183. data/lib/active_record/type/serialized.rb +6 -2
  184. data/lib/active_record/type.rb +8 -1
  185. data/lib/active_record/type_caster/connection.rb +0 -1
  186. data/lib/active_record/type_caster/map.rb +8 -5
  187. data/lib/active_record/validations/associated.rb +1 -1
  188. data/lib/active_record/validations/numericality.rb +35 -0
  189. data/lib/active_record/validations/uniqueness.rb +24 -4
  190. data/lib/active_record/validations.rb +1 -0
  191. data/lib/active_record.rb +7 -14
  192. data/lib/arel/attributes/attribute.rb +4 -0
  193. data/lib/arel/collectors/bind.rb +5 -0
  194. data/lib/arel/collectors/composite.rb +8 -0
  195. data/lib/arel/collectors/sql_string.rb +7 -0
  196. data/lib/arel/collectors/substitute_binds.rb +7 -0
  197. data/lib/arel/nodes/binary.rb +82 -8
  198. data/lib/arel/nodes/bind_param.rb +8 -0
  199. data/lib/arel/nodes/casted.rb +21 -9
  200. data/lib/arel/nodes/equality.rb +6 -9
  201. data/lib/arel/nodes/grouping.rb +3 -0
  202. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  203. data/lib/arel/nodes/in.rb +8 -1
  204. data/lib/arel/nodes/infix_operation.rb +13 -1
  205. data/lib/arel/nodes/join_source.rb +1 -1
  206. data/lib/arel/nodes/node.rb +7 -6
  207. data/lib/arel/nodes/ordering.rb +27 -0
  208. data/lib/arel/nodes/sql_literal.rb +3 -0
  209. data/lib/arel/nodes/table_alias.rb +7 -3
  210. data/lib/arel/nodes/unary.rb +0 -1
  211. data/lib/arel/nodes.rb +3 -1
  212. data/lib/arel/predications.rb +12 -18
  213. data/lib/arel/select_manager.rb +1 -2
  214. data/lib/arel/table.rb +13 -5
  215. data/lib/arel/visitors/dot.rb +14 -2
  216. data/lib/arel/visitors/mysql.rb +11 -1
  217. data/lib/arel/visitors/postgresql.rb +15 -4
  218. data/lib/arel/visitors/to_sql.rb +89 -78
  219. data/lib/arel/visitors.rb +0 -7
  220. data/lib/arel.rb +5 -13
  221. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  222. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  223. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  224. data/lib/rails/generators/active_record/migration.rb +6 -1
  225. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  226. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  227. metadata +24 -25
  228. data/lib/active_record/advisory_lock_base.rb +0 -18
  229. data/lib/active_record/attribute_decorators.rb +0 -88
  230. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  231. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  232. data/lib/active_record/define_callbacks.rb +0 -22
  233. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  234. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  235. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  236. data/lib/arel/attributes.rb +0 -22
  237. data/lib/arel/visitors/depth_first.rb +0 -203
  238. data/lib/arel/visitors/ibm_db.rb +0 -34
  239. data/lib/arel/visitors/informix.rb +0 -62
  240. data/lib/arel/visitors/mssql.rb +0 -156
  241. data/lib/arel/visitors/oracle.rb +0 -158
  242. data/lib/arel/visitors/oracle12.rb +0 -65
  243. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -31,7 +31,7 @@ module ActiveRecord
31
31
  # Association with autosave option defines several callbacks on your
32
32
  # model (around_save, before_save, after_create, after_update). Please note that
33
33
  # callbacks are executed in the order they were defined in
34
- # model. You should avoid modifying the association content, before
34
+ # model. You should avoid modifying the association content before
35
35
  # autosave callbacks are executed. Placing your callbacks after
36
36
  # associations is usually a good practice.
37
37
  #
@@ -91,8 +91,9 @@ module ActiveRecord
91
91
  # post.save # => saves both post and comment
92
92
  #
93
93
  # post = Post.create(title: 'ruby rocks')
94
- # post.comments.create(body: 'hello world')
95
- # post.save # => saves both post and comment
94
+ # comment = post.comments.create(body: 'hello world')
95
+ # comment.body = 'hi everyone'
96
+ # post.save # => saves post, but not comment
96
97
  #
97
98
  # When <tt>:autosave</tt> is true all children are saved, no matter whether they
98
99
  # are new records or not:
@@ -102,11 +103,10 @@ module ActiveRecord
102
103
  # end
103
104
  #
104
105
  # post = Post.create(title: 'ruby rocks')
105
- # post.comments.create(body: 'hello world')
106
- # post.comments[0].body = 'hi everyone'
106
+ # comment = post.comments.create(body: 'hello world')
107
+ # comment.body = 'hi everyone'
107
108
  # post.comments.build(body: "good morning.")
108
- # post.title += "!"
109
- # post.save # => saves both post and comments.
109
+ # post.save # => saves post and both comments.
110
110
  #
111
111
  # Destroying one of the associated models as part of the parent's save action
112
112
  # is as simple as marking it for destruction:
@@ -127,6 +127,14 @@ module ActiveRecord
127
127
  # Now it _is_ removed from the database:
128
128
  #
129
129
  # Comment.find_by(id: id).nil? # => true
130
+ #
131
+ # === Caveats
132
+ #
133
+ # Note that autosave will only trigger for already-persisted association records
134
+ # if the records themselves have been changed. This is to protect against
135
+ # <tt>SystemStackError</tt> caused by circular association validations. The one
136
+ # exception is if a custom validation context is used, in which case the validations
137
+ # will always fire on the associated records.
130
138
  module AutosaveAssociation
131
139
  extend ActiveSupport::Concern
132
140
 
@@ -147,8 +155,23 @@ module ActiveRecord
147
155
 
148
156
  module ClassMethods # :nodoc:
149
157
  private
158
+ if Module.method(:method_defined?).arity == 1 # MRI 2.5 and older
159
+ using Module.new {
160
+ refine Module do
161
+ def method_defined?(method, inherit = true)
162
+ if inherit
163
+ super(method)
164
+ else
165
+ instance_methods(false).include?(method.to_sym)
166
+ end
167
+ end
168
+ end
169
+ }
170
+ end
171
+
150
172
  def define_non_cyclic_method(name, &block)
151
- return if instance_methods(false).include?(name)
173
+ return if method_defined?(name, false)
174
+
152
175
  define_method(name) do |*args|
153
176
  result = true; @_already_called ||= {}
154
177
  # Loop prevention for validation of associations
@@ -278,8 +301,9 @@ module ActiveRecord
278
301
  end
279
302
  end
280
303
 
281
- # go through nested autosave associations that are loaded in memory (without loading
282
- # any new ones), and return true if is changed for autosave
304
+ # Go through nested autosave associations that are loaded in memory (without loading
305
+ # any new ones), and return true if any are changed for autosave.
306
+ # Returns false if already called to prevent an infinite loop.
283
307
  def nested_records_changed_for_autosave?
284
308
  @_nested_records_changed_for_autosave_already_called ||= false
285
309
  return false if @_nested_records_changed_for_autosave_already_called
@@ -327,21 +351,16 @@ module ActiveRecord
327
351
  if reflection.options[:autosave]
328
352
  indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors)
329
353
 
330
- record.errors.each do |attribute, message|
354
+ record.errors.group_by_attribute.each { |attribute, errors|
331
355
  attribute = normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
332
- errors[attribute] << message
333
- errors[attribute].uniq!
334
- end
335
-
336
- record.errors.details.each_key do |attribute|
337
- reflection_attribute =
338
- normalize_reflection_attribute(indexed_attribute, reflection, index, attribute).to_sym
339
356
 
340
- record.errors.details[attribute].each do |error|
341
- errors.details[reflection_attribute] << error
342
- errors.details[reflection_attribute].uniq!
343
- end
344
- end
357
+ errors.each { |error|
358
+ self.errors.import(
359
+ error,
360
+ attribute: attribute
361
+ )
362
+ }
363
+ }
345
364
  else
346
365
  errors.add(reflection.name)
347
366
  end
@@ -438,9 +457,9 @@ module ActiveRecord
438
457
  if autosave && record.marked_for_destruction?
439
458
  record.destroy
440
459
  elsif autosave != false
441
- key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
460
+ key = reflection.options[:primary_key] ? public_send(reflection.options[:primary_key]) : id
442
461
 
443
- if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
462
+ if (autosave && record.changed_for_autosave?) || record_changed?(reflection, record, key)
444
463
  unless reflection.through_reflection
445
464
  record[reflection.foreign_key] = key
446
465
  if inverse_reflection = reflection.inverse_of
@@ -466,7 +485,7 @@ module ActiveRecord
466
485
  def association_foreign_key_changed?(reflection, record, key)
467
486
  return false if reflection.through_reflection?
468
487
 
469
- record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key
488
+ record._has_attribute?(reflection.foreign_key) && record._read_attribute(reflection.foreign_key) != key
470
489
  end
471
490
 
472
491
  # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
@@ -487,7 +506,7 @@ module ActiveRecord
487
506
  saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
488
507
 
489
508
  if association.updated?
490
- association_id = record.send(reflection.options[:primary_key] || :id)
509
+ association_id = record.public_send(reflection.options[:primary_key] || :id)
491
510
  self[reflection.foreign_key] = association_id
492
511
  association.loaded!
493
512
  end
@@ -502,9 +521,7 @@ module ActiveRecord
502
521
  end
503
522
 
504
523
  def _ensure_no_duplicate_errors
505
- errors.messages.each_key do |attribute|
506
- errors[attribute].uniq!
507
- end
524
+ errors.uniq!
508
525
  end
509
526
  end
510
527
  end
@@ -1,22 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "yaml"
4
3
  require "active_support/benchmarkable"
5
4
  require "active_support/dependencies"
6
5
  require "active_support/descendants_tracker"
7
6
  require "active_support/time"
8
- require "active_support/core_ext/module/attribute_accessors"
9
- require "active_support/core_ext/array/extract_options"
10
- require "active_support/core_ext/hash/deep_merge"
11
- require "active_support/core_ext/hash/slice"
12
- require "active_support/core_ext/string/behavior"
13
- require "active_support/core_ext/kernel/singleton_class"
14
- require "active_support/core_ext/module/introspection"
15
- require "active_support/core_ext/object/duplicable"
16
7
  require "active_support/core_ext/class/subclasses"
17
- require "active_record/attribute_decorators"
18
- require "active_record/define_callbacks"
19
- require "active_record/errors"
20
8
  require "active_record/log_subscriber"
21
9
  require "active_record/explain_subscriber"
22
10
  require "active_record/relation/delegation"
@@ -285,6 +273,7 @@ module ActiveRecord #:nodoc:
285
273
  extend Querying
286
274
  extend Translation
287
275
  extend DynamicMatchers
276
+ extend DelegatedType
288
277
  extend Explain
289
278
  extend Enum
290
279
  extend Delegation::DelegateCache
@@ -303,10 +292,8 @@ module ActiveRecord #:nodoc:
303
292
  include Validations
304
293
  include CounterCache
305
294
  include Attributes
306
- include AttributeDecorators
307
295
  include Locking::Optimistic
308
296
  include Locking::Pessimistic
309
- include DefineCallbacks
310
297
  include AttributeMethods
311
298
  include Callbacks
312
299
  include Timestamp
@@ -321,6 +308,7 @@ module ActiveRecord #:nodoc:
321
308
  include Serialization
322
309
  include Store
323
310
  include SecureToken
311
+ include SignedId
324
312
  include Suppressor
325
313
  end
326
314
 
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  # = Active Record \Callbacks
5
5
  #
6
6
  # \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
7
- # before or after an alteration of the object state. This can be used to make sure that associated and
7
+ # before or after a change in the object state. This can be used to make sure that associated and
8
8
  # dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or
9
9
  # to massage attributes before they're validated (by overwriting +before_validation+).
10
10
  # As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record:
@@ -32,7 +32,7 @@ module ActiveRecord
32
32
  # is found and instantiated by a finder, with <tt>after_initialize</tt> being triggered after new objects
33
33
  # are instantiated as well.
34
34
  #
35
- # There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the
35
+ # There are nineteen callbacks in total, which give a lot of control over how to react and prepare for each state in the
36
36
  # Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar,
37
37
  # except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
38
38
  #
@@ -64,7 +64,7 @@ module ActiveRecord
64
64
  #
65
65
  # Besides the overwritable callback methods, it's also possible to register callbacks through the
66
66
  # use of the callback macros. Their main advantage is that the macros add behavior into a callback
67
- # queue that is kept intact down through an inheritance hierarchy.
67
+ # queue that is kept intact through an inheritance hierarchy.
68
68
  #
69
69
  # class Topic < ActiveRecord::Base
70
70
  # before_destroy :destroy_author
@@ -74,7 +74,7 @@ module ActiveRecord
74
74
  # before_destroy :destroy_readers
75
75
  # end
76
76
  #
77
- # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
77
+ # When <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
78
78
  # run, both +destroy_author+ and +destroy_readers+ are called.
79
79
  #
80
80
  # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
@@ -83,10 +83,9 @@ module ActiveRecord
83
83
  #
84
84
  # == Types of callbacks
85
85
  #
86
- # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
87
- # inline methods (using a proc). Method references and callback objects
88
- # are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
89
- # creating mix-ins).
86
+ # There are three types of callbacks accepted by the callback macros: method references (symbol), callback objects,
87
+ # inline methods (using a proc). Method references and callback objects are the recommended approaches,
88
+ # inline methods using a proc are sometimes appropriate (such as for creating mix-ins).
90
89
  #
91
90
  # The method reference callbacks work by specifying a protected or private method available in the object, like this:
92
91
  #
@@ -179,8 +178,8 @@ module ActiveRecord
179
178
  #
180
179
  # == Ordering callbacks
181
180
  #
182
- # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
183
- # callback (+log_children+ in this case) should be executed before the children get destroyed by the
181
+ # Sometimes application code requires that callbacks execute in a specific order. For example, a +before_destroy+
182
+ # callback (+log_children+ in this case) should be executed before records in the +children+ association are destroyed by the
184
183
  # <tt>dependent: :destroy</tt> option.
185
184
  #
186
185
  # Let's look at the code below:
@@ -196,8 +195,8 @@ module ActiveRecord
196
195
  # end
197
196
  # end
198
197
  #
199
- # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
200
- # because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback gets executed first.
198
+ # In this case, the problem is that when the +before_destroy+ callback is executed, records in the +children+ association no
199
+ # longer exist because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback was executed first.
201
200
  # You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
202
201
  #
203
202
  # class Topic < ActiveRecord::Base
@@ -211,7 +210,7 @@ module ActiveRecord
211
210
  # end
212
211
  # end
213
212
  #
214
- # This way, the +before_destroy+ gets executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
213
+ # This way, the +before_destroy+ is executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
215
214
  #
216
215
  # Also, there are cases when you want several callbacks of the same type to
217
216
  # be executed in order.
@@ -235,10 +234,10 @@ module ActiveRecord
235
234
  # end
236
235
  # end
237
236
  #
238
- # In this case the +log_children+ gets executed before +do_something_else+.
237
+ # In this case the +log_children+ is executed before +do_something_else+.
239
238
  # The same applies to all non-transactional callbacks.
240
239
  #
241
- # In case there are multiple transactional callbacks as seen below, the order
240
+ # As seen below, in case there are multiple transactional callbacks the order
242
241
  # is reversed.
243
242
  #
244
243
  # For example:
@@ -260,16 +259,16 @@ module ActiveRecord
260
259
  # end
261
260
  # end
262
261
  #
263
- # In this case the +do_something_else+ gets executed before +log_children+.
262
+ # In this case the +do_something_else+ is executed before +log_children+.
264
263
  #
265
264
  # == \Transactions
266
265
  #
267
266
  # The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
268
267
  # or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes <tt>after_*</tt> hooks.
269
- # If everything goes fine a COMMIT is executed once the chain has been completed.
268
+ # If everything goes fine a +COMMIT+ is executed once the chain has been completed.
270
269
  #
271
- # If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You
272
- # can also trigger a ROLLBACK raising an exception in any of the callbacks,
270
+ # If a <tt>before_*</tt> callback cancels the action a +ROLLBACK+ is issued. You
271
+ # can also trigger a +ROLLBACK+ raising an exception in any of the callbacks,
273
272
  # including <tt>after_*</tt> hooks. Note, however, that in that case the client
274
273
  # needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception
275
274
  # instead of quietly returning +false+.
@@ -280,17 +279,17 @@ module ActiveRecord
280
279
  # <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
281
280
  # defines what part of the chain the callback runs in.
282
281
  #
283
- # To find all callbacks in the before_save callback chain:
282
+ # To find all callbacks in the +before_save+ callback chain:
284
283
  #
285
284
  # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
286
285
  #
287
- # Returns an array of callback objects that form the before_save chain.
286
+ # Returns an array of callback objects that form the +before_save+ chain.
288
287
  #
289
288
  # To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
290
289
  #
291
290
  # Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
292
291
  #
293
- # Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
292
+ # Returns true or false depending on whether the proc is contained in the +before_save+ callback chain on a Topic model.
294
293
  #
295
294
  module Callbacks
296
295
  extend ActiveSupport::Concern
@@ -302,6 +301,137 @@ module ActiveRecord
302
301
  :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
303
302
  ]
304
303
 
304
+ module ClassMethods
305
+ include ActiveModel::Callbacks
306
+
307
+ ##
308
+ # :method: after_initialize
309
+ #
310
+ # :call-seq: after_initialize(*args, &block)
311
+ #
312
+ # Registers a callback to be called after a record is instantiated. See
313
+ # ActiveRecord::Callbacks for more information.
314
+
315
+ ##
316
+ # :method: after_find
317
+ #
318
+ # :call-seq: after_find(*args, &block)
319
+ #
320
+ # Registers a callback to be called after a record is instantiated
321
+ # via a finder. See ActiveRecord::Callbacks for more information.
322
+
323
+ ##
324
+ # :method: after_touch
325
+ #
326
+ # :call-seq: after_touch(*args, &block)
327
+ #
328
+ # Registers a callback to be called after a record is touched. See
329
+ # ActiveRecord::Callbacks for more information.
330
+
331
+ ##
332
+ # :method: before_save
333
+ #
334
+ # :call-seq: before_save(*args, &block)
335
+ #
336
+ # Registers a callback to be called before a record is saved. See
337
+ # ActiveRecord::Callbacks for more information.
338
+
339
+ ##
340
+ # :method: around_save
341
+ #
342
+ # :call-seq: around_save(*args, &block)
343
+ #
344
+ # Registers a callback to be called around the save of a record. See
345
+ # ActiveRecord::Callbacks for more information.
346
+
347
+ ##
348
+ # :method: after_save
349
+ #
350
+ # :call-seq: after_save(*args, &block)
351
+ #
352
+ # Registers a callback to be called after a record is saved. See
353
+ # ActiveRecord::Callbacks for more information.
354
+
355
+ ##
356
+ # :method: before_create
357
+ #
358
+ # :call-seq: before_create(*args, &block)
359
+ #
360
+ # Registers a callback to be called before a record is created. See
361
+ # ActiveRecord::Callbacks for more information.
362
+
363
+ ##
364
+ # :method: around_create
365
+ #
366
+ # :call-seq: around_create(*args, &block)
367
+ #
368
+ # Registers a callback to be called around the creation of a record. See
369
+ # ActiveRecord::Callbacks for more information.
370
+
371
+ ##
372
+ # :method: after_create
373
+ #
374
+ # :call-seq: after_create(*args, &block)
375
+ #
376
+ # Registers a callback to be called after a record is created. See
377
+ # ActiveRecord::Callbacks for more information.
378
+
379
+ ##
380
+ # :method: before_update
381
+ #
382
+ # :call-seq: before_update(*args, &block)
383
+ #
384
+ # Registers a callback to be called before a record is updated. See
385
+ # ActiveRecord::Callbacks for more information.
386
+
387
+ ##
388
+ # :method: around_update
389
+ #
390
+ # :call-seq: around_update(*args, &block)
391
+ #
392
+ # Registers a callback to be called around the update of a record. See
393
+ # ActiveRecord::Callbacks for more information.
394
+
395
+ ##
396
+ # :method: after_update
397
+ #
398
+ # :call-seq: after_update(*args, &block)
399
+ #
400
+ # Registers a callback to be called after a record is updated. See
401
+ # ActiveRecord::Callbacks for more information.
402
+
403
+ ##
404
+ # :method: before_destroy
405
+ #
406
+ # :call-seq: before_destroy(*args, &block)
407
+ #
408
+ # Registers a callback to be called before a record is destroyed. See
409
+ # ActiveRecord::Callbacks for more information.
410
+
411
+ ##
412
+ # :method: around_destroy
413
+ #
414
+ # :call-seq: around_destroy(*args, &block)
415
+ #
416
+ # Registers a callback to be called around the destruction of a record.
417
+ # See ActiveRecord::Callbacks for more information.
418
+
419
+ ##
420
+ # :method: after_destroy
421
+ #
422
+ # :call-seq: after_destroy(*args, &block)
423
+ #
424
+ # Registers a callback to be called after a record is destroyed. See
425
+ # ActiveRecord::Callbacks for more information.
426
+ end
427
+
428
+ included do
429
+ include ActiveModel::Validations::Callbacks
430
+
431
+ define_model_callbacks :initialize, :find, :touch, only: :after
432
+ define_model_callbacks :save, :create, :update, :destroy
433
+ end
434
+
305
435
  def destroy #:nodoc:
306
436
  @_destroy_callback_already_called ||= false
307
437
  return if @_destroy_callback_already_called
@@ -22,7 +22,7 @@ module ActiveRecord
22
22
 
23
23
  def load(yaml)
24
24
  return object_class.new if object_class != Object && yaml.nil?
25
- return yaml unless yaml.is_a?(String) && /^---/.match?(yaml)
25
+ return yaml unless yaml.is_a?(String) && yaml.start_with?("---")
26
26
  obj = yaml_load(yaml)
27
27
 
28
28
  assert_valid_value(obj, action: "load")
@@ -45,14 +45,24 @@ module ActiveRecord
45
45
  raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
46
46
  end
47
47
 
48
- def yaml_load(payload)
49
- if !ActiveRecord::Base.use_yaml_unsafe_load
50
- YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
51
- else
52
- if YAML.respond_to?(:unsafe_load)
48
+ if YAML.respond_to?(:unsafe_load)
49
+ def yaml_load(payload)
50
+ if ActiveRecord::Base.use_yaml_unsafe_load
53
51
  YAML.unsafe_load(payload)
52
+ elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
53
+ YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
54
54
  else
55
+ YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
56
+ end
57
+ end
58
+ else
59
+ def yaml_load(payload)
60
+ if ActiveRecord::Base.use_yaml_unsafe_load
55
61
  YAML.load(payload)
62
+ elsif YAML.method(:safe_load).parameters.include?([:key, :permitted_classes])
63
+ YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
64
+ else
65
+ YAML.safe_load(payload, ActiveRecord::Base.yaml_column_permitted_classes, [], true)
56
66
  end
57
67
  end
58
68
  end