activerecord 6.0.0 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +872 -582
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations.rb +116 -13
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -29
- data/lib/active_record/associations/association_scope.rb +17 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +77 -42
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +63 -44
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +86 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +4 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +74 -76
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +81 -57
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +211 -81
- data/lib/active_record/core.rb +237 -69
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -41
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +39 -10
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +120 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation.rb +108 -67
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +55 -17
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +340 -180
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/result.rb +41 -34
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +22 -71
- data/lib/active_record/type.rb +8 -2
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +15 -12
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +6 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +27 -24
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/hash/except"
|
4
4
|
require "active_support/core_ext/module/redefine_method"
|
5
|
-
require "active_support/core_ext/object/try"
|
6
5
|
require "active_support/core_ext/hash/indifferent_access"
|
7
6
|
|
8
7
|
module ActiveRecord
|
@@ -289,7 +288,7 @@ module ActiveRecord
|
|
289
288
|
# [:allow_destroy]
|
290
289
|
# If true, destroys any members from the attributes hash with a
|
291
290
|
# <tt>_destroy</tt> key and a value that evaluates to +true+
|
292
|
-
# (
|
291
|
+
# (e.g. 1, '1', true, or 'true'). This option is off by default.
|
293
292
|
# [:reject_if]
|
294
293
|
# Allows you to specify a Proc or a Symbol pointing to a method
|
295
294
|
# that checks whether a record should be built for a certain attribute
|
@@ -354,7 +353,6 @@ module ActiveRecord
|
|
354
353
|
end
|
355
354
|
|
356
355
|
private
|
357
|
-
|
358
356
|
# Generates a writer method for this association. Serves as a point for
|
359
357
|
# accessing the objects in the association. For example, this method
|
360
358
|
# could generate the following:
|
@@ -386,7 +384,6 @@ module ActiveRecord
|
|
386
384
|
end
|
387
385
|
|
388
386
|
private
|
389
|
-
|
390
387
|
# Attribute hash keys that should not be assigned as normal attributes.
|
391
388
|
# These hash keys are nested attributes implementation details.
|
392
389
|
UNASSIGNABLE_KEYS = %w( id _destroy )
|
@@ -512,7 +509,7 @@ module ActiveRecord
|
|
512
509
|
if target_record
|
513
510
|
existing_record = target_record
|
514
511
|
else
|
515
|
-
association.add_to_target(existing_record, :
|
512
|
+
association.add_to_target(existing_record, skip_callbacks: true)
|
516
513
|
end
|
517
514
|
|
518
515
|
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
@@ -414,8 +414,8 @@ module ActiveRecord
|
|
414
414
|
|
415
415
|
def _substitute_values(values)
|
416
416
|
values.map do |name, value|
|
417
|
-
attr =
|
418
|
-
bind = predicate_builder.build_bind_attribute(name, value)
|
417
|
+
attr = arel_table[name]
|
418
|
+
bind = predicate_builder.build_bind_attribute(attr.name, value)
|
419
419
|
[attr, bind]
|
420
420
|
end
|
421
421
|
end
|
@@ -424,26 +424,30 @@ module ActiveRecord
|
|
424
424
|
# Returns true if this object hasn't been saved yet -- that is, a record
|
425
425
|
# for the object doesn't exist in the database yet; otherwise, returns false.
|
426
426
|
def new_record?
|
427
|
-
sync_with_transaction_state if @transaction_state&.finalized?
|
428
427
|
@new_record
|
429
428
|
end
|
430
429
|
|
430
|
+
# Returns true if this object was just created -- that is, prior to the last
|
431
|
+
# save, the object didn't exist in the database and new_record? would have
|
432
|
+
# returned true.
|
433
|
+
def previously_new_record?
|
434
|
+
@previously_new_record
|
435
|
+
end
|
436
|
+
|
431
437
|
# Returns true if this object has been destroyed, otherwise returns false.
|
432
438
|
def destroyed?
|
433
|
-
sync_with_transaction_state if @transaction_state&.finalized?
|
434
439
|
@destroyed
|
435
440
|
end
|
436
441
|
|
437
442
|
# Returns true if the record is persisted, i.e. it's not a new record and it was
|
438
443
|
# not destroyed, otherwise returns false.
|
439
444
|
def persisted?
|
440
|
-
sync_with_transaction_state if @transaction_state&.finalized?
|
441
445
|
!(@new_record || @destroyed)
|
442
446
|
end
|
443
447
|
|
444
448
|
##
|
445
449
|
# :call-seq:
|
446
|
-
# save(
|
450
|
+
# save(**options)
|
447
451
|
#
|
448
452
|
# Saves the model.
|
449
453
|
#
|
@@ -466,15 +470,15 @@ module ActiveRecord
|
|
466
470
|
#
|
467
471
|
# Attributes marked as readonly are silently ignored if the record is
|
468
472
|
# being updated.
|
469
|
-
def save(
|
470
|
-
create_or_update(
|
473
|
+
def save(**options, &block)
|
474
|
+
create_or_update(**options, &block)
|
471
475
|
rescue ActiveRecord::RecordInvalid
|
472
476
|
false
|
473
477
|
end
|
474
478
|
|
475
479
|
##
|
476
480
|
# :call-seq:
|
477
|
-
# save!(
|
481
|
+
# save!(**options)
|
478
482
|
#
|
479
483
|
# Saves the model.
|
480
484
|
#
|
@@ -499,8 +503,8 @@ module ActiveRecord
|
|
499
503
|
# being updated.
|
500
504
|
#
|
501
505
|
# Unless an error is raised, returns true.
|
502
|
-
def save!(
|
503
|
-
create_or_update(
|
506
|
+
def save!(**options, &block)
|
507
|
+
create_or_update(**options, &block) || raise(RecordNotSaved.new("Failed to save the record", self))
|
504
508
|
end
|
505
509
|
|
506
510
|
# Deletes the record in the database and freezes this instance to
|
@@ -514,7 +518,7 @@ module ActiveRecord
|
|
514
518
|
#
|
515
519
|
# To enforce the object's +before_destroy+ and +after_destroy+
|
516
520
|
# callbacks or any <tt>:dependent</tt> association
|
517
|
-
# options, use
|
521
|
+
# options, use #destroy.
|
518
522
|
def delete
|
519
523
|
_delete_row if persisted?
|
520
524
|
@destroyed = true
|
@@ -565,12 +569,15 @@ module ActiveRecord
|
|
565
569
|
# If you want to change the sti column as well, use #becomes! instead.
|
566
570
|
def becomes(klass)
|
567
571
|
became = klass.allocate
|
568
|
-
|
569
|
-
became.
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
572
|
+
|
573
|
+
became.send(:initialize) do |becoming|
|
574
|
+
becoming.instance_variable_set(:@attributes, @attributes)
|
575
|
+
becoming.instance_variable_set(:@mutations_from_database, @mutations_from_database ||= nil)
|
576
|
+
becoming.instance_variable_set(:@new_record, new_record?)
|
577
|
+
becoming.instance_variable_set(:@destroyed, destroyed?)
|
578
|
+
becoming.errors.copy!(errors)
|
579
|
+
end
|
580
|
+
|
574
581
|
became
|
575
582
|
end
|
576
583
|
|
@@ -622,9 +629,6 @@ module ActiveRecord
|
|
622
629
|
end
|
623
630
|
end
|
624
631
|
|
625
|
-
alias update_attributes update
|
626
|
-
deprecate update_attributes: "please, use update instead"
|
627
|
-
|
628
632
|
# Updates its receiver just like #update but calls #save! instead
|
629
633
|
# of +save+, so an exception is raised if the record is invalid and saving will fail.
|
630
634
|
def update!(attributes)
|
@@ -636,9 +640,6 @@ module ActiveRecord
|
|
636
640
|
end
|
637
641
|
end
|
638
642
|
|
639
|
-
alias update_attributes! update!
|
640
|
-
deprecate update_attributes!: "please, use update! instead"
|
641
|
-
|
642
643
|
# Equivalent to <code>update_columns(name => value)</code>.
|
643
644
|
def update_column(name, value)
|
644
645
|
update_columns(name => value)
|
@@ -666,11 +667,8 @@ module ActiveRecord
|
|
666
667
|
|
667
668
|
attributes = attributes.transform_keys do |key|
|
668
669
|
name = key.to_s
|
669
|
-
self.class.attribute_aliases[name] || name
|
670
|
-
|
671
|
-
|
672
|
-
attributes.each_key do |key|
|
673
|
-
verify_readonly_attribute(key)
|
670
|
+
name = self.class.attribute_aliases[name] || name
|
671
|
+
verify_readonly_attribute(name) || name
|
674
672
|
end
|
675
673
|
|
676
674
|
id_in_database = self.id_in_database
|
@@ -703,9 +701,9 @@ module ActiveRecord
|
|
703
701
|
# Returns +self+.
|
704
702
|
def increment!(attribute, by = 1, touch: nil)
|
705
703
|
increment(attribute, by)
|
706
|
-
change = public_send(attribute) - (
|
704
|
+
change = public_send(attribute) - (public_send(:"#{attribute}_in_database") || 0)
|
707
705
|
self.class.update_counters(id, attribute => change, touch: touch)
|
708
|
-
|
706
|
+
public_send(:"clear_#{attribute}_change")
|
709
707
|
self
|
710
708
|
end
|
711
709
|
|
@@ -809,8 +807,9 @@ module ActiveRecord
|
|
809
807
|
self.class.unscoped { self.class.find(id) }
|
810
808
|
end
|
811
809
|
|
812
|
-
@attributes = fresh_object.instance_variable_get(
|
810
|
+
@attributes = fresh_object.instance_variable_get(:@attributes)
|
813
811
|
@new_record = false
|
812
|
+
@previously_new_record = false
|
814
813
|
self
|
815
814
|
end
|
816
815
|
|
@@ -849,17 +848,13 @@ module ActiveRecord
|
|
849
848
|
# ball.touch(:updated_at) # => raises ActiveRecordError
|
850
849
|
#
|
851
850
|
def touch(*names, time: nil)
|
852
|
-
unless persisted?
|
853
|
-
raise ActiveRecordError, <<-MSG.squish
|
854
|
-
cannot touch on a new or destroyed record object. Consider using
|
855
|
-
persisted?, new_record?, or destroyed? before touching
|
856
|
-
MSG
|
857
|
-
end
|
851
|
+
_raise_record_not_touched_error unless persisted?
|
858
852
|
|
859
853
|
attribute_names = timestamp_attributes_for_update_in_model
|
860
|
-
attribute_names |= names.map!
|
854
|
+
attribute_names |= names.map! do |name|
|
855
|
+
name = name.to_s
|
861
856
|
self.class.attribute_aliases[name] || name
|
862
|
-
|
857
|
+
end unless names.empty?
|
863
858
|
|
864
859
|
unless attribute_names.empty?
|
865
860
|
affected_rows = _touch_row(attribute_names, time)
|
@@ -870,7 +865,6 @@ module ActiveRecord
|
|
870
865
|
end
|
871
866
|
|
872
867
|
private
|
873
|
-
|
874
868
|
# A hook to be overridden by association modules.
|
875
869
|
def destroy_associations
|
876
870
|
end
|
@@ -920,6 +914,8 @@ module ActiveRecord
|
|
920
914
|
@_trigger_update_callback = affected_rows == 1
|
921
915
|
end
|
922
916
|
|
917
|
+
@previously_new_record = false
|
918
|
+
|
923
919
|
yield(self) if block_given?
|
924
920
|
|
925
921
|
affected_rows
|
@@ -937,6 +933,7 @@ module ActiveRecord
|
|
937
933
|
self.id ||= new_id if @primary_key
|
938
934
|
|
939
935
|
@new_record = false
|
936
|
+
@previously_new_record = true
|
940
937
|
|
941
938
|
yield(self) if block_given?
|
942
939
|
|
@@ -944,7 +941,7 @@ module ActiveRecord
|
|
944
941
|
end
|
945
942
|
|
946
943
|
def verify_readonly_attribute(name)
|
947
|
-
raise ActiveRecordError, "#{name} is marked as readonly" if self.class.
|
944
|
+
raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attribute?(name)
|
948
945
|
end
|
949
946
|
|
950
947
|
def _raise_record_not_destroyed
|
@@ -954,14 +951,21 @@ module ActiveRecord
|
|
954
951
|
@_association_destroy_exception = nil
|
955
952
|
end
|
956
953
|
|
954
|
+
def _raise_readonly_record_error
|
955
|
+
raise ReadOnlyRecord, "#{self.class} is marked as readonly"
|
956
|
+
end
|
957
|
+
|
958
|
+
def _raise_record_not_touched_error
|
959
|
+
raise ActiveRecordError, <<~MSG.squish
|
960
|
+
Cannot touch on a new or destroyed record object. Consider using
|
961
|
+
persisted?, new_record?, or destroyed? before touching.
|
962
|
+
MSG
|
963
|
+
end
|
964
|
+
|
957
965
|
# The name of the method used to touch a +belongs_to+ association when the
|
958
966
|
# +:touch+ option is used.
|
959
967
|
def belongs_to_touch_method
|
960
968
|
:touch
|
961
969
|
end
|
962
|
-
|
963
|
-
def _raise_readonly_record_error
|
964
|
-
raise ReadOnlyRecord, "#{self.class} is marked as readonly"
|
965
|
-
end
|
966
970
|
end
|
967
971
|
end
|
@@ -28,18 +28,28 @@ module ActiveRecord
|
|
28
28
|
def self.run
|
29
29
|
pools = []
|
30
30
|
|
31
|
-
ActiveRecord::Base.
|
32
|
-
|
31
|
+
if ActiveRecord::Base.legacy_connection_handling
|
32
|
+
ActiveRecord::Base.connection_handlers.each do |key, handler|
|
33
|
+
pools.concat(handler.connection_pool_list.reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! })
|
34
|
+
end
|
35
|
+
else
|
36
|
+
pools.concat(ActiveRecord::Base.connection_handler.all_connection_pools.reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! })
|
33
37
|
end
|
34
38
|
|
35
|
-
pools
|
39
|
+
pools
|
36
40
|
end
|
37
41
|
|
38
42
|
def self.complete(pools)
|
39
43
|
pools.each { |pool| pool.disable_query_cache! }
|
40
44
|
|
41
|
-
ActiveRecord::Base.
|
42
|
-
|
45
|
+
if ActiveRecord::Base.legacy_connection_handling
|
46
|
+
ActiveRecord::Base.connection_handlers.each do |_, handler|
|
47
|
+
handler.connection_pool_list.each do |pool|
|
48
|
+
pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
else
|
52
|
+
ActiveRecord::Base.connection_handler.all_connection_pools.each do |pool|
|
43
53
|
pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
|
44
54
|
end
|
45
55
|
end
|
@@ -13,10 +13,11 @@ module ActiveRecord
|
|
13
13
|
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
14
14
|
:find_each, :find_in_batches, :in_batches,
|
15
15
|
:select, :reselect, :order, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
16
|
-
:where, :rewhere, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
16
|
+
:where, :rewhere, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
|
17
|
+
:and, :or, :annotate, :optimizer_hints, :extending,
|
18
|
+
:having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
|
19
|
+
:count, :average, :minimum, :maximum, :sum, :calculate,
|
20
|
+
:pluck, :pick, :ids, :strict_loading
|
20
21
|
].freeze # :nodoc:
|
21
22
|
delegate(*QUERYING_METHODS, to: :all)
|
22
23
|
|
@@ -36,7 +37,7 @@ module ActiveRecord
|
|
36
37
|
#
|
37
38
|
# # A simple SQL query spanning multiple tables
|
38
39
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
39
|
-
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "
|
40
|
+
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
|
40
41
|
#
|
41
42
|
# You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
|
42
43
|
#
|
@@ -44,8 +45,12 @@ module ActiveRecord
|
|
44
45
|
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
45
46
|
def find_by_sql(sql, binds = [], preparable: nil, &block)
|
46
47
|
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
|
47
|
-
column_types = result_set.column_types
|
48
|
-
|
48
|
+
column_types = result_set.column_types
|
49
|
+
|
50
|
+
unless column_types.empty?
|
51
|
+
column_types = column_types.reject { |k, _| attribute_types.key?(k) }
|
52
|
+
end
|
53
|
+
|
49
54
|
message_bus = ActiveSupport::Notifications.instrumenter
|
50
55
|
|
51
56
|
payload = {
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "active_record"
|
4
4
|
require "rails"
|
5
|
+
require "active_support/core_ext/object/try"
|
5
6
|
require "active_model/railtie"
|
6
7
|
|
7
8
|
# For now, action_controller must always be present with
|
@@ -26,18 +27,17 @@ module ActiveRecord
|
|
26
27
|
)
|
27
28
|
|
28
29
|
config.active_record.use_schema_cache_dump = true
|
30
|
+
config.active_record.check_schema_cache_dump_version = true
|
29
31
|
config.active_record.maintain_test_schema = true
|
32
|
+
config.active_record.has_many_inversing = false
|
30
33
|
|
31
|
-
config.active_record.
|
32
|
-
config.active_record.sqlite3.represent_boolean_as_integer = nil
|
34
|
+
config.active_record.queues = ActiveSupport::InheritableOptions.new
|
33
35
|
|
34
36
|
config.eager_load_namespaces << ActiveRecord
|
35
37
|
|
36
38
|
rake_tasks do
|
37
39
|
namespace :db do
|
38
40
|
task :load_config do
|
39
|
-
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
|
40
|
-
|
41
41
|
if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
|
42
42
|
if engine.paths["db/migrate"].existent
|
43
43
|
ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths["db/migrate"].to_a
|
@@ -57,6 +57,7 @@ module ActiveRecord
|
|
57
57
|
require "active_record/base"
|
58
58
|
unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
|
59
59
|
console = ActiveSupport::Logger.new(STDERR)
|
60
|
+
console.level = Rails.logger.level
|
60
61
|
Rails.logger.extend ActiveSupport::Logger.broadcast console
|
61
62
|
end
|
62
63
|
ActiveRecord::Base.verbose_query_logs = false
|
@@ -81,10 +82,11 @@ module ActiveRecord
|
|
81
82
|
ActiveSupport.on_load(:active_record) { LogSubscriber.backtrace_cleaner = ::Rails.backtrace_cleaner }
|
82
83
|
end
|
83
84
|
|
84
|
-
initializer "active_record.migration_error" do
|
85
|
+
initializer "active_record.migration_error" do |app|
|
85
86
|
if config.active_record.delete(:migration_error) == :page_load
|
86
87
|
config.app_middleware.insert_after ::ActionDispatch::Callbacks,
|
87
|
-
ActiveRecord::Migration::CheckPending
|
88
|
+
ActiveRecord::Migration::CheckPending,
|
89
|
+
file_watcher: app.config.file_watcher
|
88
90
|
end
|
89
91
|
end
|
90
92
|
|
@@ -114,7 +116,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
114
116
|
|
115
117
|
config.active_record.cache_versioning = false
|
116
118
|
|
117
|
-
end_error
|
119
|
+
end_error
|
118
120
|
end
|
119
121
|
end
|
120
122
|
end
|
@@ -122,23 +124,37 @@ end_error
|
|
122
124
|
end
|
123
125
|
|
124
126
|
initializer "active_record.check_schema_cache_dump" do
|
127
|
+
check_schema_cache_dump_version = config.active_record.delete(:check_schema_cache_dump_version)
|
128
|
+
|
125
129
|
if config.active_record.delete(:use_schema_cache_dump)
|
126
130
|
config.after_initialize do |app|
|
127
131
|
ActiveSupport.on_load(:active_record) do
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
|
133
|
+
|
134
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
|
135
|
+
db_config.name,
|
136
|
+
schema_cache_path: db_config&.schema_cache_path
|
137
|
+
)
|
138
|
+
|
139
|
+
cache = ActiveRecord::ConnectionAdapters::SchemaCache.load_from(filename)
|
140
|
+
next if cache.nil?
|
141
|
+
|
142
|
+
if check_schema_cache_dump_version
|
143
|
+
current_version = begin
|
144
|
+
ActiveRecord::Migrator.current_version
|
145
|
+
rescue ActiveRecordError => error
|
146
|
+
warn "Failed to validate the schema cache because of #{error.class}: #{error.message}"
|
147
|
+
nil
|
148
|
+
end
|
133
149
|
next if current_version.nil?
|
134
150
|
|
135
|
-
cache
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
|
151
|
+
if cache.version != current_version
|
152
|
+
warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
|
153
|
+
next
|
140
154
|
end
|
141
155
|
end
|
156
|
+
|
157
|
+
connection_pool.set_schema_cache(cache)
|
142
158
|
end
|
143
159
|
end
|
144
160
|
end
|
@@ -148,16 +164,29 @@ end_error
|
|
148
164
|
config.after_initialize do
|
149
165
|
ActiveSupport.on_load(:active_record) do
|
150
166
|
if app.config.eager_load
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
167
|
+
begin
|
168
|
+
descendants.each do |model|
|
169
|
+
# SchemaMigration and InternalMetadata both override `table_exists?`
|
170
|
+
# to bypass the schema cache, so skip them to avoid the extra queries.
|
171
|
+
next if model._internal?
|
172
|
+
|
173
|
+
# If the schema cache was loaded from a dump, we can use it without connecting
|
174
|
+
schema_cache = model.connection_pool.schema_cache
|
175
|
+
|
176
|
+
# If there's no connection yet, we avoid connecting.
|
177
|
+
schema_cache ||= model.connected? && model.connection.schema_cache
|
178
|
+
|
179
|
+
# If the schema cache doesn't have the columns
|
180
|
+
# hash for the model cached, `define_attribute_methods` would trigger a query.
|
181
|
+
if schema_cache && schema_cache.columns_hash?(model.table_name)
|
182
|
+
model.define_attribute_methods
|
183
|
+
end
|
184
|
+
end
|
185
|
+
rescue ActiveRecordError => error
|
186
|
+
# Regardless of whether there was already a connection or not, we rescue any database
|
187
|
+
# error because it is critical that the application can boot even if the database
|
188
|
+
# is unhealthy.
|
189
|
+
warn "Failed to define attribute methods because of #{error.class}: #{error.message}"
|
161
190
|
end
|
162
191
|
end
|
163
192
|
end
|
@@ -176,16 +205,6 @@ end_error
|
|
176
205
|
ActiveSupport.on_load(:active_record) do
|
177
206
|
configs = app.config.active_record
|
178
207
|
|
179
|
-
represent_boolean_as_integer = configs.sqlite3.delete(:represent_boolean_as_integer)
|
180
|
-
|
181
|
-
unless represent_boolean_as_integer.nil?
|
182
|
-
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
183
|
-
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
configs.delete(:sqlite3)
|
188
|
-
|
189
208
|
configs.each do |k, v|
|
190
209
|
send "#{k}=", v
|
191
210
|
end
|
@@ -196,7 +215,9 @@ end_error
|
|
196
215
|
# and then establishes the connection.
|
197
216
|
initializer "active_record.initialize_database" do
|
198
217
|
ActiveSupport.on_load(:active_record) do
|
199
|
-
|
218
|
+
if ActiveRecord::Base.legacy_connection_handling
|
219
|
+
self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler }
|
220
|
+
end
|
200
221
|
self.configurations = Rails.application.config.database_configuration
|
201
222
|
establish_connection
|
202
223
|
end
|
@@ -210,13 +231,6 @@ end_error
|
|
210
231
|
end
|
211
232
|
end
|
212
233
|
|
213
|
-
initializer "active_record.collection_cache_association_loading" do
|
214
|
-
require "active_record/railties/collection_cache_association_loading"
|
215
|
-
ActiveSupport.on_load(:action_view) do
|
216
|
-
ActionView::PartialRenderer.prepend(ActiveRecord::Railties::CollectionCacheAssociationLoading)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
234
|
initializer "active_record.set_reloader_hooks" do
|
221
235
|
ActiveSupport.on_load(:active_record) do
|
222
236
|
ActiveSupport::Reloader.before_class_unload do
|
@@ -259,5 +273,11 @@ end_error
|
|
259
273
|
self.filter_attributes += Rails.application.config.filter_parameters
|
260
274
|
end
|
261
275
|
end
|
276
|
+
|
277
|
+
initializer "active_record.set_signed_id_verifier_secret" do
|
278
|
+
ActiveSupport.on_load(:active_record) do
|
279
|
+
self.signed_id_verifier_secret ||= -> { Rails.application.key_generator.generate_key("active_record/signed_id") }
|
280
|
+
end
|
281
|
+
end
|
262
282
|
end
|
263
283
|
end
|