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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +657 -2080
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +28 -28
- data/examples/simple.rb +3 -3
- data/lib/active_record/aggregations.rb +244 -244
- data/lib/active_record/association_relation.rb +5 -5
- data/lib/active_record/associations/alias_tracker.rb +10 -11
- data/lib/active_record/associations/association.rb +23 -5
- data/lib/active_record/associations/association_scope.rb +95 -81
- data/lib/active_record/associations/belongs_to_association.rb +7 -4
- data/lib/active_record/associations/builder/belongs_to.rb +30 -16
- data/lib/active_record/associations/builder/collection_association.rb +1 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
- data/lib/active_record/associations/collection_association.rb +36 -205
- data/lib/active_record/associations/collection_proxy.rb +132 -63
- data/lib/active_record/associations/has_many_association.rb +10 -19
- data/lib/active_record/associations/has_many_through_association.rb +12 -4
- data/lib/active_record/associations/has_one_association.rb +24 -28
- data/lib/active_record/associations/has_one_through_association.rb +5 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +4 -28
- data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +121 -118
- data/lib/active_record/associations/preloader/association.rb +64 -64
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
- data/lib/active_record/associations/preloader/collection_association.rb +6 -6
- data/lib/active_record/associations/preloader/has_many.rb +0 -2
- data/lib/active_record/associations/preloader/singular_association.rb +6 -8
- data/lib/active_record/associations/preloader/through_association.rb +41 -41
- data/lib/active_record/associations/preloader.rb +94 -94
- data/lib/active_record/associations/singular_association.rb +8 -25
- data/lib/active_record/associations/through_association.rb +2 -5
- data/lib/active_record/associations.rb +1591 -1562
- data/lib/active_record/attribute/user_provided_default.rb +4 -2
- data/lib/active_record/attribute.rb +98 -71
- data/lib/active_record/attribute_assignment.rb +61 -61
- data/lib/active_record/attribute_decorators.rb +35 -13
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
- data/lib/active_record/attribute_methods/dirty.rb +229 -46
- data/lib/active_record/attribute_methods/primary_key.rb +74 -73
- data/lib/active_record/attribute_methods/read.rb +39 -35
- data/lib/active_record/attribute_methods/serialization.rb +7 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
- data/lib/active_record/attribute_methods/write.rb +30 -33
- data/lib/active_record/attribute_methods.rb +56 -65
- data/lib/active_record/attribute_mutation_tracker.rb +63 -11
- data/lib/active_record/attribute_set/builder.rb +27 -33
- data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
- data/lib/active_record/attribute_set.rb +9 -6
- data/lib/active_record/attributes.rb +22 -22
- data/lib/active_record/autosave_association.rb +18 -13
- data/lib/active_record/base.rb +24 -22
- data/lib/active_record/callbacks.rb +56 -14
- data/lib/active_record/coders/yaml_column.rb +9 -11
- data/lib/active_record/collection_cache_key.rb +3 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +330 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +39 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +32 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -51
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +10 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +74 -79
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/abstract/transaction.rb +49 -43
- data/lib/active_record/connection_adapters/abstract_adapter.rb +165 -135
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +404 -424
- data/lib/active_record/connection_adapters/column.rb +26 -4
- data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
- data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -28
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +7 -6
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +32 -53
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
- data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +32 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
- data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -35
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +182 -222
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +6 -4
- data/lib/active_record/connection_adapters/postgresql/utils.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +198 -167
- data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +184 -167
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
- data/lib/active_record/connection_handling.rb +14 -26
- data/lib/active_record/core.rb +109 -93
- data/lib/active_record/counter_cache.rb +60 -13
- data/lib/active_record/define_callbacks.rb +20 -0
- data/lib/active_record/dynamic_matchers.rb +80 -79
- data/lib/active_record/enum.rb +8 -6
- data/lib/active_record/errors.rb +64 -15
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +7 -4
- data/lib/active_record/fixture_set/file.rb +11 -8
- data/lib/active_record/fixtures.rb +66 -53
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +93 -79
- data/lib/active_record/integration.rb +7 -7
- data/lib/active_record/internal_metadata.rb +3 -16
- data/lib/active_record/legacy_yaml_adapter.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +69 -74
- data/lib/active_record/locking/pessimistic.rb +10 -1
- data/lib/active_record/log_subscriber.rb +23 -28
- data/lib/active_record/migration/command_recorder.rb +94 -94
- data/lib/active_record/migration/compatibility.rb +100 -47
- data/lib/active_record/migration/join_table.rb +6 -6
- data/lib/active_record/migration.rb +153 -155
- data/lib/active_record/model_schema.rb +94 -107
- data/lib/active_record/nested_attributes.rb +200 -199
- data/lib/active_record/null_relation.rb +11 -34
- data/lib/active_record/persistence.rb +65 -50
- data/lib/active_record/query_cache.rb +2 -6
- data/lib/active_record/querying.rb +3 -4
- data/lib/active_record/railtie.rb +16 -17
- data/lib/active_record/railties/controller_runtime.rb +6 -2
- data/lib/active_record/railties/databases.rake +105 -133
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +2 -2
- data/lib/active_record/reflection.rb +154 -108
- data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
- data/lib/active_record/relation/batches.rb +80 -51
- data/lib/active_record/relation/calculations.rb +169 -162
- data/lib/active_record/relation/delegation.rb +32 -31
- data/lib/active_record/relation/finder_methods.rb +197 -231
- data/lib/active_record/relation/merger.rb +58 -62
- data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
- data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder.rb +92 -89
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +255 -293
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +4 -5
- data/lib/active_record/relation/where_clause.rb +80 -65
- data/lib/active_record/relation/where_clause_factory.rb +47 -8
- data/lib/active_record/relation.rb +93 -119
- data/lib/active_record/result.rb +41 -32
- data/lib/active_record/runtime_registry.rb +3 -3
- data/lib/active_record/sanitization.rb +176 -192
- data/lib/active_record/schema.rb +3 -3
- data/lib/active_record/schema_dumper.rb +15 -38
- data/lib/active_record/schema_migration.rb +8 -4
- data/lib/active_record/scoping/default.rb +90 -90
- data/lib/active_record/scoping/named.rb +11 -11
- data/lib/active_record/scoping.rb +6 -6
- data/lib/active_record/secure_token.rb +2 -2
- data/lib/active_record/statement_cache.rb +13 -15
- data/lib/active_record/store.rb +31 -32
- data/lib/active_record/suppressor.rb +2 -1
- data/lib/active_record/table_metadata.rb +9 -5
- data/lib/active_record/tasks/database_tasks.rb +65 -55
- data/lib/active_record/tasks/mysql_database_tasks.rb +76 -73
- data/lib/active_record/tasks/postgresql_database_tasks.rb +72 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
- data/lib/active_record/timestamp.rb +46 -25
- data/lib/active_record/touch_later.rb +1 -2
- data/lib/active_record/transactions.rb +97 -109
- data/lib/active_record/type/adapter_specific_registry.rb +46 -42
- data/lib/active_record/type/decimal_without_scale.rb +13 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
- data/lib/active_record/type/internal/abstract_json.rb +4 -0
- data/lib/active_record/type/serialized.rb +14 -8
- data/lib/active_record/type/text.rb +9 -0
- data/lib/active_record/type/time.rb +0 -1
- data/lib/active_record/type/type_map.rb +11 -15
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type.rb +17 -13
- data/lib/active_record/type_caster/connection.rb +8 -6
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +8 -39
- data/lib/active_record/validations.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +20 -20
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
- data/lib/rails/generators/active_record/migration.rb +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
- data/lib/rails/generators/active_record.rb +4 -4
- metadata +24 -13
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
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
|
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
|
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
|
-
#
|
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
|
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
|
-
|
246
|
-
|
245
|
+
NO_DEFAULT_PROVIDED = Object.new # :nodoc:
|
246
|
+
private_constant :NO_DEFAULT_PROVIDED
|
247
247
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
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? ||
|
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
|
-
|
332
|
+
context = validation_context unless [:create, :update].include?(validation_context)
|
332
333
|
|
333
|
-
unless valid = record.valid?(
|
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(:
|
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(:
|
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.
|
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(:
|
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)
|
data/lib/active_record/base.rb
CHANGED
@@ -1,25 +1,26 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
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(*)
|
339
|
+
def create_or_update(*)
|
298
340
|
_run_save_callbacks { super }
|
299
341
|
end
|
300
342
|
|
301
|
-
def _create_record
|
343
|
+
def _create_record
|
302
344
|
_run_create_callbacks { super }
|
303
345
|
end
|
304
346
|
|
305
|
-
def _update_record(*)
|
347
|
+
def _update_record(*)
|
306
348
|
_run_update_callbacks { super }
|
307
349
|
end
|
308
350
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require
|
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
|
-
"
|
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
|
-
|
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(×tamp_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.
|
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"
|