activerecord 6.1.6 → 7.0.4
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 +1314 -975
- 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 +33 -17
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- 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 +10 -3
- 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 +19 -21
- data/lib/active_record/associations/collection_proxy.rb +10 -5
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +8 -5
- 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/join_dependency.rb +23 -15
- data/lib/active_record/associations/preloader/association.rb +186 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +49 -13
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +124 -95
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -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 +49 -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 +57 -19
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +14 -15
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +8 -23
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +10 -2
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -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 +47 -561
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +38 -13
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +80 -24
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +105 -81
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -24
- data/lib/active_record/connection_adapters/mysql/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -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 +30 -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 +51 -51
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +37 -19
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +208 -107
- data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +17 -15
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +96 -32
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +49 -55
- data/lib/active_record/core.rb +124 -134
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -9
- data/lib/active_record/database_configurations/hash_config.rb +63 -5
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +15 -32
- data/lib/active_record/delegated_type.rb +53 -12
- 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 +67 -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 +206 -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 +28 -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 +90 -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 +50 -43
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +41 -6
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +20 -23
- 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 +80 -14
- data/lib/active_record/integration.rb +4 -3
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/locking/pessimistic.rb +10 -4
- data/lib/active_record/log_subscriber.rb +23 -7
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +18 -6
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +7 -7
- data/lib/active_record/migration/compatibility.rb +84 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +114 -83
- data/lib/active_record/model_schema.rb +58 -59
- data/lib/active_record/nested_attributes.rb +13 -12
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +228 -60
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +138 -0
- data/lib/active_record/querying.rb +16 -6
- data/lib/active_record/railtie.rb +136 -22
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +78 -136
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +73 -50
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +6 -6
- data/lib/active_record/relation/calculations.rb +43 -38
- data/lib/active_record/relation/delegation.rb +7 -7
- data/lib/active_record/relation/finder_methods.rb +31 -35
- 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 +276 -67
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +189 -88
- data/lib/active_record/result.rb +17 -7
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +17 -12
- data/lib/active_record/schema.rb +38 -23
- data/lib/active_record/schema_dumper.rb +25 -19
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +60 -13
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +3 -3
- data/lib/active_record/store.rb +7 -2
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/tasks/database_tasks.rb +127 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +16 -9
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +3 -3
- 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 +4 -4
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +217 -27
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -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 +8 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +11 -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 +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +8 -2
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +58 -2
- data/lib/arel.rb +2 -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
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +55 -11
@@ -3,7 +3,7 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Querying
|
5
5
|
QUERYING_METHODS = [
|
6
|
-
:find, :find_by, :find_by!, :take, :take!, :first, :first!, :last, :last!,
|
6
|
+
:find, :find_by, :find_by!, :take, :take!, :sole, :find_sole_by, :first, :first!, :last, :last!,
|
7
7
|
:second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!,
|
8
8
|
:forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!,
|
9
9
|
:exists?, :any?, :many?, :none?, :one?,
|
@@ -12,12 +12,12 @@ module ActiveRecord
|
|
12
12
|
:create_or_find_by, :create_or_find_by!,
|
13
13
|
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
14
14
|
:find_each, :find_in_batches, :in_batches,
|
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,
|
15
|
+
:select, :reselect, :order, :in_order_of, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
16
|
+
:where, :rewhere, :invert_where, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
|
17
17
|
:and, :or, :annotate, :optimizer_hints, :extending,
|
18
18
|
:having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
|
19
19
|
:count, :average, :minimum, :maximum, :sum, :calculate,
|
20
|
-
:pluck, :pick, :ids, :strict_loading
|
20
|
+
:pluck, :pick, :ids, :strict_loading, :excluding, :without
|
21
21
|
].freeze # :nodoc:
|
22
22
|
delegate(*QUERYING_METHODS, to: :all)
|
23
23
|
|
@@ -39,12 +39,22 @@ module ActiveRecord
|
|
39
39
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
40
40
|
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
|
41
41
|
#
|
42
|
-
# You can use the same string replacement techniques as you can with
|
42
|
+
# You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where :
|
43
43
|
#
|
44
44
|
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
|
45
45
|
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
|
46
|
+
#
|
47
|
+
# Note that building your own SQL query string from user input may expose your application to
|
48
|
+
# injection attacks (https://guides.rubyonrails.org/security.html#sql-injection).
|
46
49
|
def find_by_sql(sql, binds = [], preparable: nil, &block)
|
47
|
-
|
50
|
+
_load_from_sql(_query_by_sql(sql, binds, preparable: preparable), &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def _query_by_sql(sql, binds = [], preparable: nil, async: false) # :nodoc:
|
54
|
+
connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable, async: async)
|
55
|
+
end
|
56
|
+
|
57
|
+
def _load_from_sql(result_set, &block) # :nodoc:
|
48
58
|
column_types = result_set.column_types
|
49
59
|
|
50
60
|
unless column_types.empty?
|
@@ -15,6 +15,7 @@ module ActiveRecord
|
|
15
15
|
# = Active Record Railtie
|
16
16
|
class Railtie < Rails::Railtie # :nodoc:
|
17
17
|
config.active_record = ActiveSupport::OrderedOptions.new
|
18
|
+
config.active_record.encryption = ActiveSupport::OrderedOptions.new
|
18
19
|
|
19
20
|
config.app_generators.orm :active_record, migration: true,
|
20
21
|
timestamps: true
|
@@ -30,6 +31,10 @@ module ActiveRecord
|
|
30
31
|
config.active_record.check_schema_cache_dump_version = true
|
31
32
|
config.active_record.maintain_test_schema = true
|
32
33
|
config.active_record.has_many_inversing = false
|
34
|
+
config.active_record.sqlite3_production_warning = true
|
35
|
+
config.active_record.query_log_tags_enabled = false
|
36
|
+
config.active_record.query_log_tags = [ :application ]
|
37
|
+
config.active_record.cache_query_log_tags = false
|
33
38
|
|
34
39
|
config.active_record.queues = ActiveSupport::InheritableOptions.new
|
35
40
|
|
@@ -60,7 +65,7 @@ module ActiveRecord
|
|
60
65
|
console.level = Rails.logger.level
|
61
66
|
Rails.logger.extend ActiveSupport::Logger.broadcast console
|
62
67
|
end
|
63
|
-
ActiveRecord
|
68
|
+
ActiveRecord.verbose_query_logs = false
|
64
69
|
end
|
65
70
|
|
66
71
|
runner do
|
@@ -70,7 +75,12 @@ module ActiveRecord
|
|
70
75
|
initializer "active_record.initialize_timezone" do
|
71
76
|
ActiveSupport.on_load(:active_record) do
|
72
77
|
self.time_zone_aware_attributes = true
|
73
|
-
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
initializer "active_record.postgresql_time_zone_aware_types" do
|
82
|
+
ActiveSupport.on_load(:active_record_postgresqladapter) do
|
83
|
+
ActiveRecord::Base.time_zone_aware_types << :timestamptz
|
74
84
|
end
|
75
85
|
end
|
76
86
|
|
@@ -83,21 +93,13 @@ module ActiveRecord
|
|
83
93
|
end
|
84
94
|
|
85
95
|
initializer "active_record.migration_error" do |app|
|
86
|
-
if config.active_record.
|
96
|
+
if config.active_record.migration_error == :page_load
|
87
97
|
config.app_middleware.insert_after ::ActionDispatch::Callbacks,
|
88
98
|
ActiveRecord::Migration::CheckPending,
|
89
99
|
file_watcher: app.config.file_watcher
|
90
100
|
end
|
91
101
|
end
|
92
102
|
|
93
|
-
initializer "active_record.database_selector" do
|
94
|
-
if options = config.active_record.delete(:database_selector)
|
95
|
-
resolver = config.active_record.delete(:database_resolver)
|
96
|
-
operations = config.active_record.delete(:database_resolver_context)
|
97
|
-
config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
103
|
initializer "Check for cache versioning support" do
|
102
104
|
config.after_initialize do |app|
|
103
105
|
ActiveSupport.on_load(:active_record) do
|
@@ -124,9 +126,9 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
124
126
|
end
|
125
127
|
|
126
128
|
initializer "active_record.check_schema_cache_dump" do
|
127
|
-
check_schema_cache_dump_version = config.active_record.
|
129
|
+
check_schema_cache_dump_version = config.active_record.check_schema_cache_dump_version
|
128
130
|
|
129
|
-
if config.active_record.
|
131
|
+
if config.active_record.use_schema_cache_dump && !config.active_record.lazily_load_schema_cache
|
130
132
|
config.after_initialize do |app|
|
131
133
|
ActiveSupport.on_load(:active_record) do
|
132
134
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
|
@@ -149,11 +151,12 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
149
151
|
next if current_version.nil?
|
150
152
|
|
151
153
|
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}."
|
154
|
+
warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the schema cache file is #{cache.version}."
|
153
155
|
next
|
154
156
|
end
|
155
157
|
end
|
156
158
|
|
159
|
+
Rails.logger.info("Using schema cache file #{filename}")
|
157
160
|
connection_pool.set_schema_cache(cache)
|
158
161
|
end
|
159
162
|
end
|
@@ -166,10 +169,6 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
166
169
|
if app.config.eager_load
|
167
170
|
begin
|
168
171
|
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
172
|
# If the schema cache was loaded from a dump, we can use it without connecting
|
174
173
|
schema_cache = model.connection_pool.schema_cache
|
175
174
|
|
@@ -201,12 +200,58 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
201
200
|
end
|
202
201
|
end
|
203
202
|
|
203
|
+
SQLITE3_PRODUCTION_WARN = "You are running SQLite in production, this is generally not recommended."\
|
204
|
+
" You can disable this warning by setting \"config.active_record.sqlite3_production_warning=false\"."
|
205
|
+
initializer "active_record.sqlite3_production_warning" do
|
206
|
+
if config.active_record.sqlite3_production_warning && Rails.env.production?
|
207
|
+
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
208
|
+
Rails.logger.warn(SQLITE3_PRODUCTION_WARN)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
204
213
|
initializer "active_record.set_configs" do |app|
|
214
|
+
configs = app.config.active_record
|
215
|
+
|
216
|
+
config.after_initialize do
|
217
|
+
configs.each do |k, v|
|
218
|
+
next if k == :encryption
|
219
|
+
setter = "#{k}="
|
220
|
+
if ActiveRecord.respond_to?(setter)
|
221
|
+
ActiveRecord.send(setter, v)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
205
226
|
ActiveSupport.on_load(:active_record) do
|
206
|
-
|
227
|
+
# Configs used in other initializers
|
228
|
+
configs = configs.except(
|
229
|
+
:migration_error,
|
230
|
+
:database_selector,
|
231
|
+
:database_resolver,
|
232
|
+
:database_resolver_context,
|
233
|
+
:shard_selector,
|
234
|
+
:shard_resolver,
|
235
|
+
:query_log_tags_enabled,
|
236
|
+
:query_log_tags,
|
237
|
+
:cache_query_log_tags,
|
238
|
+
:sqlite3_production_warning,
|
239
|
+
:check_schema_cache_dump_version,
|
240
|
+
:use_schema_cache_dump
|
241
|
+
)
|
207
242
|
|
208
243
|
configs.each do |k, v|
|
209
|
-
|
244
|
+
next if k == :encryption
|
245
|
+
setter = "#{k}="
|
246
|
+
# Some existing initializers might rely on Active Record configuration
|
247
|
+
# being copied from the config object to their actual destination when
|
248
|
+
# `ActiveRecord::Base` is loaded.
|
249
|
+
# So to preserve backward compatibility we copy the config a second time.
|
250
|
+
if ActiveRecord.respond_to?(setter)
|
251
|
+
ActiveRecord.send(setter, v)
|
252
|
+
else
|
253
|
+
send(setter, v)
|
254
|
+
end
|
210
255
|
end
|
211
256
|
end
|
212
257
|
end
|
@@ -215,10 +260,11 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
215
260
|
# and then establishes the connection.
|
216
261
|
initializer "active_record.initialize_database" do
|
217
262
|
ActiveSupport.on_load(:active_record) do
|
218
|
-
if ActiveRecord
|
219
|
-
self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler }
|
263
|
+
if ActiveRecord.legacy_connection_handling
|
264
|
+
self.connection_handlers = { ActiveRecord.writing_role => ActiveRecord::Base.default_connection_handler }
|
220
265
|
end
|
221
266
|
self.configurations = Rails.application.config.database_configuration
|
267
|
+
|
222
268
|
establish_connection
|
223
269
|
end
|
224
270
|
end
|
@@ -244,6 +290,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
244
290
|
|
245
291
|
initializer "active_record.set_executor_hooks" do
|
246
292
|
ActiveRecord::QueryCache.install_executor_hooks
|
293
|
+
ActiveRecord::AsynchronousQueriesTracker.install_executor_hooks
|
247
294
|
end
|
248
295
|
|
249
296
|
initializer "active_record.add_watchable_files" do |app|
|
@@ -279,5 +326,72 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
279
326
|
self.signed_id_verifier_secret ||= -> { Rails.application.key_generator.generate_key("active_record/signed_id") }
|
280
327
|
end
|
281
328
|
end
|
329
|
+
|
330
|
+
initializer "active_record_encryption.configuration" do |app|
|
331
|
+
ActiveRecord::Encryption.configure \
|
332
|
+
primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
|
333
|
+
deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
|
334
|
+
key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
|
335
|
+
**config.active_record.encryption
|
336
|
+
|
337
|
+
ActiveSupport.on_load(:active_record) do
|
338
|
+
# Support extended queries for deterministic attributes and validations
|
339
|
+
if ActiveRecord::Encryption.config.extend_queries
|
340
|
+
ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
|
341
|
+
ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
ActiveSupport.on_load(:active_record_fixture_set) do
|
346
|
+
# Encrypt active record fixtures
|
347
|
+
if ActiveRecord::Encryption.config.encrypt_fixtures
|
348
|
+
ActiveRecord::Fixture.prepend ActiveRecord::Encryption::EncryptedFixtures
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
# Filtered params
|
353
|
+
ActiveSupport.on_load(:action_controller, run_once: true) do
|
354
|
+
if ActiveRecord::Encryption.config.add_to_filter_parameters
|
355
|
+
ActiveRecord::Encryption.install_auto_filtered_parameters_hook(app)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
initializer "active_record.query_log_tags_config" do |app|
|
361
|
+
config.after_initialize do
|
362
|
+
if app.config.active_record.query_log_tags_enabled
|
363
|
+
ActiveRecord.query_transformers << ActiveRecord::QueryLogs
|
364
|
+
ActiveRecord::QueryLogs.taggings.merge!(
|
365
|
+
application: Rails.application.class.name.split("::").first,
|
366
|
+
pid: -> { Process.pid },
|
367
|
+
socket: -> { ActiveRecord::Base.connection_db_config.socket },
|
368
|
+
db_host: -> { ActiveRecord::Base.connection_db_config.host },
|
369
|
+
database: -> { ActiveRecord::Base.connection_db_config.database }
|
370
|
+
)
|
371
|
+
|
372
|
+
if app.config.active_record.query_log_tags.present?
|
373
|
+
ActiveRecord::QueryLogs.tags = app.config.active_record.query_log_tags
|
374
|
+
end
|
375
|
+
|
376
|
+
if app.config.active_record.cache_query_log_tags
|
377
|
+
ActiveRecord::QueryLogs.cache_query_log_tags = true
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
initializer "active_record.unregister_current_scopes_on_unload" do |app|
|
384
|
+
config.after_initialize do
|
385
|
+
unless app.config.cache_classes
|
386
|
+
Rails.autoloaders.main.on_unload do |_cpath, value, _abspath|
|
387
|
+
# Conditions are written this way to be robust against custom
|
388
|
+
# implementations of value#is_a? or value#<.
|
389
|
+
if Class === value && ActiveRecord::Base > value
|
390
|
+
value.current_scope = nil
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
282
396
|
end
|
283
397
|
end
|
@@ -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"
|
@@ -307,7 +332,7 @@ db_namespace = namespace :db do
|
|
307
332
|
|
308
333
|
desc "Retrieves the current schema version number"
|
309
334
|
task version: :load_config do
|
310
|
-
puts "Current version: #{ActiveRecord::Base.connection.
|
335
|
+
puts "Current version: #{ActiveRecord::Base.connection.schema_version}"
|
311
336
|
end
|
312
337
|
|
313
338
|
# desc "Raises an error if there are pending migrations"
|
@@ -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"
|
@@ -447,36 +452,32 @@ db_namespace = namespace :db do
|
|
447
452
|
end
|
448
453
|
|
449
454
|
namespace :schema do
|
450
|
-
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
|
455
|
+
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
|
451
456
|
task dump: :load_config do
|
452
457
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
453
|
-
|
454
|
-
|
458
|
+
if db_config.schema_dump
|
459
|
+
ActiveRecord::Base.establish_connection(db_config)
|
460
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
461
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
|
462
|
+
end
|
455
463
|
end
|
456
464
|
|
457
465
|
db_namespace["schema:dump"].reenable
|
458
466
|
end
|
459
467
|
|
460
|
-
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database"
|
468
|
+
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the database"
|
461
469
|
task load: [:load_config, :check_protected_environments] do
|
462
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord
|
463
|
-
end
|
464
|
-
|
465
|
-
task load_if_ruby: ["db:create", :environment] do
|
466
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
467
|
-
Using `bin/rails db:schema:load_if_ruby` is deprecated and will be removed in Rails 7.0.
|
468
|
-
Configure the format using `config.active_record.schema_format = :ruby` to use `schema.rb` and run `bin/rails db:schema:load` instead.
|
469
|
-
MSG
|
470
|
-
db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
|
470
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
|
471
471
|
end
|
472
472
|
|
473
473
|
namespace :dump do
|
474
474
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
475
|
-
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for #{name} database"
|
475
|
+
desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) for #{name} database"
|
476
476
|
task name => :load_config do
|
477
477
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
|
478
478
|
ActiveRecord::Base.establish_connection(db_config)
|
479
|
-
ActiveRecord
|
479
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
480
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
|
480
481
|
db_namespace["schema:dump:#{name}"].reenable
|
481
482
|
end
|
482
483
|
end
|
@@ -484,10 +485,14 @@ db_namespace = namespace :db do
|
|
484
485
|
|
485
486
|
namespace :load do
|
486
487
|
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
487
|
-
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"
|
488
|
-
task name => :load_config do
|
488
|
+
desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the #{name} database"
|
489
|
+
task name => [:load_config, :check_protected_environments] do
|
490
|
+
original_db_config = ActiveRecord::Base.connection_db_config
|
489
491
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
|
490
|
-
|
492
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
493
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
494
|
+
ensure
|
495
|
+
ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
|
491
496
|
end
|
492
497
|
end
|
493
498
|
end
|
@@ -523,60 +528,17 @@ db_namespace = namespace :db do
|
|
523
528
|
end
|
524
529
|
end
|
525
530
|
|
526
|
-
namespace :
|
527
|
-
desc "
|
528
|
-
task
|
529
|
-
|
530
|
-
|
531
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump` instead.
|
532
|
-
MSG
|
533
|
-
|
534
|
-
db_namespace["schema:dump"].invoke
|
535
|
-
db_namespace["structure:dump"].reenable
|
536
|
-
end
|
531
|
+
namespace :encryption do
|
532
|
+
desc "Generate a set of keys for configuring Active Record encryption in a given environment"
|
533
|
+
task :init do
|
534
|
+
puts <<~MSG
|
535
|
+
Add this entry to the credentials of the target environment:#{' '}
|
537
536
|
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
|
537
|
+
active_record_encryption:
|
538
|
+
primary_key: #{SecureRandom.alphanumeric(32)}
|
539
|
+
deterministic_key: #{SecureRandom.alphanumeric(32)}
|
540
|
+
key_derivation_salt: #{SecureRandom.alphanumeric(32)}
|
543
541
|
MSG
|
544
|
-
db_namespace["schema:load"].invoke
|
545
|
-
end
|
546
|
-
|
547
|
-
task load_if_sql: ["db:create", :environment] do
|
548
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
549
|
-
Using `bin/rails db:structure:load_if_sql` is deprecated and will be removed in Rails 7.0.
|
550
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
|
551
|
-
MSG
|
552
|
-
db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :sql
|
553
|
-
end
|
554
|
-
|
555
|
-
namespace :dump do
|
556
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
557
|
-
desc "Dumps the #{name} database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
|
558
|
-
task name => :load_config do
|
559
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
560
|
-
Using `bin/rails db:structure:dump:#{name}` is deprecated and will be removed in Rails 7.0.
|
561
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump:#{name}` instead.
|
562
|
-
MSG
|
563
|
-
db_namespace["schema:dump:#{name}"].invoke
|
564
|
-
db_namespace["structure:dump:#{name}"].reenable
|
565
|
-
end
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
namespace :load do
|
570
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
|
571
|
-
desc "Recreates the #{name} database from the structure.sql file"
|
572
|
-
task name => :load_config do
|
573
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
574
|
-
Using `bin/rails db:structure:load:#{name}` is deprecated and will be removed in Rails 7.0.
|
575
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load:#{name}` instead.
|
576
|
-
MSG
|
577
|
-
db_namespace["schema:load:#{name}"].invoke
|
578
|
-
end
|
579
|
-
end
|
580
542
|
end
|
581
543
|
end
|
582
544
|
|
@@ -586,13 +548,13 @@ db_namespace = namespace :db do
|
|
586
548
|
db_namespace["test:load_schema"].invoke
|
587
549
|
end
|
588
550
|
|
589
|
-
# desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `config.active_record.schema_format`)"
|
551
|
+
# desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
|
590
552
|
task load_schema: %w(db:test:purge) do
|
591
553
|
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
592
554
|
ActiveRecord::Schema.verbose = false
|
593
555
|
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
594
|
-
|
595
|
-
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config,
|
556
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
557
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
596
558
|
end
|
597
559
|
ensure
|
598
560
|
if should_reconnect
|
@@ -600,15 +562,6 @@ db_namespace = namespace :db do
|
|
600
562
|
end
|
601
563
|
end
|
602
564
|
|
603
|
-
# desc "Recreate the test database from an existent structure.sql file"
|
604
|
-
task load_structure: %w(db:test:purge) do
|
605
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
606
|
-
Using `bin/rails db:test:load_structure` is deprecated and will be removed in Rails 7.0.
|
607
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_schema` instead.
|
608
|
-
MSG
|
609
|
-
db_namespace["test:load_schema"].invoke
|
610
|
-
end
|
611
|
-
|
612
565
|
# desc "Empty the test database"
|
613
566
|
task purge: %w(load_config check_protected_environments) do
|
614
567
|
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
@@ -636,9 +589,9 @@ db_namespace = namespace :db do
|
|
636
589
|
task name => "db:test:purge:#{name}" do
|
637
590
|
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
638
591
|
ActiveRecord::Schema.verbose = false
|
639
|
-
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(name)
|
640
592
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
|
641
|
-
|
593
|
+
schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
|
594
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
|
642
595
|
ensure
|
643
596
|
if should_reconnect
|
644
597
|
ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
|
@@ -646,17 +599,6 @@ db_namespace = namespace :db do
|
|
646
599
|
end
|
647
600
|
end
|
648
601
|
|
649
|
-
# desc "Recreate the #{name} test database from an existent structure.sql file"
|
650
|
-
namespace :load_structure do
|
651
|
-
task name => "db:test:purge:#{name}" do
|
652
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
653
|
-
Using `bin/rails db:test:load_structure:#{name}` is deprecated and will be removed in Rails 7.0.
|
654
|
-
Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_structure:#{name}` instead.
|
655
|
-
MSG
|
656
|
-
db_namespace["test:load_schema:#{name}"].invoke
|
657
|
-
end
|
658
|
-
end
|
659
|
-
|
660
602
|
# desc "Empty the #{name} test database"
|
661
603
|
namespace :purge do
|
662
604
|
task name => %w(load_config check_protected_environments) do
|
@@ -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
|