activerecord 7.1.4.1 → 7.2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +643 -2274
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +15 -8
- data/lib/active_record/associations/belongs_to_association.rb +14 -7
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/belongs_to.rb +1 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/collection_association.rb +7 -1
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +4 -4
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +2 -1
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +6 -0
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +59 -292
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/primary_key.rb +23 -55
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods.rb +54 -63
- data/lib/active_record/attributes.rb +61 -47
- data/lib/active_record/autosave_association.rb +12 -29
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +270 -65
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +34 -17
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +189 -74
- data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -62
- data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -44
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +40 -10
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +6 -0
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +16 -15
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +5 -23
- data/lib/active_record/connection_adapters/pool_config.rb +7 -6
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +17 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +29 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -75
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +15 -15
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -48
- data/lib/active_record/connection_adapters.rb +121 -0
- data/lib/active_record/connection_handling.rb +56 -41
- data/lib/active_record/core.rb +86 -38
- data/lib/active_record/counter_cache.rb +18 -9
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +19 -4
- data/lib/active_record/database_configurations/hash_config.rb +38 -34
- data/lib/active_record/database_configurations/url_config.rb +20 -1
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +24 -0
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/encryptable_record.rb +3 -3
- data/lib/active_record/encryption/encrypted_attribute_type.rb +24 -4
- data/lib/active_record/encryption/encryptor.rb +18 -3
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +19 -2
- data/lib/active_record/errors.rb +46 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -31
- data/lib/active_record/future_result.rb +8 -4
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +18 -15
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +7 -6
- data/lib/active_record/log_subscriber.rb +0 -21
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +2 -3
- data/lib/active_record/migration/compatibility.rb +5 -3
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +85 -76
- data/lib/active_record/model_schema.rb +32 -68
- data/lib/active_record/nested_attributes.rb +24 -5
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +30 -352
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +15 -0
- data/lib/active_record/querying.rb +21 -9
- data/lib/active_record/railtie.rb +42 -57
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +40 -43
- data/lib/active_record/reflection.rb +98 -36
- data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
- data/lib/active_record/relation/batches.rb +14 -8
- data/lib/active_record/relation/calculations.rb +96 -63
- data/lib/active_record/relation/delegation.rb +8 -11
- data/lib/active_record/relation/finder_methods.rb +16 -2
- data/lib/active_record/relation/merger.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -3
- data/lib/active_record/relation/predicate_builder.rb +3 -3
- data/lib/active_record/relation/query_methods.rb +224 -58
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -18
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +496 -72
- data/lib/active_record/result.rb +31 -44
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +24 -19
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +19 -9
- data/lib/active_record/schema_migration.rb +30 -14
- data/lib/active_record/scoping/named.rb +1 -0
- data/lib/active_record/signed_id.rb +20 -1
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/table_metadata.rb +1 -10
- data/lib/active_record/tasks/database_tasks.rb +81 -42
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
- data/lib/active_record/test_fixtures.rb +86 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +2 -2
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +70 -14
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +15 -10
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +148 -39
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/nodes/binary.rb +0 -6
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +4 -3
- data/lib/arel/nodes/sql_literal.rb +7 -0
- data/lib/arel/nodes.rb +2 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +29 -16
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +18 -12
@@ -21,7 +21,7 @@ module ActiveRecord
|
|
21
21
|
# For example the following migration is not reversible.
|
22
22
|
# Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
|
23
23
|
#
|
24
|
-
# class IrreversibleMigrationExample < ActiveRecord::Migration[7.
|
24
|
+
# class IrreversibleMigrationExample < ActiveRecord::Migration[7.2]
|
25
25
|
# def change
|
26
26
|
# create_table :distributors do |t|
|
27
27
|
# t.string :zipcode
|
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
39
39
|
#
|
40
40
|
# 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
|
41
41
|
#
|
42
|
-
# class ReversibleMigrationExample < ActiveRecord::Migration[7.
|
42
|
+
# class ReversibleMigrationExample < ActiveRecord::Migration[7.2]
|
43
43
|
# def up
|
44
44
|
# create_table :distributors do |t|
|
45
45
|
# t.string :zipcode
|
@@ -64,7 +64,7 @@ module ActiveRecord
|
|
64
64
|
#
|
65
65
|
# 2. Use the #reversible method in <tt>#change</tt> method:
|
66
66
|
#
|
67
|
-
# class ReversibleMigrationExample < ActiveRecord::Migration[7.
|
67
|
+
# class ReversibleMigrationExample < ActiveRecord::Migration[7.2]
|
68
68
|
# def change
|
69
69
|
# create_table :distributors do |t|
|
70
70
|
# t.string :zipcode
|
@@ -131,6 +131,22 @@ module ActiveRecord
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
class InvalidMigrationTimestampError < MigrationError # :nodoc:
|
135
|
+
def initialize(version = nil, name = nil)
|
136
|
+
if version && name
|
137
|
+
super(<<~MSG)
|
138
|
+
Invalid timestamp #{version} for migration file: #{name}.
|
139
|
+
Timestamp must be in form YYYYMMDDHHMMSS, and less than #{(Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S")}.
|
140
|
+
MSG
|
141
|
+
else
|
142
|
+
super(<<~MSG)
|
143
|
+
Invalid timestamp for migration.
|
144
|
+
Timestamp must be in form YYYYMMDDHHMMSS, and less than #{(Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S")}.
|
145
|
+
MSG
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
134
150
|
class PendingMigrationError < MigrationError # :nodoc:
|
135
151
|
include ActiveSupport::ActionableError
|
136
152
|
|
@@ -145,8 +161,7 @@ module ActiveRecord
|
|
145
161
|
|
146
162
|
def initialize(message = nil, pending_migrations: nil)
|
147
163
|
if pending_migrations.nil?
|
148
|
-
|
149
|
-
pending_migrations = connection.migration_context.open.pending_migrations
|
164
|
+
pending_migrations = connection_pool.migration_context.open.pending_migrations
|
150
165
|
end
|
151
166
|
|
152
167
|
super(message || detailed_migration_message(pending_migrations))
|
@@ -167,8 +182,8 @@ module ActiveRecord
|
|
167
182
|
message
|
168
183
|
end
|
169
184
|
|
170
|
-
def
|
171
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
185
|
+
def connection_pool
|
186
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
172
187
|
end
|
173
188
|
end
|
174
189
|
|
@@ -235,7 +250,7 @@ module ActiveRecord
|
|
235
250
|
#
|
236
251
|
# Example of a simple migration:
|
237
252
|
#
|
238
|
-
# class AddSsl < ActiveRecord::Migration[7.
|
253
|
+
# class AddSsl < ActiveRecord::Migration[7.2]
|
239
254
|
# def up
|
240
255
|
# add_column :accounts, :ssl_enabled, :boolean, default: true
|
241
256
|
# end
|
@@ -255,7 +270,7 @@ module ActiveRecord
|
|
255
270
|
#
|
256
271
|
# Example of a more complex migration that also needs to initialize data:
|
257
272
|
#
|
258
|
-
# class AddSystemSettings < ActiveRecord::Migration[7.
|
273
|
+
# class AddSystemSettings < ActiveRecord::Migration[7.2]
|
259
274
|
# def up
|
260
275
|
# create_table :system_settings do |t|
|
261
276
|
# t.string :name
|
@@ -384,7 +399,7 @@ module ActiveRecord
|
|
384
399
|
# $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
|
385
400
|
#
|
386
401
|
# This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
|
387
|
-
# class AddFieldnameToTablename < ActiveRecord::Migration[7.
|
402
|
+
# class AddFieldnameToTablename < ActiveRecord::Migration[7.2]
|
388
403
|
# def change
|
389
404
|
# add_column :tablenames, :fieldname, :string
|
390
405
|
# end
|
@@ -410,7 +425,7 @@ module ActiveRecord
|
|
410
425
|
#
|
411
426
|
# Not all migrations change the schema. Some just fix the data:
|
412
427
|
#
|
413
|
-
# class RemoveEmptyTags < ActiveRecord::Migration[7.
|
428
|
+
# class RemoveEmptyTags < ActiveRecord::Migration[7.2]
|
414
429
|
# def up
|
415
430
|
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
|
416
431
|
# end
|
@@ -423,7 +438,7 @@ module ActiveRecord
|
|
423
438
|
#
|
424
439
|
# Others remove columns when they migrate up instead of down:
|
425
440
|
#
|
426
|
-
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.
|
441
|
+
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.2]
|
427
442
|
# def up
|
428
443
|
# remove_column :items, :incomplete_items_count
|
429
444
|
# remove_column :items, :completed_items_count
|
@@ -437,7 +452,7 @@ module ActiveRecord
|
|
437
452
|
#
|
438
453
|
# And sometimes you need to do something in SQL not abstracted directly by migrations:
|
439
454
|
#
|
440
|
-
# class MakeJoinUnique < ActiveRecord::Migration[7.
|
455
|
+
# class MakeJoinUnique < ActiveRecord::Migration[7.2]
|
441
456
|
# def up
|
442
457
|
# execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
|
443
458
|
# end
|
@@ -454,7 +469,7 @@ module ActiveRecord
|
|
454
469
|
# <tt>Base#reset_column_information</tt> in order to ensure that the model has the
|
455
470
|
# latest column data from after the new column was added. Example:
|
456
471
|
#
|
457
|
-
# class AddPeopleSalary < ActiveRecord::Migration[7.
|
472
|
+
# class AddPeopleSalary < ActiveRecord::Migration[7.2]
|
458
473
|
# def up
|
459
474
|
# add_column :people, :salary, :integer
|
460
475
|
# Person.reset_column_information
|
@@ -470,7 +485,7 @@ module ActiveRecord
|
|
470
485
|
# them to the console as they happen, along with benchmarks describing how
|
471
486
|
# long each step took.
|
472
487
|
#
|
473
|
-
# You can quiet them down by setting ActiveRecord::Migration.verbose = false
|
488
|
+
# You can quiet them down by setting <tt>ActiveRecord::Migration.verbose = false</tt>.
|
474
489
|
#
|
475
490
|
# You can also insert your own messages and benchmarks by using the +say_with_time+
|
476
491
|
# method:
|
@@ -494,7 +509,11 @@ module ActiveRecord
|
|
494
509
|
#
|
495
510
|
# 20080717013526_your_migration_name.rb
|
496
511
|
#
|
497
|
-
# The prefix is a generation timestamp (in UTC).
|
512
|
+
# The prefix is a generation timestamp (in UTC). Timestamps should not be
|
513
|
+
# modified manually. To validate that migration timestamps adhere to the
|
514
|
+
# format Active Record expects, you can use the following configuration option:
|
515
|
+
#
|
516
|
+
# config.active_record.validate_migration_timestamps = true
|
498
517
|
#
|
499
518
|
# If you'd prefer to use numeric prefixes, you can turn timestamped migrations
|
500
519
|
# off by setting:
|
@@ -512,7 +531,7 @@ module ActiveRecord
|
|
512
531
|
# To define a reversible migration, define the +change+ method in your
|
513
532
|
# migration like this:
|
514
533
|
#
|
515
|
-
# class TenderloveMigration < ActiveRecord::Migration[7.
|
534
|
+
# class TenderloveMigration < ActiveRecord::Migration[7.2]
|
516
535
|
# def change
|
517
536
|
# create_table(:horses) do |t|
|
518
537
|
# t.column :content, :text
|
@@ -542,7 +561,7 @@ module ActiveRecord
|
|
542
561
|
# can't execute inside a transaction though, and for these situations
|
543
562
|
# you can turn the automatic transactions off.
|
544
563
|
#
|
545
|
-
# class ChangeEnum < ActiveRecord::Migration[7.
|
564
|
+
# class ChangeEnum < ActiveRecord::Migration[7.2]
|
546
565
|
# disable_ddl_transaction!
|
547
566
|
#
|
548
567
|
# def up
|
@@ -676,30 +695,13 @@ module ActiveRecord
|
|
676
695
|
delegate || superclass.nearest_delegate
|
677
696
|
end
|
678
697
|
|
679
|
-
# Raises ActiveRecord::PendingMigrationError error if any migrations are pending.
|
680
|
-
#
|
681
|
-
# This is deprecated in favor of +check_all_pending!+
|
682
|
-
def check_pending!(connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection)
|
683
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
684
|
-
The `check_pending!` method is deprecated in favor of `check_all_pending!`. The
|
685
|
-
new implementation will loop through all available database configurations and find
|
686
|
-
pending migrations. The prior implementation did not permit this.
|
687
|
-
MSG
|
688
|
-
|
689
|
-
pending_migrations = connection.migration_context.open.pending_migrations
|
690
|
-
|
691
|
-
if pending_migrations.any?
|
692
|
-
raise ActiveRecord::PendingMigrationError.new(pending_migrations: pending_migrations)
|
693
|
-
end
|
694
|
-
end
|
695
|
-
|
696
698
|
# Raises ActiveRecord::PendingMigrationError error if any migrations are pending
|
697
699
|
# for all database configurations in an environment.
|
698
700
|
def check_all_pending!
|
699
701
|
pending_migrations = []
|
700
702
|
|
701
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
702
|
-
if pending =
|
703
|
+
ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: env) do |pool|
|
704
|
+
if pending = pool.migration_context.open.pending_migrations
|
703
705
|
pending_migrations << pending
|
704
706
|
end
|
705
707
|
end
|
@@ -731,10 +733,9 @@ module ActiveRecord
|
|
731
733
|
end
|
732
734
|
end
|
733
735
|
|
734
|
-
def method_missing(name,
|
735
|
-
nearest_delegate.send(name,
|
736
|
+
def method_missing(name, ...) # :nodoc:
|
737
|
+
nearest_delegate.send(name, ...)
|
736
738
|
end
|
737
|
-
ruby2_keywords(:method_missing)
|
738
739
|
|
739
740
|
def migrate(direction)
|
740
741
|
new.migrate direction
|
@@ -771,8 +772,8 @@ module ActiveRecord
|
|
771
772
|
pending_migrations = []
|
772
773
|
|
773
774
|
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
|
774
|
-
ActiveRecord::PendingMigrationConnection.
|
775
|
-
if pending =
|
775
|
+
ActiveRecord::PendingMigrationConnection.with_temporary_pool(db_config) do |pool|
|
776
|
+
if pending = pool.migration_context.open.pending_migrations
|
776
777
|
pending_migrations << pending
|
777
778
|
end
|
778
779
|
end
|
@@ -790,6 +791,12 @@ module ActiveRecord
|
|
790
791
|
self.class.disable_ddl_transaction
|
791
792
|
end
|
792
793
|
|
794
|
+
##
|
795
|
+
# :singleton-method: verbose
|
796
|
+
#
|
797
|
+
# Specifies if migrations will write the actions they are taking to the console as they
|
798
|
+
# happen, along with benchmarks describing how long each step took. Defaults to
|
799
|
+
# true.
|
793
800
|
cattr_accessor :verbose
|
794
801
|
attr_accessor :name, :version
|
795
802
|
|
@@ -797,6 +804,7 @@ module ActiveRecord
|
|
797
804
|
@name = name
|
798
805
|
@version = version
|
799
806
|
@connection = nil
|
807
|
+
@pool = nil
|
800
808
|
end
|
801
809
|
|
802
810
|
def execution_strategy
|
@@ -814,7 +822,7 @@ module ActiveRecord
|
|
814
822
|
# and create the table 'apples' on the way up, and the reverse
|
815
823
|
# on the way down.
|
816
824
|
#
|
817
|
-
# class FixTLMigration < ActiveRecord::Migration[7.
|
825
|
+
# class FixTLMigration < ActiveRecord::Migration[7.2]
|
818
826
|
# def change
|
819
827
|
# revert do
|
820
828
|
# create_table(:horses) do |t|
|
@@ -833,7 +841,7 @@ module ActiveRecord
|
|
833
841
|
#
|
834
842
|
# require_relative "20121212123456_tenderlove_migration"
|
835
843
|
#
|
836
|
-
# class FixupTLMigration < ActiveRecord::Migration[7.
|
844
|
+
# class FixupTLMigration < ActiveRecord::Migration[7.2]
|
837
845
|
# def change
|
838
846
|
# revert TenderloveMigration
|
839
847
|
#
|
@@ -884,7 +892,7 @@ module ActiveRecord
|
|
884
892
|
# when the three columns 'first_name', 'last_name' and 'full_name' exist,
|
885
893
|
# even when migrating down:
|
886
894
|
#
|
887
|
-
# class SplitNameMigration < ActiveRecord::Migration[7.
|
895
|
+
# class SplitNameMigration < ActiveRecord::Migration[7.2]
|
888
896
|
# def change
|
889
897
|
# add_column :users, :first_name, :string
|
890
898
|
# add_column :users, :last_name, :string
|
@@ -912,7 +920,7 @@ module ActiveRecord
|
|
912
920
|
# In the following example, the new column +published+ will be given
|
913
921
|
# the value +true+ for all existing records.
|
914
922
|
#
|
915
|
-
# class AddPublishedToPosts < ActiveRecord::Migration[7.
|
923
|
+
# class AddPublishedToPosts < ActiveRecord::Migration[7.2]
|
916
924
|
# def change
|
917
925
|
# add_column :posts, :published, :boolean, default: false
|
918
926
|
# up_only do
|
@@ -1032,6 +1040,10 @@ module ActiveRecord
|
|
1032
1040
|
@connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1033
1041
|
end
|
1034
1042
|
|
1043
|
+
def connection_pool
|
1044
|
+
@pool || ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
1045
|
+
end
|
1046
|
+
|
1035
1047
|
def method_missing(method, *arguments, &block)
|
1036
1048
|
say_with_time "#{method}(#{format_arguments(arguments)})" do
|
1037
1049
|
unless connection.respond_to? :revert
|
@@ -1203,31 +1215,9 @@ module ActiveRecord
|
|
1203
1215
|
attr_reader :migrations_paths, :schema_migration, :internal_metadata
|
1204
1216
|
|
1205
1217
|
def initialize(migrations_paths, schema_migration = nil, internal_metadata = nil)
|
1206
|
-
if schema_migration == SchemaMigration
|
1207
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
1208
|
-
SchemaMigration no longer inherits from ActiveRecord::Base. If you want
|
1209
|
-
to use the default connection, remove this argument. If you want to use a
|
1210
|
-
specific connection, instantiate MigrationContext with the connection's schema
|
1211
|
-
migration, for example `MigrationContext.new(path, Dog.connection.schema_migration)`.
|
1212
|
-
MSG
|
1213
|
-
|
1214
|
-
schema_migration = nil
|
1215
|
-
end
|
1216
|
-
|
1217
|
-
if internal_metadata == InternalMetadata
|
1218
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
1219
|
-
SchemaMigration no longer inherits from ActiveRecord::Base. If you want
|
1220
|
-
to use the default connection, remove this argument. If you want to use a
|
1221
|
-
specific connection, instantiate MigrationContext with the connection's internal
|
1222
|
-
metadata, for example `MigrationContext.new(path, nil, Dog.connection.internal_metadata)`.
|
1223
|
-
MSG
|
1224
|
-
|
1225
|
-
internal_metadata = nil
|
1226
|
-
end
|
1227
|
-
|
1228
1218
|
@migrations_paths = migrations_paths
|
1229
|
-
@schema_migration = schema_migration || SchemaMigration.new(
|
1230
|
-
@internal_metadata = internal_metadata || InternalMetadata.new(
|
1219
|
+
@schema_migration = schema_migration || SchemaMigration.new(connection_pool)
|
1220
|
+
@internal_metadata = internal_metadata || InternalMetadata.new(connection_pool)
|
1231
1221
|
end
|
1232
1222
|
|
1233
1223
|
# Runs the migrations in the +migrations_path+.
|
@@ -1317,6 +1307,9 @@ module ActiveRecord
|
|
1317
1307
|
migrations = migration_files.map do |file|
|
1318
1308
|
version, name, scope = parse_migration_filename(file)
|
1319
1309
|
raise IllegalMigrationNameError.new(file) unless version
|
1310
|
+
if validate_timestamp? && !valid_migration_timestamp?(version)
|
1311
|
+
raise InvalidMigrationTimestampError.new(version, name)
|
1312
|
+
end
|
1320
1313
|
version = version.to_i
|
1321
1314
|
name = name.camelize
|
1322
1315
|
|
@@ -1332,6 +1325,9 @@ module ActiveRecord
|
|
1332
1325
|
file_list = migration_files.filter_map do |file|
|
1333
1326
|
version, name, scope = parse_migration_filename(file)
|
1334
1327
|
raise IllegalMigrationNameError.new(file) unless version
|
1328
|
+
if validate_timestamp? && !valid_migration_timestamp?(version)
|
1329
|
+
raise InvalidMigrationTimestampError.new(version, name)
|
1330
|
+
end
|
1335
1331
|
version = schema_migration.normalize_migration_number(version)
|
1336
1332
|
status = db_list.delete(version) ? "up" : "down"
|
1337
1333
|
[status, version, (name + scope).humanize]
|
@@ -1353,11 +1349,12 @@ module ActiveRecord
|
|
1353
1349
|
end
|
1354
1350
|
|
1355
1351
|
def last_stored_environment # :nodoc:
|
1356
|
-
|
1352
|
+
internal_metadata = connection_pool.internal_metadata
|
1353
|
+
return nil unless internal_metadata.enabled?
|
1357
1354
|
return nil if current_version == 0
|
1358
|
-
raise NoEnvironmentInSchemaError unless
|
1355
|
+
raise NoEnvironmentInSchemaError unless internal_metadata.table_exists?
|
1359
1356
|
|
1360
|
-
environment =
|
1357
|
+
environment = internal_metadata[:environment]
|
1361
1358
|
raise NoEnvironmentInSchemaError unless environment
|
1362
1359
|
environment
|
1363
1360
|
end
|
@@ -1367,6 +1364,10 @@ module ActiveRecord
|
|
1367
1364
|
ActiveRecord::Tasks::DatabaseTasks.migration_connection
|
1368
1365
|
end
|
1369
1366
|
|
1367
|
+
def connection_pool
|
1368
|
+
ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
1369
|
+
end
|
1370
|
+
|
1370
1371
|
def migration_files
|
1371
1372
|
paths = Array(migrations_paths)
|
1372
1373
|
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
|
@@ -1376,6 +1377,14 @@ module ActiveRecord
|
|
1376
1377
|
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
|
1377
1378
|
end
|
1378
1379
|
|
1380
|
+
def validate_timestamp?
|
1381
|
+
ActiveRecord.timestamped_migrations && ActiveRecord.validate_migration_timestamps
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
def valid_migration_timestamp?(version)
|
1385
|
+
version.to_i < (Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S").to_i
|
1386
|
+
end
|
1387
|
+
|
1379
1388
|
def move(direction, steps)
|
1380
1389
|
migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
|
1381
1390
|
|
@@ -1402,9 +1411,9 @@ module ActiveRecord
|
|
1402
1411
|
|
1403
1412
|
# For cases where a table doesn't exist like loading from schema cache
|
1404
1413
|
def current_version
|
1405
|
-
|
1406
|
-
schema_migration = SchemaMigration.new(
|
1407
|
-
internal_metadata = InternalMetadata.new(
|
1414
|
+
connection_pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
1415
|
+
schema_migration = SchemaMigration.new(connection_pool)
|
1416
|
+
internal_metadata = InternalMetadata.new(connection_pool)
|
1408
1417
|
|
1409
1418
|
MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
|
1410
1419
|
end
|
@@ -146,6 +146,11 @@ module ActiveRecord
|
|
146
146
|
# your own model for something else, you can set +inheritance_column+:
|
147
147
|
#
|
148
148
|
# self.inheritance_column = 'zoink'
|
149
|
+
#
|
150
|
+
# If you wish to disable single-table inheritance altogether you can set
|
151
|
+
# +inheritance_column+ to +nil+
|
152
|
+
#
|
153
|
+
# self.inheritance_column = nil
|
149
154
|
|
150
155
|
##
|
151
156
|
# :singleton-method: inheritance_column=
|
@@ -273,13 +278,13 @@ module ActiveRecord
|
|
273
278
|
@table_name = value
|
274
279
|
@quoted_table_name = nil
|
275
280
|
@arel_table = nil
|
276
|
-
@sequence_name = nil unless
|
281
|
+
@sequence_name = nil unless @explicit_sequence_name
|
277
282
|
@predicate_builder = nil
|
278
283
|
end
|
279
284
|
|
280
285
|
# Returns a quoted version of the table name, used to construct SQL statements.
|
281
286
|
def quoted_table_name
|
282
|
-
@quoted_table_name ||=
|
287
|
+
@quoted_table_name ||= adapter_class.quote_table_name(table_name)
|
283
288
|
end
|
284
289
|
|
285
290
|
# Computes the table name, (re)sets it internally, and returns it.
|
@@ -374,7 +379,7 @@ module ActiveRecord
|
|
374
379
|
|
375
380
|
def reset_sequence_name # :nodoc:
|
376
381
|
@explicit_sequence_name = false
|
377
|
-
@sequence_name =
|
382
|
+
@sequence_name = with_connection { |c| c.default_sequence_name(table_name, primary_key) }
|
378
383
|
end
|
379
384
|
|
380
385
|
# Sets the name of the sequence to use when generating ids to the given
|
@@ -399,39 +404,37 @@ module ActiveRecord
|
|
399
404
|
# Determines if the primary key values should be selected from their
|
400
405
|
# corresponding sequence before the insert statement.
|
401
406
|
def prefetch_primary_key?
|
402
|
-
|
407
|
+
with_connection { |c| c.prefetch_primary_key?(table_name) }
|
403
408
|
end
|
404
409
|
|
405
410
|
# Returns the next value that will be used as the primary key on
|
406
411
|
# an insert statement.
|
407
412
|
def next_sequence_value
|
408
|
-
|
413
|
+
with_connection { |c| c.next_sequence_value(sequence_name) }
|
409
414
|
end
|
410
415
|
|
411
416
|
# Indicates whether the table associated with this class exists
|
412
417
|
def table_exists?
|
413
|
-
|
418
|
+
schema_cache.data_source_exists?(table_name)
|
414
419
|
end
|
415
420
|
|
416
421
|
def attributes_builder # :nodoc:
|
417
|
-
|
422
|
+
@attributes_builder ||= begin
|
418
423
|
defaults = _default_attributes.except(*(column_names - [primary_key]))
|
419
|
-
|
424
|
+
ActiveModel::AttributeSet::Builder.new(attribute_types, defaults)
|
420
425
|
end
|
421
|
-
@attributes_builder
|
422
426
|
end
|
423
427
|
|
424
428
|
def columns_hash # :nodoc:
|
425
|
-
load_schema
|
429
|
+
load_schema unless @columns_hash
|
426
430
|
@columns_hash
|
427
431
|
end
|
428
432
|
|
429
433
|
def columns
|
430
|
-
load_schema
|
431
434
|
@columns ||= columns_hash.values.freeze
|
432
435
|
end
|
433
436
|
|
434
|
-
def _returning_columns_for_insert # :nodoc:
|
437
|
+
def _returning_columns_for_insert(connection) # :nodoc:
|
435
438
|
@_returning_columns_for_insert ||= begin
|
436
439
|
auto_populated_columns = columns.filter_map do |c|
|
437
440
|
c.name if connection.return_value_after_insert?(c)
|
@@ -441,37 +444,10 @@ module ActiveRecord
|
|
441
444
|
end
|
442
445
|
end
|
443
446
|
|
444
|
-
def attribute_types # :nodoc:
|
445
|
-
load_schema
|
446
|
-
@attribute_types ||= Hash.new(Type.default_value)
|
447
|
-
end
|
448
|
-
|
449
447
|
def yaml_encoder # :nodoc:
|
450
448
|
@yaml_encoder ||= ActiveModel::AttributeSet::YAMLEncoder.new(attribute_types)
|
451
449
|
end
|
452
450
|
|
453
|
-
# Returns the type of the attribute with the given name, after applying
|
454
|
-
# all modifiers. This method is the only valid source of information for
|
455
|
-
# anything related to the types of a model's attributes. This method will
|
456
|
-
# access the database and load the model's schema if it is required.
|
457
|
-
#
|
458
|
-
# The return value of this method will implement the interface described
|
459
|
-
# by ActiveModel::Type::Value (though the object itself may not subclass
|
460
|
-
# it).
|
461
|
-
#
|
462
|
-
# +attr_name+ The name of the attribute to retrieve the type for. Must be
|
463
|
-
# a string or a symbol.
|
464
|
-
def type_for_attribute(attr_name, &block)
|
465
|
-
attr_name = attr_name.to_s
|
466
|
-
attr_name = attribute_aliases[attr_name] || attr_name
|
467
|
-
|
468
|
-
if block
|
469
|
-
attribute_types.fetch(attr_name, &block)
|
470
|
-
else
|
471
|
-
attribute_types[attr_name]
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
451
|
# Returns the column object for the named attribute.
|
476
452
|
# Returns an ActiveRecord::ConnectionAdapters::NullColumn if the
|
477
453
|
# named attribute does not exist.
|
@@ -499,11 +475,6 @@ module ActiveRecord
|
|
499
475
|
@column_defaults ||= _default_attributes.deep_dup.to_hash.freeze
|
500
476
|
end
|
501
477
|
|
502
|
-
def _default_attributes # :nodoc:
|
503
|
-
load_schema
|
504
|
-
@default_attributes ||= ActiveModel::AttributeSet.new({})
|
505
|
-
end
|
506
|
-
|
507
478
|
# Returns an array of column names as strings.
|
508
479
|
def column_names
|
509
480
|
@column_names ||= columns.map(&:name).freeze
|
@@ -531,7 +502,7 @@ module ActiveRecord
|
|
531
502
|
# when just after creating a table you want to populate it with some default
|
532
503
|
# values, e.g.:
|
533
504
|
#
|
534
|
-
# class CreateJobLevels < ActiveRecord::Migration[7.
|
505
|
+
# class CreateJobLevels < ActiveRecord::Migration[7.2]
|
535
506
|
# def up
|
536
507
|
# create_table :job_levels do |t|
|
537
508
|
# t.integer :id
|
@@ -551,18 +522,20 @@ module ActiveRecord
|
|
551
522
|
# end
|
552
523
|
# end
|
553
524
|
def reset_column_information
|
554
|
-
|
525
|
+
connection_pool.active_connection&.clear_cache!
|
555
526
|
([self] + descendants).each(&:undefine_attribute_methods)
|
556
|
-
|
527
|
+
schema_cache.clear_data_source_cache!(table_name)
|
557
528
|
|
558
529
|
reload_schema_from_cache
|
559
530
|
initialize_find_by_cache
|
560
531
|
end
|
561
532
|
|
562
|
-
|
533
|
+
# Load the model's schema information either from the schema cache
|
534
|
+
# or directly from the database.
|
535
|
+
def load_schema
|
563
536
|
return if schema_loaded?
|
564
537
|
@load_schema_monitor.synchronize do
|
565
|
-
return if
|
538
|
+
return if schema_loaded?
|
566
539
|
|
567
540
|
load_schema!
|
568
541
|
|
@@ -583,9 +556,7 @@ module ActiveRecord
|
|
583
556
|
@arel_table = nil
|
584
557
|
@column_names = nil
|
585
558
|
@symbol_column_to_string_name_hash = nil
|
586
|
-
@attribute_types = nil
|
587
559
|
@content_columns = nil
|
588
|
-
@default_attributes = nil
|
589
560
|
@column_defaults = nil
|
590
561
|
@attributes_builder = nil
|
591
562
|
@columns = nil
|
@@ -611,7 +582,7 @@ module ActiveRecord
|
|
611
582
|
end
|
612
583
|
|
613
584
|
def schema_loaded?
|
614
|
-
|
585
|
+
@schema_loaded
|
615
586
|
end
|
616
587
|
|
617
588
|
def load_schema!
|
@@ -619,20 +590,11 @@ module ActiveRecord
|
|
619
590
|
raise ActiveRecord::TableNotSpecified, "#{self} has no table configured. Set one with #{self}.table_name="
|
620
591
|
end
|
621
592
|
|
622
|
-
columns_hash =
|
593
|
+
columns_hash = schema_cache.columns_hash(table_name)
|
623
594
|
columns_hash = columns_hash.except(*ignored_columns) unless ignored_columns.empty?
|
624
595
|
@columns_hash = columns_hash.freeze
|
625
|
-
|
626
|
-
|
627
|
-
type = _convert_type_from_options(type)
|
628
|
-
define_attribute(
|
629
|
-
name,
|
630
|
-
type,
|
631
|
-
default: column.default,
|
632
|
-
user_provided_default: false
|
633
|
-
)
|
634
|
-
alias_attribute :id_value, :id if name == "id"
|
635
|
-
end
|
596
|
+
|
597
|
+
_default_attributes # Precompute to cache DB-dependent attribute types
|
636
598
|
end
|
637
599
|
|
638
600
|
# Guesses the table name, but does not decorate it with prefix and suffix information.
|
@@ -658,12 +620,14 @@ module ActiveRecord
|
|
658
620
|
end
|
659
621
|
end
|
660
622
|
|
661
|
-
def
|
623
|
+
def type_for_column(connection, column)
|
624
|
+
type = connection.lookup_cast_type_from_column(column)
|
625
|
+
|
662
626
|
if immutable_strings_by_default && type.respond_to?(:to_immutable_string)
|
663
|
-
type.to_immutable_string
|
664
|
-
else
|
665
|
-
type
|
627
|
+
type = type.to_immutable_string
|
666
628
|
end
|
629
|
+
|
630
|
+
type
|
667
631
|
end
|
668
632
|
end
|
669
633
|
end
|