activerecord 5.0.7 → 5.1.7

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.

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
@@ -1,4 +1,4 @@
1
- require 'active_record/attribute/user_provided_default'
1
+ require "active_record/attribute/user_provided_default"
2
2
 
3
3
  module ActiveRecord
4
4
  # See ActiveRecord::Attributes::ClassMethods for documentation
@@ -56,7 +56,7 @@ module ActiveRecord
56
56
  # store_listing = StoreListing.new(price_in_cents: '10.1')
57
57
  #
58
58
  # # before
59
- # store_listing.price_in_cents # => BigDecimal.new(10.1)
59
+ # store_listing.price_in_cents # => BigDecimal(10.1)
60
60
  #
61
61
  # class StoreListing < ActiveRecord::Base
62
62
  # attribute :price_in_cents, :integer
@@ -116,7 +116,7 @@ module ActiveRecord
116
116
  # Users may also define their own custom types, as long as they respond
117
117
  # to the methods defined on the value type. The method +deserialize+ or
118
118
  # +cast+ will be called on your type object, with raw input from the
119
- # database or from your controllers. See ActiveRecord::Type::Value for the
119
+ # database or from your controllers. See ActiveModel::Type::Value for the
120
120
  # expected API. It is recommended that your type objects inherit from an
121
121
  # existing type, or from ActiveRecord::Type::Value
122
122
  #
@@ -143,7 +143,7 @@ module ActiveRecord
143
143
  # store_listing.price_in_cents # => 1000
144
144
  #
145
145
  # For more details on creating custom types, see the documentation for
146
- # ActiveRecord::Type::Value. For more details on registering your types
146
+ # ActiveModel::Type::Value. For more details on registering your types
147
147
  # to be referenced by a symbol, see ActiveRecord::Type.register. You can
148
148
  # also pass a type object directly, in place of a symbol.
149
149
  #
@@ -190,8 +190,8 @@ module ActiveRecord
190
190
  # The type of an attribute is given the opportunity to change how dirty
191
191
  # tracking is performed. The methods +changed?+ and +changed_in_place?+
192
192
  # will be called from ActiveModel::Dirty. See the documentation for those
193
- # methods in ActiveRecord::Type::Value for more details.
194
- def attribute(name, cast_type, **options)
193
+ # methods in ActiveModel::Type::Value for more details.
194
+ def attribute(name, cast_type = Type::Value.new, **options)
195
195
  name = name.to_s
196
196
  reload_schema_from_cache
197
197
 
@@ -242,24 +242,24 @@ module ActiveRecord
242
242
 
243
243
  private
244
244
 
245
- NO_DEFAULT_PROVIDED = Object.new # :nodoc:
246
- private_constant :NO_DEFAULT_PROVIDED
245
+ NO_DEFAULT_PROVIDED = Object.new # :nodoc:
246
+ private_constant :NO_DEFAULT_PROVIDED
247
247
 
248
- def define_default_attribute(name, value, type, from_user:)
249
- if value == NO_DEFAULT_PROVIDED
250
- default_attribute = _default_attributes[name].with_type(type)
251
- elsif from_user
252
- default_attribute = Attribute::UserProvidedDefault.new(
253
- name,
254
- value,
255
- type,
256
- _default_attributes.fetch(name.to_s) { nil },
257
- )
258
- else
259
- default_attribute = Attribute.from_database(name, value, type)
248
+ def define_default_attribute(name, value, type, from_user:)
249
+ if value == NO_DEFAULT_PROVIDED
250
+ default_attribute = _default_attributes[name].with_type(type)
251
+ elsif from_user
252
+ default_attribute = Attribute::UserProvidedDefault.new(
253
+ name,
254
+ value,
255
+ type,
256
+ _default_attributes.fetch(name.to_s) { nil },
257
+ )
258
+ else
259
+ default_attribute = Attribute.from_database(name, value, type)
260
+ end
261
+ _default_attributes[name] = default_attribute
260
262
  end
261
- _default_attributes[name] = default_attribute
262
- end
263
263
  end
264
264
  end
265
265
  end
@@ -154,10 +154,10 @@ module ActiveRecord
154
154
  # Loop prevention for validation of associations
155
155
  unless @_already_called[name]
156
156
  begin
157
- @_already_called[name]=true
157
+ @_already_called[name] = true
158
158
  result = instance_eval(&block)
159
159
  ensure
160
- @_already_called[name]=false
160
+ @_already_called[name] = false
161
161
  end
162
162
  end
163
163
 
@@ -181,6 +181,7 @@ module ActiveRecord
181
181
 
182
182
  if reflection.collection?
183
183
  before_save :before_save_collection_association
184
+ after_save :after_save_collection_association
184
185
 
185
186
  define_non_cyclic_method(save_method) { save_collection_association(reflection) }
186
187
  # Doesn't use after_save as that would save associations added in after_create/after_update twice
@@ -267,7 +268,7 @@ module ActiveRecord
267
268
  # Returns whether or not this record has been changed in any way (including whether
268
269
  # any of its nested autosave associations are likewise changed)
269
270
  def changed_for_autosave?
270
- new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
271
+ new_record? || has_changes_to_save? || marked_for_destruction? || nested_records_changed_for_autosave?
271
272
  end
272
273
 
273
274
  private
@@ -325,12 +326,12 @@ module ActiveRecord
325
326
  # Returns whether or not the association is valid and applies any errors to
326
327
  # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
327
328
  # enabled records if they're marked_for_destruction? or destroyed.
328
- def association_valid?(reflection, record, index=nil)
329
+ def association_valid?(reflection, record, index = nil)
329
330
  return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?)
330
331
 
331
- validation_context = self.validation_context unless [:create, :update].include?(self.validation_context)
332
+ context = validation_context unless [:create, :update].include?(validation_context)
332
333
 
333
- unless valid = record.valid?(validation_context)
334
+ unless valid = record.valid?(context)
334
335
  if reflection.options[:autosave]
335
336
  indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors)
336
337
 
@@ -371,6 +372,10 @@ module ActiveRecord
371
372
  true
372
373
  end
373
374
 
375
+ def after_save_collection_association
376
+ @new_record_before_save = false
377
+ end
378
+
374
379
  # Saves any new associated records, or all loaded autosave associations if
375
380
  # <tt>:autosave</tt> is enabled on the association.
376
381
  #
@@ -383,6 +388,9 @@ module ActiveRecord
383
388
  if association = association_instance_get(reflection.name)
384
389
  autosave = reflection.options[:autosave]
385
390
 
391
+ # reconstruct the scope now that we know the owner's id
392
+ association.reset_scope if association.respond_to?(:reset_scope)
393
+
386
394
  if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
387
395
  if autosave
388
396
  records_to_destroy = records.select(&:marked_for_destruction?)
@@ -402,15 +410,12 @@ module ActiveRecord
402
410
  association.insert_record(record) unless reflection.nested?
403
411
  end
404
412
  elsif autosave
405
- saved = record.save(:validate => false)
413
+ saved = record.save(validate: false)
406
414
  end
407
415
 
408
416
  raise ActiveRecord::Rollback unless saved
409
417
  end
410
418
  end
411
-
412
- # reconstruct the scope now that we know the owner's id
413
- association.reset_scope if association.respond_to?(:reset_scope)
414
419
  end
415
420
  end
416
421
 
@@ -439,7 +444,7 @@ module ActiveRecord
439
444
  record[reflection.foreign_key] = key
440
445
  end
441
446
 
442
- saved = record.save(:validate => !autosave)
447
+ saved = record.save(validate: !autosave)
443
448
  raise ActiveRecord::Rollback if !saved && autosave
444
449
  saved
445
450
  end
@@ -451,7 +456,7 @@ module ActiveRecord
451
456
  def record_changed?(reflection, record, key)
452
457
  record.new_record? ||
453
458
  (record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key) ||
454
- record.attribute_changed?(reflection.foreign_key)
459
+ record.will_save_change_to_attribute?(reflection.foreign_key)
455
460
  end
456
461
 
457
462
  # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
@@ -469,7 +474,7 @@ module ActiveRecord
469
474
  self[reflection.foreign_key] = nil
470
475
  record.destroy
471
476
  elsif autosave != false
472
- saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
477
+ saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
473
478
 
474
479
  if association.updated?
475
480
  association_id = record.send(reflection.options[:primary_key] || :id)
@@ -1,25 +1,26 @@
1
- require 'yaml'
2
- require 'active_support/benchmarkable'
3
- require 'active_support/dependencies'
4
- require 'active_support/descendants_tracker'
5
- require 'active_support/time'
6
- require 'active_support/core_ext/module/attribute_accessors'
7
- require 'active_support/core_ext/array/extract_options'
8
- require 'active_support/core_ext/hash/deep_merge'
9
- require 'active_support/core_ext/hash/slice'
10
- require 'active_support/core_ext/hash/transform_values'
11
- require 'active_support/core_ext/string/behavior'
12
- require 'active_support/core_ext/kernel/singleton_class'
13
- require 'active_support/core_ext/module/introspection'
14
- require 'active_support/core_ext/object/duplicable'
15
- require 'active_support/core_ext/class/subclasses'
16
- require 'active_record/attribute_decorators'
17
- require 'active_record/errors'
18
- require 'active_record/log_subscriber'
19
- require 'active_record/explain_subscriber'
20
- require 'active_record/relation/delegation'
21
- require 'active_record/attributes'
22
- require 'active_record/type_caster'
1
+ require "yaml"
2
+ require "active_support/benchmarkable"
3
+ require "active_support/dependencies"
4
+ require "active_support/descendants_tracker"
5
+ require "active_support/time"
6
+ require "active_support/core_ext/module/attribute_accessors"
7
+ require "active_support/core_ext/array/extract_options"
8
+ require "active_support/core_ext/hash/deep_merge"
9
+ require "active_support/core_ext/hash/slice"
10
+ require "active_support/core_ext/hash/transform_values"
11
+ require "active_support/core_ext/string/behavior"
12
+ require "active_support/core_ext/kernel/singleton_class"
13
+ require "active_support/core_ext/module/introspection"
14
+ require "active_support/core_ext/object/duplicable"
15
+ require "active_support/core_ext/class/subclasses"
16
+ require "active_record/attribute_decorators"
17
+ require "active_record/define_callbacks"
18
+ require "active_record/errors"
19
+ require "active_record/log_subscriber"
20
+ require "active_record/explain_subscriber"
21
+ require "active_record/relation/delegation"
22
+ require "active_record/attributes"
23
+ require "active_record/type_caster"
23
24
 
24
25
  module ActiveRecord #:nodoc:
25
26
  # = Active Record
@@ -303,6 +304,7 @@ module ActiveRecord #:nodoc:
303
304
  include AttributeDecorators
304
305
  include Locking::Optimistic
305
306
  include Locking::Pessimistic
307
+ include DefineCallbacks
306
308
  include AttributeMethods
307
309
  include Callbacks
308
310
  include Timestamp
@@ -225,6 +225,55 @@ module ActiveRecord
225
225
  #
226
226
  # This way, the +before_destroy+ gets executed before the <tt>dependent: :destroy</tt> is called, and the data is still available.
227
227
  #
228
+ # Also, there are cases when you want several callbacks of the same type to
229
+ # be executed in order.
230
+ #
231
+ # For example:
232
+ #
233
+ # class Topic
234
+ # has_many :children
235
+ #
236
+ # after_save :log_children
237
+ # after_save :do_something_else
238
+ #
239
+ # private
240
+ #
241
+ # def log_chidren
242
+ # # Child processing
243
+ # end
244
+ #
245
+ # def do_something_else
246
+ # # Something else
247
+ # end
248
+ # end
249
+ #
250
+ # In this case the +log_children+ gets executed before +do_something_else+.
251
+ # The same applies to all non-transactional callbacks.
252
+ #
253
+ # In case there are multiple transactional callbacks as seen below, the order
254
+ # is reversed.
255
+ #
256
+ # For example:
257
+ #
258
+ # class Topic
259
+ # has_many :children
260
+ #
261
+ # after_commit :log_children
262
+ # after_commit :do_something_else
263
+ #
264
+ # private
265
+ #
266
+ # def log_chidren
267
+ # # Child processing
268
+ # end
269
+ #
270
+ # def do_something_else
271
+ # # Something else
272
+ # end
273
+ # end
274
+ #
275
+ # In this case the +do_something_else+ gets executed before +log_children+.
276
+ #
228
277
  # == \Transactions
229
278
  #
230
279
  # The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
@@ -265,17 +314,6 @@ module ActiveRecord
265
314
  :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
266
315
  ]
267
316
 
268
- module ClassMethods # :nodoc:
269
- include ActiveModel::Callbacks
270
- end
271
-
272
- included do
273
- include ActiveModel::Validations::Callbacks
274
-
275
- define_model_callbacks :initialize, :find, :touch, :only => :after
276
- define_model_callbacks :save, :create, :update, :destroy
277
- end
278
-
279
317
  def destroy #:nodoc:
280
318
  @_destroy_callback_already_called ||= false
281
319
  return if @_destroy_callback_already_called
@@ -292,17 +330,21 @@ module ActiveRecord
292
330
  _run_touch_callbacks { super }
293
331
  end
294
332
 
333
+ def increment!(attribute, by = 1, touch: nil) # :nodoc:
334
+ touch ? _run_touch_callbacks { super } : super
335
+ end
336
+
295
337
  private
296
338
 
297
- def create_or_update(*) #:nodoc:
339
+ def create_or_update(*)
298
340
  _run_save_callbacks { super }
299
341
  end
300
342
 
301
- def _create_record #:nodoc:
343
+ def _create_record
302
344
  _run_create_callbacks { super }
303
345
  end
304
346
 
305
- def _update_record(*) #:nodoc:
347
+ def _update_record(*)
306
348
  _run_update_callbacks { super }
307
349
  end
308
350
  end
@@ -1,12 +1,12 @@
1
- require 'yaml'
1
+ require "yaml"
2
2
 
3
3
  module ActiveRecord
4
4
  module Coders # :nodoc:
5
5
  class YAMLColumn # :nodoc:
6
-
7
6
  attr_accessor :object_class
8
7
 
9
- def initialize(object_class = Object)
8
+ def initialize(attr_name, object_class = Object)
9
+ @attr_name = attr_name
10
10
  @object_class = object_class
11
11
  check_arity_of_constructor
12
12
  end
@@ -14,37 +14,35 @@ module ActiveRecord
14
14
  def dump(obj)
15
15
  return if obj.nil?
16
16
 
17
- assert_valid_value(obj)
17
+ assert_valid_value(obj, action: "dump")
18
18
  YAML.dump obj
19
19
  end
20
20
 
21
21
  def load(yaml)
22
22
  return object_class.new if object_class != Object && yaml.nil?
23
- return yaml unless yaml.is_a?(String) && yaml =~ /^---/
23
+ return yaml unless yaml.is_a?(String) && /^---/.match?(yaml)
24
24
  obj = YAML.load(yaml)
25
25
 
26
- assert_valid_value(obj)
26
+ assert_valid_value(obj, action: "load")
27
27
  obj ||= object_class.new if object_class != Object
28
28
 
29
29
  obj
30
30
  end
31
31
 
32
- def assert_valid_value(obj)
32
+ def assert_valid_value(obj, action:)
33
33
  unless obj.nil? || obj.is_a?(object_class)
34
34
  raise SerializationTypeMismatch,
35
- "Attribute was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
35
+ "can't #{action} `#{@attr_name}`: was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
36
36
  end
37
37
  end
38
38
 
39
39
  private
40
40
 
41
- def check_arity_of_constructor
42
- begin
41
+ def check_arity_of_constructor
43
42
  load(nil)
44
43
  rescue ArgumentError
45
44
  raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
46
45
  end
47
- end
48
46
  end
49
47
  end
50
48
  end
@@ -1,12 +1,11 @@
1
1
  module ActiveRecord
2
2
  module CollectionCacheKey
3
-
4
3
  def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
5
4
  query_signature = Digest::MD5.hexdigest(collection.to_sql)
6
5
  key = "#{collection.model_name.cache_key}/query-#{query_signature}"
7
6
 
8
- if collection.loaded?
9
- size = collection.size
7
+ if collection.loaded? || collection.distinct_value
8
+ size = collection.records.size
10
9
  if size > 0
11
10
  timestamp = collection.max_by(&timestamp_column)._read_attribute(timestamp_column)
12
11
  end
@@ -15,7 +14,7 @@ module ActiveRecord
15
14
  column = "#{connection.quote_table_name(collection.table_name)}.#{connection.quote_column_name(timestamp_column)}"
16
15
  select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
17
16
 
18
- if collection.limit_value || collection.offset_value
17
+ if collection.has_limit_or_offset?
19
18
  query = collection.spawn
20
19
  query.select_values = [column]
21
20
  subquery_alias = "subquery_for_cache_key"