activerecord 6.1.3.2 → 7.0.0.alpha2
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 +734 -1058
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +35 -7
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +16 -6
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +24 -25
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/preloader/association.rb +161 -49
- data/lib/active_record/associations/preloader/batch.rb +51 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +37 -11
- data/lib/active_record/associations/preloader.rb +46 -110
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +76 -81
- data/lib/active_record/asynchronous_queries_tracker.rb +57 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +41 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +6 -9
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +3 -18
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +11 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +312 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +31 -558
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +45 -21
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -7
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +5 -18
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -9
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +60 -16
- data/lib/active_record/connection_adapters/abstract/transaction.rb +17 -6
- data/lib/active_record/connection_adapters/abstract_adapter.rb +115 -69
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +96 -81
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +6 -2
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +33 -21
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +1 -3
- data/lib/active_record/connection_adapters/pool_manager.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +12 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +157 -100
- data/lib/active_record/connection_adapters/schema_cache.rb +35 -4
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +0 -2
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +23 -17
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +8 -5
- data/lib/active_record/connection_handling.rb +20 -38
- data/lib/active_record/core.rb +129 -117
- data/lib/active_record/database_configurations/database_config.rb +12 -0
- data/lib/active_record/database_configurations/hash_config.rb +27 -1
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +18 -9
- data/lib/active_record/delegated_type.rb +33 -11
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +61 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +208 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +29 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +80 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +44 -46
- data/lib/active_record/errors.rb +66 -3
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +40 -5
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +16 -11
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +39 -6
- data/lib/active_record/integration.rb +1 -1
- data/lib/active_record/internal_metadata.rb +3 -5
- data/lib/active_record/legacy_yaml_adapter.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/log_subscriber.rb +6 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +83 -1
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +109 -79
- data/lib/active_record/model_schema.rb +46 -32
- data/lib/active_record/nested_attributes.rb +3 -3
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +134 -45
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +203 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +117 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +83 -58
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +45 -44
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +42 -25
- data/lib/active_record/relation/delegation.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +32 -23
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +233 -50
- data/lib/active_record/relation/record_fetch_warning.rb +2 -2
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +22 -15
- data/lib/active_record/relation.rb +170 -87
- data/lib/active_record/result.rb +17 -2
- data/lib/active_record/runtime_registry.rb +2 -4
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +3 -3
- data/lib/active_record/schema_migration.rb +0 -4
- data/lib/active_record/scoping/default.rb +62 -15
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +40 -22
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/tasks/database_tasks.rb +107 -23
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -11
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +45 -4
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/numericality.rb +1 -1
- data/lib/active_record.rb +170 -2
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/collectors/bind.rb +2 -2
- data/lib/arel/collectors/composite.rb +3 -3
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/crud.rb +18 -22
- data/lib/arel/delete_manager.rb +2 -4
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +8 -13
- data/lib/arel/nodes/homogeneous_in.rb +4 -0
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +3 -2
- data/lib/arel/predications.rb +3 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +2 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +6 -1
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +44 -3
- data/lib/arel.rb +1 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- metadata +55 -16
@@ -86,19 +86,30 @@ db_namespace = namespace :db do
|
|
86
86
|
|
87
87
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
88
88
|
task migrate: :load_config do
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
|
90
|
+
|
91
|
+
if db_configs.size == 1
|
92
92
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
93
|
+
else
|
94
|
+
original_db_config = ActiveRecord::Base.connection_db_config
|
95
|
+
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
|
96
|
+
|
97
|
+
mapped_versions.sort.each do |version, db_configs|
|
98
|
+
db_configs.each do |db_config|
|
99
|
+
ActiveRecord::Base.establish_connection(db_config)
|
100
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate(version)
|
101
|
+
end
|
102
|
+
end
|
93
103
|
end
|
104
|
+
|
94
105
|
db_namespace["_dump"].invoke
|
95
106
|
ensure
|
96
|
-
ActiveRecord::Base.establish_connection(original_db_config)
|
107
|
+
ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
|
97
108
|
end
|
98
109
|
|
99
|
-
# IMPORTANT: This task won't dump the schema if ActiveRecord
|
110
|
+
# IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
|
100
111
|
task :_dump do
|
101
|
-
if ActiveRecord
|
112
|
+
if ActiveRecord.dump_schema_after_migration
|
102
113
|
db_namespace["schema:dump"].invoke
|
103
114
|
end
|
104
115
|
# Allow this task to be called as many times as required. An example is the
|
@@ -108,11 +119,15 @@ db_namespace = namespace :db do
|
|
108
119
|
|
109
120
|
namespace :_dump do
|
110
121
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
111
|
-
# IMPORTANT: This task won't dump the schema if ActiveRecord
|
122
|
+
# IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
|
112
123
|
task name do
|
113
|
-
|
124
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
|
125
|
+
|
126
|
+
if ActiveRecord.dump_schema_after_migration && db_config.schema_dump
|
127
|
+
ActiveRecord::Base.establish_connection(db_config)
|
114
128
|
db_namespace["schema:dump:#{name}"].invoke
|
115
129
|
end
|
130
|
+
|
116
131
|
# Allow this task to be called as many times as required. An example is the
|
117
132
|
# migrate:redo task, which calls other two internally that depend on this one.
|
118
133
|
db_namespace["_dump:#{name}"].reenable
|
@@ -275,6 +290,7 @@ db_namespace = namespace :db do
|
|
275
290
|
desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
|
276
291
|
task rollback: :load_config do
|
277
292
|
ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback")
|
293
|
+
raise "VERSION is not supported - To rollback a specific version, use db:migrate:down" if ENV["VERSION"]
|
278
294
|
|
279
295
|
step = ENV["STEP"] ? ENV["STEP"].to_i : 1
|
280
296
|
|
@@ -290,7 +306,16 @@ db_namespace = namespace :db do
|
|
290
306
|
db_namespace["_dump"].invoke
|
291
307
|
end
|
292
308
|
|
293
|
-
|
309
|
+
namespace :reset do
|
310
|
+
task all: ["db:drop", "db:setup"]
|
311
|
+
|
312
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
313
|
+
desc "Drops and recreates the #{name} database from its schema for the current environment and loads the seeds."
|
314
|
+
task name => ["db:drop:#{name}", "db:setup:#{name}"]
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
desc "Drops and recreates all databases from their schema for the current environment and loads the seeds."
|
294
319
|
task reset: [ "db:drop", "db:setup" ]
|
295
320
|
|
296
321
|
# desc "Retrieves the charset for the current environment's database"
|
@@ -349,41 +374,21 @@ db_namespace = namespace :db do
|
|
349
374
|
end
|
350
375
|
end
|
351
376
|
|
352
|
-
|
377
|
+
namespace :setup do
|
378
|
+
task all: ["db:create", :environment, "db:schema:load", :seed]
|
379
|
+
|
380
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
381
|
+
desc "Creates the #{name} database, loads the schema, and initializes with the seed data (use db:reset:#{name} to also drop the database first)"
|
382
|
+
task name => ["db:create:#{name}", :environment, "db:schema:load:#{name}", "db:seed"]
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
desc "Creates all databases, loads all schemas, and initializes with the seed data (use db:reset to also drop all databases first)"
|
353
387
|
task setup: ["db:create", :environment, "db:schema:load", :seed]
|
354
388
|
|
355
389
|
desc "Runs setup if database does not exist, or runs migrations if it does"
|
356
390
|
task prepare: :load_config do
|
357
|
-
|
358
|
-
|
359
|
-
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
360
|
-
ActiveRecord::Base.establish_connection(db_config)
|
361
|
-
|
362
|
-
# Skipped when no database
|
363
|
-
ActiveRecord::Tasks::DatabaseTasks.migrate
|
364
|
-
|
365
|
-
if ActiveRecord::Base.dump_schema_after_migration
|
366
|
-
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ActiveRecord::Base.schema_format)
|
367
|
-
end
|
368
|
-
rescue ActiveRecord::NoDatabaseError
|
369
|
-
config_name = db_config.name
|
370
|
-
ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, config_name)
|
371
|
-
|
372
|
-
if File.exist?(ActiveRecord::Tasks::DatabaseTasks.dump_filename(config_name))
|
373
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(
|
374
|
-
db_config,
|
375
|
-
ActiveRecord::Base.schema_format,
|
376
|
-
nil
|
377
|
-
)
|
378
|
-
else
|
379
|
-
ActiveRecord::Tasks::DatabaseTasks.migrate
|
380
|
-
end
|
381
|
-
|
382
|
-
seed = true
|
383
|
-
end
|
384
|
-
|
385
|
-
ActiveRecord::Base.establish_connection
|
386
|
-
ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
|
391
|
+
ActiveRecord::Tasks::DatabaseTasks.prepare_all
|
387
392
|
end
|
388
393
|
|
389
394
|
desc "Loads the seed data from db/seeds.rb"
|
@@ -413,8 +418,9 @@ db_namespace = namespace :db do
|
|
413
418
|
fixture_files = if ENV["FIXTURES"]
|
414
419
|
ENV["FIXTURES"].split(",")
|
415
420
|
else
|
416
|
-
|
417
|
-
|
421
|
+
files = Dir[File.join(fixtures_dir, "**/*.{yml}")]
|
422
|
+
files.reject! { |f| f.start_with?(File.join(fixtures_dir, "files")) }
|
423
|
+
files.map! { |f| f[fixtures_dir.to_s.size..-5].delete_prefix("/") }
|
418
424
|
end
|
419
425
|
|
420
426
|
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_files)
|
@@ -449,8 +455,10 @@ db_namespace = namespace :db do
|
|
449
455
|
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
|
450
456
|
task dump: :load_config do
|
451
457
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
452
|
-
|
453
|
-
|
458
|
+
if db_config.schema_dump
|
459
|
+
ActiveRecord::Base.establish_connection(db_config)
|
460
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
|
461
|
+
end
|
454
462
|
end
|
455
463
|
|
456
464
|
db_namespace["schema:dump"].reenable
|
@@ -458,15 +466,15 @@ db_namespace = namespace :db do
|
|
458
466
|
|
459
467
|
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database"
|
460
468
|
task load: [:load_config, :check_protected_environments] do
|
461
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord
|
469
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
|
462
470
|
end
|
463
471
|
|
464
472
|
task load_if_ruby: ["db:create", :environment] do
|
465
473
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
466
|
-
Using `bin/rails db:schema:load_if_ruby` is deprecated and will be removed in Rails
|
474
|
+
Using `bin/rails db:schema:load_if_ruby` is deprecated and will be removed in Rails 7.0.
|
467
475
|
Configure the format using `config.active_record.schema_format = :ruby` to use `schema.rb` and run `bin/rails db:schema:load` instead.
|
468
476
|
MSG
|
469
|
-
db_namespace["schema:load"].invoke if ActiveRecord
|
477
|
+
db_namespace["schema:load"].invoke if ActiveRecord.schema_format == :ruby
|
470
478
|
end
|
471
479
|
|
472
480
|
namespace :dump do
|
@@ -485,8 +493,11 @@ db_namespace = namespace :db do
|
|
485
493
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
486
494
|
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the #{name} database"
|
487
495
|
task name => :load_config do
|
496
|
+
original_db_config = ActiveRecord::Base.connection_db_config
|
488
497
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
|
489
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord
|
498
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord.schema_format, ENV["SCHEMA"])
|
499
|
+
ensure
|
500
|
+
ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
|
490
501
|
end
|
491
502
|
end
|
492
503
|
end
|
@@ -526,7 +537,7 @@ db_namespace = namespace :db do
|
|
526
537
|
desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
|
527
538
|
task dump: :load_config do
|
528
539
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
529
|
-
Using `bin/rails db:structure:dump` is deprecated and will be removed in Rails
|
540
|
+
Using `bin/rails db:structure:dump` is deprecated and will be removed in Rails 7.0.
|
530
541
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump` instead.
|
531
542
|
MSG
|
532
543
|
|
@@ -537,7 +548,7 @@ db_namespace = namespace :db do
|
|
537
548
|
desc "Recreates the databases from the structure.sql file"
|
538
549
|
task load: [:load_config, :check_protected_environments] do
|
539
550
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
540
|
-
Using `bin/rails db:structure:load` is deprecated and will be removed in Rails
|
551
|
+
Using `bin/rails db:structure:load` is deprecated and will be removed in Rails 7.0.
|
541
552
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
|
542
553
|
MSG
|
543
554
|
db_namespace["schema:load"].invoke
|
@@ -545,10 +556,10 @@ db_namespace = namespace :db do
|
|
545
556
|
|
546
557
|
task load_if_sql: ["db:create", :environment] do
|
547
558
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
548
|
-
Using `bin/rails db:structure:load_if_sql` is deprecated and will be removed in Rails
|
559
|
+
Using `bin/rails db:structure:load_if_sql` is deprecated and will be removed in Rails 7.0.
|
549
560
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
|
550
561
|
MSG
|
551
|
-
db_namespace["schema:load"].invoke if ActiveRecord
|
562
|
+
db_namespace["schema:load"].invoke if ActiveRecord.schema_format == :sql
|
552
563
|
end
|
553
564
|
|
554
565
|
namespace :dump do
|
@@ -556,7 +567,7 @@ db_namespace = namespace :db do
|
|
556
567
|
desc "Dumps the #{name} database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
|
557
568
|
task name => :load_config do
|
558
569
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
559
|
-
Using `bin/rails db:structure:dump:#{name}` is deprecated and will be removed in Rails
|
570
|
+
Using `bin/rails db:structure:dump:#{name}` is deprecated and will be removed in Rails 7.0.
|
560
571
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump:#{name}` instead.
|
561
572
|
MSG
|
562
573
|
db_namespace["schema:dump:#{name}"].invoke
|
@@ -570,7 +581,7 @@ db_namespace = namespace :db do
|
|
570
581
|
desc "Recreates the #{name} database from the structure.sql file"
|
571
582
|
task name => :load_config do
|
572
583
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
573
|
-
Using `bin/rails db:structure:load:#{name}` is deprecated and will be removed in Rails
|
584
|
+
Using `bin/rails db:structure:load:#{name}` is deprecated and will be removed in Rails 7.0.
|
574
585
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load:#{name}` instead.
|
575
586
|
MSG
|
576
587
|
db_namespace["schema:load:#{name}"].invoke
|
@@ -579,6 +590,20 @@ db_namespace = namespace :db do
|
|
579
590
|
end
|
580
591
|
end
|
581
592
|
|
593
|
+
namespace :encryption do
|
594
|
+
desc "Generate a set of keys for configuring Active Record encryption in a given environment"
|
595
|
+
task :init do
|
596
|
+
puts <<~MSG
|
597
|
+
Add this entry to the credentials of the target environment:#{' '}
|
598
|
+
|
599
|
+
active_record_encryption:
|
600
|
+
primary_key: #{SecureRandom.alphanumeric(32)}
|
601
|
+
deterministic_key: #{SecureRandom.alphanumeric(32)}
|
602
|
+
key_derivation_salt: #{SecureRandom.alphanumeric(32)}
|
603
|
+
MSG
|
604
|
+
end
|
605
|
+
end
|
606
|
+
|
582
607
|
namespace :test do
|
583
608
|
# desc "Recreate the test database from the current schema"
|
584
609
|
task load: %w(db:test:purge) do
|
@@ -591,7 +616,7 @@ db_namespace = namespace :db do
|
|
591
616
|
ActiveRecord::Schema.verbose = false
|
592
617
|
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
593
618
|
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.name)
|
594
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord
|
619
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord.schema_format, filename)
|
595
620
|
end
|
596
621
|
ensure
|
597
622
|
if should_reconnect
|
@@ -602,7 +627,7 @@ db_namespace = namespace :db do
|
|
602
627
|
# desc "Recreate the test database from an existent structure.sql file"
|
603
628
|
task load_structure: %w(db:test:purge) do
|
604
629
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
605
|
-
Using `bin/rails db:test:load_structure` is deprecated and will be removed in Rails
|
630
|
+
Using `bin/rails db:test:load_structure` is deprecated and will be removed in Rails 7.0.
|
606
631
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_schema` instead.
|
607
632
|
MSG
|
608
633
|
db_namespace["test:load_schema"].invoke
|
@@ -637,7 +662,7 @@ db_namespace = namespace :db do
|
|
637
662
|
ActiveRecord::Schema.verbose = false
|
638
663
|
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(name)
|
639
664
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
|
640
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord
|
665
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord.schema_format, filename)
|
641
666
|
ensure
|
642
667
|
if should_reconnect
|
643
668
|
ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
|
@@ -649,7 +674,7 @@ db_namespace = namespace :db do
|
|
649
674
|
namespace :load_structure do
|
650
675
|
task name => "db:test:purge:#{name}" do
|
651
676
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
652
|
-
Using `bin/rails db:test:load_structure:#{name}` is deprecated and will be removed in Rails
|
677
|
+
Using `bin/rails db:test:load_structure:#{name}` is deprecated and will be removed in Rails 7.0.
|
653
678
|
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_structure:#{name}` instead.
|
654
679
|
MSG
|
655
680
|
db_namespace["test:load_schema:#{name}"].invoke
|
@@ -11,6 +11,17 @@ module ActiveRecord
|
|
11
11
|
module ClassMethods
|
12
12
|
# Attributes listed as readonly will be used to create a new record but update operations will
|
13
13
|
# ignore these fields.
|
14
|
+
#
|
15
|
+
# You can assign a new value to a readonly attribute, but it will be ignored when the record is updated.
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# class Post < ActiveRecord::Base
|
20
|
+
# attr_readonly :title
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# post = Post.create!(title: "Introducing Ruby on Rails!")
|
24
|
+
# post.update(title: "a different title") # change to title will be ignored
|
14
25
|
def attr_readonly(*attributes)
|
15
26
|
self._attr_readonly = Set.new(attributes.map(&:to_s)) + (_attr_readonly || [])
|
16
27
|
end
|
@@ -115,7 +115,7 @@ module ActiveRecord
|
|
115
115
|
reflections[association.to_s]
|
116
116
|
end
|
117
117
|
|
118
|
-
def _reflect_on_association(association)
|
118
|
+
def _reflect_on_association(association) # :nodoc:
|
119
119
|
_reflections[association.to_s]
|
120
120
|
end
|
121
121
|
|
@@ -194,9 +194,9 @@ module ActiveRecord
|
|
194
194
|
klass_scope
|
195
195
|
end
|
196
196
|
|
197
|
-
def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
|
197
|
+
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
198
198
|
if scope
|
199
|
-
[scope_for(build_scope(table, predicate_builder, klass))]
|
199
|
+
[scope_for(build_scope(table, predicate_builder, klass), record)]
|
200
200
|
else
|
201
201
|
[]
|
202
202
|
end
|
@@ -237,7 +237,7 @@ module ActiveRecord
|
|
237
237
|
end
|
238
238
|
end
|
239
239
|
|
240
|
-
#
|
240
|
+
# We need to avoid the following situation:
|
241
241
|
#
|
242
242
|
# * An associated record is deleted via record.destroy
|
243
243
|
# * Hence the callbacks run, and they find a belongs_to on the record with a
|
@@ -306,6 +306,12 @@ module ActiveRecord
|
|
306
306
|
def primary_key(klass)
|
307
307
|
klass.primary_key || raise(UnknownPrimaryKey.new(klass))
|
308
308
|
end
|
309
|
+
|
310
|
+
def ensure_option_not_given_as_class!(option_name)
|
311
|
+
if options[option_name] && options[option_name].class == Class
|
312
|
+
raise ArgumentError, "A class was passed to `:#{option_name}` but we are expecting a string."
|
313
|
+
end
|
314
|
+
end
|
309
315
|
end
|
310
316
|
|
311
317
|
# Base class for AggregateReflection and AssociationReflection. Objects of
|
@@ -392,7 +398,7 @@ module ActiveRecord
|
|
392
398
|
|
393
399
|
# Holds all the metadata about an aggregation as it was specified in the
|
394
400
|
# Active Record class.
|
395
|
-
class AggregateReflection < MacroReflection
|
401
|
+
class AggregateReflection < MacroReflection # :nodoc:
|
396
402
|
def mapping
|
397
403
|
mapping = options[:mapping] || [name, name]
|
398
404
|
mapping.first.is_a?(Array) ? mapping : [mapping]
|
@@ -401,12 +407,29 @@ module ActiveRecord
|
|
401
407
|
|
402
408
|
# Holds all the metadata about an association as it was specified in the
|
403
409
|
# Active Record class.
|
404
|
-
class AssociationReflection < MacroReflection
|
410
|
+
class AssociationReflection < MacroReflection # :nodoc:
|
405
411
|
def compute_class(name)
|
406
412
|
if polymorphic?
|
407
413
|
raise ArgumentError, "Polymorphic associations do not support computing the class."
|
408
414
|
end
|
409
|
-
|
415
|
+
|
416
|
+
msg = <<-MSG.squish
|
417
|
+
Rails couldn't find a valid model for #{name} association.
|
418
|
+
Please provide the :class_name option on the association declaration.
|
419
|
+
If :class_name is already provided, make sure it's an ActiveRecord::Base subclass.
|
420
|
+
MSG
|
421
|
+
|
422
|
+
begin
|
423
|
+
klass = active_record.send(:compute_type, name)
|
424
|
+
|
425
|
+
unless klass < ActiveRecord::Base
|
426
|
+
raise ArgumentError, msg
|
427
|
+
end
|
428
|
+
|
429
|
+
klass
|
430
|
+
rescue NameError
|
431
|
+
raise NameError, msg
|
432
|
+
end
|
410
433
|
end
|
411
434
|
|
412
435
|
attr_reader :type, :foreign_type
|
@@ -416,11 +439,8 @@ module ActiveRecord
|
|
416
439
|
super
|
417
440
|
@type = -(options[:foreign_type]&.to_s || "#{options[:as]}_type") if options[:as]
|
418
441
|
@foreign_type = -(options[:foreign_type]&.to_s || "#{name}_type") if options[:polymorphic]
|
419
|
-
@constructable = calculate_constructable(macro, options)
|
420
442
|
|
421
|
-
|
422
|
-
raise ArgumentError, "A class was passed to `:class_name` but we are expecting a string."
|
423
|
-
end
|
443
|
+
ensure_option_not_given_as_class!(:class_name)
|
424
444
|
end
|
425
445
|
|
426
446
|
def association_scope_cache(klass, owner, &block)
|
@@ -431,10 +451,6 @@ module ActiveRecord
|
|
431
451
|
klass.cached_find_by_statement(key, &block)
|
432
452
|
end
|
433
453
|
|
434
|
-
def constructable? # :nodoc:
|
435
|
-
@constructable
|
436
|
-
end
|
437
|
-
|
438
454
|
def join_table
|
439
455
|
@join_table ||= -(options[:join_table]&.to_s || derive_join_table)
|
440
456
|
end
|
@@ -467,18 +483,17 @@ module ActiveRecord
|
|
467
483
|
check_validity_of_inverse!
|
468
484
|
end
|
469
485
|
|
470
|
-
def
|
486
|
+
def check_eager_loadable!
|
471
487
|
return unless scope
|
472
488
|
|
473
489
|
unless scope.arity == 0
|
474
490
|
raise ArgumentError, <<-MSG.squish
|
475
491
|
The association scope '#{name}' is instance dependent (the scope
|
476
|
-
block takes an argument).
|
477
|
-
not supported.
|
492
|
+
block takes an argument). Eager loading instance dependent scopes
|
493
|
+
is not supported.
|
478
494
|
MSG
|
479
495
|
end
|
480
496
|
end
|
481
|
-
alias :check_eager_loadable! :check_preloadable!
|
482
497
|
|
483
498
|
def join_id_for(owner) # :nodoc:
|
484
499
|
owner[join_foreign_key]
|
@@ -563,9 +578,6 @@ module ActiveRecord
|
|
563
578
|
options[:polymorphic]
|
564
579
|
end
|
565
580
|
|
566
|
-
VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_one, :belongs_to]
|
567
|
-
INVALID_AUTOMATIC_INVERSE_OPTIONS = [:through, :foreign_key]
|
568
|
-
|
569
581
|
def add_as_source(seed)
|
570
582
|
seed
|
571
583
|
end
|
@@ -583,10 +595,6 @@ module ActiveRecord
|
|
583
595
|
end
|
584
596
|
|
585
597
|
private
|
586
|
-
def calculate_constructable(macro, options)
|
587
|
-
true
|
588
|
-
end
|
589
|
-
|
590
598
|
# Attempts to find the inverse association name automatically.
|
591
599
|
# If it cannot find a suitable inverse association name, it returns
|
592
600
|
# +nil+.
|
@@ -639,8 +647,8 @@ module ActiveRecord
|
|
639
647
|
# inverse, so we exclude reflections with scopes.
|
640
648
|
def can_find_inverse_of_automatically?(reflection)
|
641
649
|
reflection.options[:inverse_of] != false &&
|
642
|
-
|
643
|
-
!
|
650
|
+
!reflection.options[:through] &&
|
651
|
+
!reflection.options[:foreign_key] &&
|
644
652
|
!reflection.scope
|
645
653
|
end
|
646
654
|
|
@@ -656,7 +664,7 @@ module ActiveRecord
|
|
656
664
|
elsif options[:as]
|
657
665
|
"#{options[:as]}_id"
|
658
666
|
else
|
659
|
-
active_record.
|
667
|
+
active_record.model_name.to_s.foreign_key
|
660
668
|
end
|
661
669
|
end
|
662
670
|
|
@@ -691,11 +699,6 @@ module ActiveRecord
|
|
691
699
|
Associations::HasOneAssociation
|
692
700
|
end
|
693
701
|
end
|
694
|
-
|
695
|
-
private
|
696
|
-
def calculate_constructable(macro, options)
|
697
|
-
!options[:through]
|
698
|
-
end
|
699
702
|
end
|
700
703
|
|
701
704
|
class BelongsToReflection < AssociationReflection # :nodoc:
|
@@ -736,10 +739,6 @@ module ActiveRecord
|
|
736
739
|
def can_find_inverse_of_automatically?(_)
|
737
740
|
!polymorphic? && super
|
738
741
|
end
|
739
|
-
|
740
|
-
def calculate_constructable(macro, options)
|
741
|
-
!polymorphic?
|
742
|
-
end
|
743
742
|
end
|
744
743
|
|
745
744
|
class HasAndBelongsToManyReflection < AssociationReflection # :nodoc:
|
@@ -752,7 +751,7 @@ module ActiveRecord
|
|
752
751
|
|
753
752
|
# Holds all the metadata about a :through association as it was specified
|
754
753
|
# in the Active Record class.
|
755
|
-
class ThroughReflection < AbstractReflection
|
754
|
+
class ThroughReflection < AbstractReflection # :nodoc:
|
756
755
|
delegate :foreign_key, :foreign_type, :association_foreign_key, :join_id_for, :type,
|
757
756
|
:active_record_primary_key, :join_foreign_key, to: :source_reflection
|
758
757
|
|
@@ -760,6 +759,8 @@ module ActiveRecord
|
|
760
759
|
@delegate_reflection = delegate_reflection
|
761
760
|
@klass = delegate_reflection.options[:anonymous_class]
|
762
761
|
@source_reflection_name = delegate_reflection.options[:source]
|
762
|
+
|
763
|
+
ensure_option_not_given_as_class!(:source_type)
|
763
764
|
end
|
764
765
|
|
765
766
|
def through_reflection?
|
@@ -840,8 +841,8 @@ module ActiveRecord
|
|
840
841
|
source_reflection.scopes + super
|
841
842
|
end
|
842
843
|
|
843
|
-
def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
|
844
|
-
source_reflection.join_scopes(table, predicate_builder, klass) + super
|
844
|
+
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
845
|
+
source_reflection.join_scopes(table, predicate_builder, klass, record) + super
|
845
846
|
end
|
846
847
|
|
847
848
|
def has_scope?
|
@@ -1013,9 +1014,9 @@ module ActiveRecord
|
|
1013
1014
|
@previous_reflection = previous_reflection
|
1014
1015
|
end
|
1015
1016
|
|
1016
|
-
def join_scopes(table, predicate_builder, klass = self.klass) # :nodoc:
|
1017
|
-
scopes = @previous_reflection.join_scopes(table, predicate_builder) + super
|
1018
|
-
scopes << build_scope(table, predicate_builder, klass).instance_exec(
|
1017
|
+
def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
|
1018
|
+
scopes = @previous_reflection.join_scopes(table, predicate_builder, record) + super
|
1019
|
+
scopes << build_scope(table, predicate_builder, klass).instance_exec(record, &source_type_scope)
|
1019
1020
|
end
|
1020
1021
|
|
1021
1022
|
def constraints
|