activerecord 7.1.5.2 → 8.1.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.
Files changed (244) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +567 -2443
  3. data/README.rdoc +16 -16
  4. data/examples/performance.rb +2 -2
  5. data/lib/active_record/association_relation.rb +3 -2
  6. data/lib/active_record/associations/alias_tracker.rb +31 -23
  7. data/lib/active_record/associations/association.rb +43 -12
  8. data/lib/active_record/associations/belongs_to_association.rb +31 -8
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  10. data/lib/active_record/associations/builder/association.rb +23 -11
  11. data/lib/active_record/associations/builder/belongs_to.rb +18 -4
  12. data/lib/active_record/associations/builder/collection_association.rb +7 -3
  13. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  14. data/lib/active_record/associations/builder/has_many.rb +3 -4
  15. data/lib/active_record/associations/builder/has_one.rb +3 -4
  16. data/lib/active_record/associations/builder/singular_association.rb +33 -5
  17. data/lib/active_record/associations/collection_association.rb +17 -9
  18. data/lib/active_record/associations/collection_proxy.rb +36 -5
  19. data/lib/active_record/associations/deprecation.rb +88 -0
  20. data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
  21. data/lib/active_record/associations/errors.rb +268 -0
  22. data/lib/active_record/associations/has_many_association.rb +1 -1
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -3
  24. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  25. data/lib/active_record/associations/join_dependency.rb +4 -2
  26. data/lib/active_record/associations/nested_error.rb +47 -0
  27. data/lib/active_record/associations/preloader/association.rb +4 -3
  28. data/lib/active_record/associations/preloader/batch.rb +7 -1
  29. data/lib/active_record/associations/preloader/branch.rb +8 -1
  30. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  31. data/lib/active_record/associations/singular_association.rb +14 -3
  32. data/lib/active_record/associations/through_association.rb +1 -1
  33. data/lib/active_record/associations.rb +250 -315
  34. data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
  35. data/lib/active_record/attribute_assignment.rb +0 -2
  36. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  37. data/lib/active_record/attribute_methods/primary_key.rb +25 -61
  38. data/lib/active_record/attribute_methods/query.rb +34 -0
  39. data/lib/active_record/attribute_methods/read.rb +1 -13
  40. data/lib/active_record/attribute_methods/serialization.rb +20 -27
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +19 -20
  42. data/lib/active_record/attribute_methods.rb +71 -75
  43. data/lib/active_record/attributes.rb +96 -68
  44. data/lib/active_record/autosave_association.rb +93 -58
  45. data/lib/active_record/base.rb +5 -7
  46. data/lib/active_record/callbacks.rb +1 -1
  47. data/lib/active_record/coders/json.rb +14 -5
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +50 -126
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -4
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +52 -13
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +681 -135
  52. data/lib/active_record/connection_adapters/abstract/database_statements.rb +165 -86
  53. data/lib/active_record/connection_adapters/abstract/query_cache.rb +226 -78
  54. data/lib/active_record/connection_adapters/abstract/quoting.rb +79 -114
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +11 -7
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +37 -36
  57. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
  58. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +136 -34
  59. data/lib/active_record/connection_adapters/abstract/transaction.rb +163 -68
  60. data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -129
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -63
  62. data/lib/active_record/connection_adapters/column.rb +17 -4
  63. data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -3
  64. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
  65. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
  66. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +41 -10
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +79 -46
  68. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +97 -101
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +14 -33
  70. data/lib/active_record/connection_adapters/pool_config.rb +14 -13
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +4 -0
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +98 -44
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -3
  74. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  75. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
  77. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  78. data/lib/active_record/connection_adapters/postgresql/quoting.rb +79 -68
  79. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  80. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +9 -17
  81. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +44 -41
  82. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +69 -32
  83. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +155 -75
  84. data/lib/active_record/connection_adapters/postgresql_adapter.rb +104 -121
  85. data/lib/active_record/connection_adapters/schema_cache.rb +126 -133
  86. data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
  87. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +91 -95
  88. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -54
  89. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
  90. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
  91. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +43 -2
  92. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -15
  93. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +231 -111
  94. data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
  95. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +40 -69
  96. data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
  97. data/lib/active_record/connection_adapters.rb +66 -0
  98. data/lib/active_record/connection_handling.rb +88 -46
  99. data/lib/active_record/core.rb +142 -58
  100. data/lib/active_record/counter_cache.rb +52 -18
  101. data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
  102. data/lib/active_record/database_configurations/database_config.rb +28 -5
  103. data/lib/active_record/database_configurations/hash_config.rb +103 -41
  104. data/lib/active_record/database_configurations/url_config.rb +30 -1
  105. data/lib/active_record/database_configurations.rb +8 -4
  106. data/lib/active_record/delegated_type.rb +43 -19
  107. data/lib/active_record/dynamic_matchers.rb +56 -71
  108. data/lib/active_record/encryption/config.rb +3 -1
  109. data/lib/active_record/encryption/encryptable_record.rb +12 -12
  110. data/lib/active_record/encryption/encrypted_attribute_type.rb +35 -6
  111. data/lib/active_record/encryption/encryptor.rb +58 -22
  112. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
  113. data/lib/active_record/encryption/key_provider.rb +1 -1
  114. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  115. data/lib/active_record/encryption/message_serializer.rb +4 -0
  116. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  117. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  118. data/lib/active_record/encryption/scheme.rb +9 -2
  119. data/lib/active_record/enum.rb +57 -36
  120. data/lib/active_record/errors.rb +76 -26
  121. data/lib/active_record/explain.rb +14 -25
  122. data/lib/active_record/explain_registry.rb +51 -2
  123. data/lib/active_record/filter_attribute_handler.rb +73 -0
  124. data/lib/active_record/fixture_set/table_row.rb +19 -2
  125. data/lib/active_record/fixtures.rb +39 -35
  126. data/lib/active_record/future_result.rb +21 -13
  127. data/lib/active_record/gem_version.rb +3 -3
  128. data/lib/active_record/inheritance.rb +5 -3
  129. data/lib/active_record/insert_all.rb +28 -20
  130. data/lib/active_record/integration.rb +4 -1
  131. data/lib/active_record/internal_metadata.rb +48 -34
  132. data/lib/active_record/locking/optimistic.rb +15 -7
  133. data/lib/active_record/locking/pessimistic.rb +5 -0
  134. data/lib/active_record/log_subscriber.rb +3 -34
  135. data/lib/active_record/message_pack.rb +1 -1
  136. data/lib/active_record/middleware/shard_selector.rb +34 -17
  137. data/lib/active_record/migration/command_recorder.rb +46 -14
  138. data/lib/active_record/migration/compatibility.rb +40 -25
  139. data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
  140. data/lib/active_record/migration/default_strategy.rb +4 -5
  141. data/lib/active_record/migration/pending_migration_connection.rb +2 -2
  142. data/lib/active_record/migration.rb +119 -103
  143. data/lib/active_record/model_schema.rb +66 -78
  144. data/lib/active_record/nested_attributes.rb +17 -9
  145. data/lib/active_record/persistence.rb +161 -454
  146. data/lib/active_record/query_cache.rb +33 -15
  147. data/lib/active_record/query_logs.rb +106 -39
  148. data/lib/active_record/query_logs_formatter.rb +17 -28
  149. data/lib/active_record/querying.rb +28 -16
  150. data/lib/active_record/railtie.rb +61 -74
  151. data/lib/active_record/railties/controller_runtime.rb +19 -5
  152. data/lib/active_record/railties/databases.rake +64 -78
  153. data/lib/active_record/railties/job_checkpoints.rb +15 -0
  154. data/lib/active_record/railties/job_runtime.rb +10 -11
  155. data/lib/active_record/reflection.rb +147 -53
  156. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  157. data/lib/active_record/relation/batches.rb +153 -73
  158. data/lib/active_record/relation/calculations.rb +146 -96
  159. data/lib/active_record/relation/delegation.rb +30 -23
  160. data/lib/active_record/relation/finder_methods.rb +64 -34
  161. data/lib/active_record/relation/merger.rb +12 -14
  162. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  163. data/lib/active_record/relation/predicate_builder/association_query_value.rb +19 -11
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +8 -8
  165. data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
  166. data/lib/active_record/relation/predicate_builder.rb +25 -10
  167. data/lib/active_record/relation/query_attribute.rb +4 -2
  168. data/lib/active_record/relation/query_methods.rb +351 -124
  169. data/lib/active_record/relation/spawn_methods.rb +9 -25
  170. data/lib/active_record/relation/where_clause.rb +17 -30
  171. data/lib/active_record/relation.rb +590 -124
  172. data/lib/active_record/result.rb +131 -59
  173. data/lib/active_record/runtime_registry.rb +44 -21
  174. data/lib/active_record/sanitization.rb +33 -25
  175. data/lib/active_record/schema.rb +8 -6
  176. data/lib/active_record/schema_dumper.rb +66 -31
  177. data/lib/active_record/schema_migration.rb +31 -14
  178. data/lib/active_record/scoping/named.rb +6 -2
  179. data/lib/active_record/scoping.rb +0 -1
  180. data/lib/active_record/secure_token.rb +3 -3
  181. data/lib/active_record/signed_id.rb +68 -20
  182. data/lib/active_record/statement_cache.rb +29 -25
  183. data/lib/active_record/store.rb +51 -22
  184. data/lib/active_record/structured_event_subscriber.rb +85 -0
  185. data/lib/active_record/table_metadata.rb +7 -33
  186. data/lib/active_record/tasks/abstract_tasks.rb +76 -0
  187. data/lib/active_record/tasks/database_tasks.rb +118 -90
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -42
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -40
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +17 -28
  191. data/lib/active_record/test_databases.rb +14 -4
  192. data/lib/active_record/test_fixtures.rb +123 -89
  193. data/lib/active_record/testing/query_assertions.rb +127 -0
  194. data/lib/active_record/timestamp.rb +6 -4
  195. data/lib/active_record/token_for.rb +22 -12
  196. data/lib/active_record/touch_later.rb +1 -1
  197. data/lib/active_record/transaction.rb +129 -0
  198. data/lib/active_record/transactions.rb +97 -18
  199. data/lib/active_record/translation.rb +0 -2
  200. data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
  201. data/lib/active_record/type/internal/timezone.rb +7 -0
  202. data/lib/active_record/type/json.rb +15 -2
  203. data/lib/active_record/type/serialized.rb +12 -7
  204. data/lib/active_record/type/type_map.rb +1 -1
  205. data/lib/active_record/type_caster/connection.rb +5 -4
  206. data/lib/active_record/validations/associated.rb +10 -4
  207. data/lib/active_record/validations/uniqueness.rb +23 -18
  208. data/lib/active_record/validations.rb +4 -1
  209. data/lib/active_record.rb +203 -59
  210. data/lib/arel/alias_predication.rb +3 -1
  211. data/lib/arel/collectors/bind.rb +4 -2
  212. data/lib/arel/collectors/composite.rb +7 -0
  213. data/lib/arel/collectors/sql_string.rb +2 -2
  214. data/lib/arel/collectors/substitute_binds.rb +3 -3
  215. data/lib/arel/crud.rb +8 -11
  216. data/lib/arel/delete_manager.rb +5 -0
  217. data/lib/arel/nodes/binary.rb +1 -7
  218. data/lib/arel/nodes/bound_sql_literal.rb +9 -5
  219. data/lib/arel/nodes/count.rb +2 -2
  220. data/lib/arel/nodes/delete_statement.rb +4 -2
  221. data/lib/arel/nodes/function.rb +4 -10
  222. data/lib/arel/nodes/named_function.rb +2 -2
  223. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  224. data/lib/arel/nodes/node.rb +6 -5
  225. data/lib/arel/nodes/sql_literal.rb +8 -1
  226. data/lib/arel/nodes/update_statement.rb +4 -2
  227. data/lib/arel/nodes.rb +2 -4
  228. data/lib/arel/predications.rb +1 -1
  229. data/lib/arel/select_manager.rb +14 -5
  230. data/lib/arel/table.rb +3 -7
  231. data/lib/arel/tree_manager.rb +3 -2
  232. data/lib/arel/update_manager.rb +7 -1
  233. data/lib/arel/visitors/dot.rb +3 -3
  234. data/lib/arel/visitors/mysql.rb +9 -4
  235. data/lib/arel/visitors/postgresql.rb +56 -12
  236. data/lib/arel/visitors/sqlite.rb +80 -8
  237. data/lib/arel/visitors/to_sql.rb +34 -37
  238. data/lib/arel.rb +10 -4
  239. data/lib/rails/generators/active_record/application_record/USAGE +1 -1
  240. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  241. metadata +23 -14
  242. data/lib/active_record/explain_subscriber.rb +0 -34
  243. data/lib/active_record/normalization.rb +0 -167
  244. data/lib/active_record/relation/record_fetch_warning.rb +0 -49
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "benchmark"
4
- require "set"
5
- require "zlib"
6
3
  require "active_support/core_ext/array/access"
7
4
  require "active_support/core_ext/enumerable"
8
5
  require "active_support/core_ext/module/attribute_accessors"
@@ -21,7 +18,7 @@ module ActiveRecord
21
18
  # For example the following migration is not reversible.
22
19
  # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
23
20
  #
24
- # class IrreversibleMigrationExample < ActiveRecord::Migration[7.1]
21
+ # class IrreversibleMigrationExample < ActiveRecord::Migration[8.1]
25
22
  # def change
26
23
  # create_table :distributors do |t|
27
24
  # t.string :zipcode
@@ -39,7 +36,7 @@ module ActiveRecord
39
36
  #
40
37
  # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
41
38
  #
42
- # class ReversibleMigrationExample < ActiveRecord::Migration[7.1]
39
+ # class ReversibleMigrationExample < ActiveRecord::Migration[8.1]
43
40
  # def up
44
41
  # create_table :distributors do |t|
45
42
  # t.string :zipcode
@@ -64,7 +61,7 @@ module ActiveRecord
64
61
  #
65
62
  # 2. Use the #reversible method in <tt>#change</tt> method:
66
63
  #
67
- # class ReversibleMigrationExample < ActiveRecord::Migration[7.1]
64
+ # class ReversibleMigrationExample < ActiveRecord::Migration[8.1]
68
65
  # def change
69
66
  # create_table :distributors do |t|
70
67
  # t.string :zipcode
@@ -131,22 +128,36 @@ module ActiveRecord
131
128
  end
132
129
  end
133
130
 
131
+ class InvalidMigrationTimestampError < MigrationError # :nodoc:
132
+ def initialize(version = nil, name = nil)
133
+ if version && name
134
+ super(<<~MSG)
135
+ Invalid timestamp #{version} for migration file: #{name}.
136
+ Timestamp must be in form YYYYMMDDHHMMSS, and less than #{(Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S")}.
137
+ MSG
138
+ else
139
+ super(<<~MSG)
140
+ Invalid timestamp for migration.
141
+ Timestamp must be in form YYYYMMDDHHMMSS, and less than #{(Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S")}.
142
+ MSG
143
+ end
144
+ end
145
+ end
146
+
134
147
  class PendingMigrationError < MigrationError # :nodoc:
135
148
  include ActiveSupport::ActionableError
136
149
 
137
150
  action "Run pending migrations" do
138
- ActiveRecord::Tasks::DatabaseTasks.migrate
151
+ ActiveRecord::Tasks::DatabaseTasks.migrate_all
139
152
 
140
153
  if ActiveRecord.dump_schema_after_migration
141
- connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
142
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(connection.pool.db_config)
154
+ ActiveRecord::Tasks::DatabaseTasks.dump_all
143
155
  end
144
156
  end
145
157
 
146
158
  def initialize(message = nil, pending_migrations: nil)
147
159
  if pending_migrations.nil?
148
- connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
149
- pending_migrations = connection.migration_context.open.pending_migrations
160
+ pending_migrations = connection_pool.migration_context.open.pending_migrations
150
161
  end
151
162
 
152
163
  super(message || detailed_migration_message(pending_migrations))
@@ -167,8 +178,8 @@ module ActiveRecord
167
178
  message
168
179
  end
169
180
 
170
- def connection
171
- ActiveRecord::Tasks::DatabaseTasks.migration_connection
181
+ def connection_pool
182
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
172
183
  end
173
184
  end
174
185
 
@@ -235,7 +246,7 @@ module ActiveRecord
235
246
  #
236
247
  # Example of a simple migration:
237
248
  #
238
- # class AddSsl < ActiveRecord::Migration[7.1]
249
+ # class AddSsl < ActiveRecord::Migration[8.1]
239
250
  # def up
240
251
  # add_column :accounts, :ssl_enabled, :boolean, default: true
241
252
  # end
@@ -255,7 +266,7 @@ module ActiveRecord
255
266
  #
256
267
  # Example of a more complex migration that also needs to initialize data:
257
268
  #
258
- # class AddSystemSettings < ActiveRecord::Migration[7.1]
269
+ # class AddSystemSettings < ActiveRecord::Migration[8.1]
259
270
  # def up
260
271
  # create_table :system_settings do |t|
261
272
  # t.string :name
@@ -342,7 +353,7 @@ module ActiveRecord
342
353
  #
343
354
  # === Deletion
344
355
  #
345
- # * <tt>drop_table(name)</tt>: Drops the table called +name+.
356
+ # * <tt>drop_table(*names)</tt>: Drops the given tables.
346
357
  # * <tt>drop_join_table(table_1, table_2, options)</tt>: Drops the join table
347
358
  # specified by the given arguments.
348
359
  # * <tt>remove_column(table_name, column_name, type, options)</tt>: Removes the column
@@ -384,7 +395,7 @@ module ActiveRecord
384
395
  # $ bin/rails generate migration add_fieldname_to_tablename fieldname:string
385
396
  #
386
397
  # This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
387
- # class AddFieldnameToTablename < ActiveRecord::Migration[7.1]
398
+ # class AddFieldnameToTablename < ActiveRecord::Migration[8.1]
388
399
  # def change
389
400
  # add_column :tablenames, :fieldname, :string
390
401
  # end
@@ -410,7 +421,7 @@ module ActiveRecord
410
421
  #
411
422
  # Not all migrations change the schema. Some just fix the data:
412
423
  #
413
- # class RemoveEmptyTags < ActiveRecord::Migration[7.1]
424
+ # class RemoveEmptyTags < ActiveRecord::Migration[8.1]
414
425
  # def up
415
426
  # Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
416
427
  # end
@@ -423,7 +434,7 @@ module ActiveRecord
423
434
  #
424
435
  # Others remove columns when they migrate up instead of down:
425
436
  #
426
- # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.1]
437
+ # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[8.1]
427
438
  # def up
428
439
  # remove_column :items, :incomplete_items_count
429
440
  # remove_column :items, :completed_items_count
@@ -437,7 +448,7 @@ module ActiveRecord
437
448
  #
438
449
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
439
450
  #
440
- # class MakeJoinUnique < ActiveRecord::Migration[7.1]
451
+ # class MakeJoinUnique < ActiveRecord::Migration[8.1]
441
452
  # def up
442
453
  # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
443
454
  # end
@@ -454,7 +465,7 @@ module ActiveRecord
454
465
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
455
466
  # latest column data from after the new column was added. Example:
456
467
  #
457
- # class AddPeopleSalary < ActiveRecord::Migration[7.1]
468
+ # class AddPeopleSalary < ActiveRecord::Migration[8.1]
458
469
  # def up
459
470
  # add_column :people, :salary, :integer
460
471
  # Person.reset_column_information
@@ -470,7 +481,7 @@ module ActiveRecord
470
481
  # them to the console as they happen, along with benchmarks describing how
471
482
  # long each step took.
472
483
  #
473
- # You can quiet them down by setting ActiveRecord::Migration.verbose = false.
484
+ # You can quiet them down by setting <tt>ActiveRecord::Migration.verbose = false</tt>.
474
485
  #
475
486
  # You can also insert your own messages and benchmarks by using the +say_with_time+
476
487
  # method:
@@ -494,7 +505,11 @@ module ActiveRecord
494
505
  #
495
506
  # 20080717013526_your_migration_name.rb
496
507
  #
497
- # The prefix is a generation timestamp (in UTC).
508
+ # The prefix is a generation timestamp (in UTC). Timestamps should not be
509
+ # modified manually. To validate that migration timestamps adhere to the
510
+ # format Active Record expects, you can use the following configuration option:
511
+ #
512
+ # config.active_record.validate_migration_timestamps = true
498
513
  #
499
514
  # If you'd prefer to use numeric prefixes, you can turn timestamped migrations
500
515
  # off by setting:
@@ -512,7 +527,7 @@ module ActiveRecord
512
527
  # To define a reversible migration, define the +change+ method in your
513
528
  # migration like this:
514
529
  #
515
- # class TenderloveMigration < ActiveRecord::Migration[7.1]
530
+ # class TenderloveMigration < ActiveRecord::Migration[8.1]
516
531
  # def change
517
532
  # create_table(:horses) do |t|
518
533
  # t.column :content, :text
@@ -542,7 +557,7 @@ module ActiveRecord
542
557
  # can't execute inside a transaction though, and for these situations
543
558
  # you can turn the automatic transactions off.
544
559
  #
545
- # class ChangeEnum < ActiveRecord::Migration[7.1]
560
+ # class ChangeEnum < ActiveRecord::Migration[8.1]
546
561
  # disable_ddl_transaction!
547
562
  #
548
563
  # def up
@@ -555,6 +570,7 @@ module ActiveRecord
555
570
  class Migration
556
571
  autoload :CommandRecorder, "active_record/migration/command_recorder"
557
572
  autoload :Compatibility, "active_record/migration/compatibility"
573
+ autoload :DefaultSchemaVersionsFormatter, "active_record/migration/default_schema_versions_formatter"
558
574
  autoload :JoinTable, "active_record/migration/join_table"
559
575
  autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
560
576
  autoload :DefaultStrategy, "active_record/migration/default_strategy"
@@ -585,7 +601,7 @@ module ActiveRecord
585
601
  end
586
602
  end
587
603
 
588
- def drop_table(table_name, **options)
604
+ def drop_table(*table_names, **options)
589
605
  if block_given?
590
606
  super { |t| yield compatible_table_definition(t) }
591
607
  else
@@ -662,10 +678,6 @@ module ActiveRecord
662
678
  paths = all_configs.flat_map { |config| config.migrations_paths || Migrator.migrations_paths }.uniq
663
679
  @file_watcher.new([], paths.index_with(["rb"]), &block)
664
680
  end
665
-
666
- def connection
667
- ActiveRecord::Tasks::DatabaseTasks.migration_connection
668
- end
669
681
  end
670
682
 
671
683
  class << self
@@ -676,30 +688,13 @@ module ActiveRecord
676
688
  delegate || superclass.nearest_delegate
677
689
  end
678
690
 
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
691
  # Raises ActiveRecord::PendingMigrationError error if any migrations are pending
697
692
  # for all database configurations in an environment.
698
693
  def check_all_pending!
699
694
  pending_migrations = []
700
695
 
701
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: env) do |connection|
702
- if pending = connection.migration_context.open.pending_migrations
696
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: env) do |pool|
697
+ if pending = pool.migration_context.open.pending_migrations
703
698
  pending_migrations << pending
704
699
  end
705
700
  end
@@ -713,13 +708,7 @@ module ActiveRecord
713
708
 
714
709
  def load_schema_if_pending!
715
710
  if any_schema_needs_update?
716
- # Roundtrip to Rake to allow plugins to hook into database initialization.
717
- root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
718
-
719
- FileUtils.cd(root) do
720
- Base.connection_handler.clear_all_connections!(:all)
721
- system("bin/rails db:test:prepare")
722
- end
711
+ load_schema!
723
712
  end
724
713
 
725
714
  check_pending_migrations
@@ -731,10 +720,9 @@ module ActiveRecord
731
720
  end
732
721
  end
733
722
 
734
- def method_missing(name, *args, &block) # :nodoc:
735
- nearest_delegate.send(name, *args, &block)
723
+ def method_missing(name, ...) # :nodoc:
724
+ nearest_delegate.send(name, ...)
736
725
  end
737
- ruby2_keywords(:method_missing)
738
726
 
739
727
  def migrate(direction)
740
728
  new.migrate direction
@@ -759,7 +747,7 @@ module ActiveRecord
759
747
  private
760
748
  def any_schema_needs_update?
761
749
  !db_configs_in_current_env.all? do |db_config|
762
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
750
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config)
763
751
  end
764
752
  end
765
753
 
@@ -771,8 +759,8 @@ module ActiveRecord
771
759
  pending_migrations = []
772
760
 
773
761
  ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
774
- ActiveRecord::PendingMigrationConnection.establish_temporary_connection(db_config) do |conn|
775
- if pending = conn.migration_context.open.pending_migrations
762
+ ActiveRecord::PendingMigrationConnection.with_temporary_pool(db_config) do |pool|
763
+ if pending = pool.migration_context.open.pending_migrations
776
764
  pending_migrations << pending
777
765
  end
778
766
  end
@@ -784,12 +772,33 @@ module ActiveRecord
784
772
  def env
785
773
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
786
774
  end
775
+
776
+ def load_schema!
777
+ # Roundtrip to Rake to allow plugins to hook into database initialization.
778
+ root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
779
+
780
+ FileUtils.cd(root) do
781
+ Base.connection_handler.clear_all_connections!(:all)
782
+ system("bin/rails db:test:prepare")
783
+ end
784
+ end
785
+
786
+ def respond_to_missing?(method, include_private = false)
787
+ return false if nearest_delegate == delegate
788
+ nearest_delegate.respond_to?(method, include_private)
789
+ end
787
790
  end
788
791
 
789
792
  def disable_ddl_transaction # :nodoc:
790
793
  self.class.disable_ddl_transaction
791
794
  end
792
795
 
796
+ ##
797
+ # :singleton-method: verbose
798
+ #
799
+ # Specifies if migrations will write the actions they are taking to the console as they
800
+ # happen, along with benchmarks describing how long each step took. Defaults to
801
+ # true.
793
802
  cattr_accessor :verbose
794
803
  attr_accessor :name, :version
795
804
 
@@ -797,6 +806,7 @@ module ActiveRecord
797
806
  @name = name
798
807
  @version = version
799
808
  @connection = nil
809
+ @pool = nil
800
810
  end
801
811
 
802
812
  def execution_strategy
@@ -814,7 +824,7 @@ module ActiveRecord
814
824
  # and create the table 'apples' on the way up, and the reverse
815
825
  # on the way down.
816
826
  #
817
- # class FixTLMigration < ActiveRecord::Migration[7.1]
827
+ # class FixTLMigration < ActiveRecord::Migration[8.1]
818
828
  # def change
819
829
  # revert do
820
830
  # create_table(:horses) do |t|
@@ -833,7 +843,7 @@ module ActiveRecord
833
843
  #
834
844
  # require_relative "20121212123456_tenderlove_migration"
835
845
  #
836
- # class FixupTLMigration < ActiveRecord::Migration[7.1]
846
+ # class FixupTLMigration < ActiveRecord::Migration[8.1]
837
847
  # def change
838
848
  # revert TenderloveMigration
839
849
  #
@@ -884,7 +894,7 @@ module ActiveRecord
884
894
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
885
895
  # even when migrating down:
886
896
  #
887
- # class SplitNameMigration < ActiveRecord::Migration[7.1]
897
+ # class SplitNameMigration < ActiveRecord::Migration[8.1]
888
898
  # def change
889
899
  # add_column :users, :first_name, :string
890
900
  # add_column :users, :last_name, :string
@@ -912,7 +922,7 @@ module ActiveRecord
912
922
  # In the following example, the new column +published+ will be given
913
923
  # the value +true+ for all existing records.
914
924
  #
915
- # class AddPublishedToPosts < ActiveRecord::Migration[7.1]
925
+ # class AddPublishedToPosts < ActiveRecord::Migration[8.1]
916
926
  # def change
917
927
  # add_column :posts, :published, :boolean, default: false
918
928
  # up_only do
@@ -964,16 +974,16 @@ module ActiveRecord
964
974
  when :down then announce "reverting"
965
975
  end
966
976
 
967
- time = nil
977
+ time_elapsed = nil
968
978
  ActiveRecord::Tasks::DatabaseTasks.migration_connection.pool.with_connection do |conn|
969
- time = Benchmark.measure do
979
+ time_elapsed = ActiveSupport::Benchmark.realtime do
970
980
  exec_migration(conn, direction)
971
981
  end
972
982
  end
973
983
 
974
984
  case direction
975
- when :up then announce "migrated (%.4fs)" % time.real; write
976
- when :down then announce "reverted (%.4fs)" % time.real; write
985
+ when :up then announce "migrated (%.4fs)" % time_elapsed; write
986
+ when :down then announce "reverted (%.4fs)" % time_elapsed; write
977
987
  end
978
988
  end
979
989
 
@@ -1014,8 +1024,8 @@ module ActiveRecord
1014
1024
  def say_with_time(message)
1015
1025
  say(message)
1016
1026
  result = nil
1017
- time = Benchmark.measure { result = yield }
1018
- say "%.4fs" % time.real, :subitem
1027
+ time_elapsed = ActiveSupport::Benchmark.realtime { result = yield }
1028
+ say "%.4fs" % time_elapsed, :subitem
1019
1029
  say("#{result} rows", :subitem) if result.is_a?(Integer)
1020
1030
  result
1021
1031
  end
@@ -1032,6 +1042,10 @@ module ActiveRecord
1032
1042
  @connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
1033
1043
  end
1034
1044
 
1045
+ def connection_pool
1046
+ @pool || ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
1047
+ end
1048
+
1035
1049
  def method_missing(method, *arguments, &block)
1036
1050
  say_with_time "#{method}(#{format_arguments(arguments)})" do
1037
1051
  unless connection.respond_to? :revert
@@ -1161,6 +1175,10 @@ module ActiveRecord
1161
1175
  def command_recorder
1162
1176
  CommandRecorder.new(connection)
1163
1177
  end
1178
+
1179
+ def respond_to_missing?(method, include_private = false)
1180
+ execution_strategy.respond_to?(method, include_private) || super
1181
+ end
1164
1182
  end
1165
1183
 
1166
1184
  # MigrationProxy is used to defer loading of the actual migration classes
@@ -1203,31 +1221,9 @@ module ActiveRecord
1203
1221
  attr_reader :migrations_paths, :schema_migration, :internal_metadata
1204
1222
 
1205
1223
  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
1224
  @migrations_paths = migrations_paths
1229
- @schema_migration = schema_migration || SchemaMigration.new(connection)
1230
- @internal_metadata = internal_metadata || InternalMetadata.new(connection)
1225
+ @schema_migration = schema_migration || SchemaMigration.new(connection_pool)
1226
+ @internal_metadata = internal_metadata || InternalMetadata.new(connection_pool)
1231
1227
  end
1232
1228
 
1233
1229
  # Runs the migrations in the +migrations_path+.
@@ -1317,6 +1313,9 @@ module ActiveRecord
1317
1313
  migrations = migration_files.map do |file|
1318
1314
  version, name, scope = parse_migration_filename(file)
1319
1315
  raise IllegalMigrationNameError.new(file) unless version
1316
+ if validate_timestamp? && !valid_migration_timestamp?(version)
1317
+ raise InvalidMigrationTimestampError.new(version, name)
1318
+ end
1320
1319
  version = version.to_i
1321
1320
  name = name.camelize
1322
1321
 
@@ -1332,6 +1331,9 @@ module ActiveRecord
1332
1331
  file_list = migration_files.filter_map do |file|
1333
1332
  version, name, scope = parse_migration_filename(file)
1334
1333
  raise IllegalMigrationNameError.new(file) unless version
1334
+ if validate_timestamp? && !valid_migration_timestamp?(version)
1335
+ raise InvalidMigrationTimestampError.new(version, name)
1336
+ end
1335
1337
  version = schema_migration.normalize_migration_number(version)
1336
1338
  status = db_list.delete(version) ? "up" : "down"
1337
1339
  [status, version, (name + scope).humanize]
@@ -1353,11 +1355,12 @@ module ActiveRecord
1353
1355
  end
1354
1356
 
1355
1357
  def last_stored_environment # :nodoc:
1356
- return nil unless connection.internal_metadata.enabled?
1358
+ internal_metadata = connection_pool.internal_metadata
1359
+ return nil unless internal_metadata.enabled?
1357
1360
  return nil if current_version == 0
1358
- raise NoEnvironmentInSchemaError unless connection.internal_metadata.table_exists?
1361
+ raise NoEnvironmentInSchemaError unless internal_metadata.table_exists?
1359
1362
 
1360
- environment = connection.internal_metadata[:environment]
1363
+ environment = internal_metadata[:environment]
1361
1364
  raise NoEnvironmentInSchemaError unless environment
1362
1365
  environment
1363
1366
  end
@@ -1367,6 +1370,10 @@ module ActiveRecord
1367
1370
  ActiveRecord::Tasks::DatabaseTasks.migration_connection
1368
1371
  end
1369
1372
 
1373
+ def connection_pool
1374
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
1375
+ end
1376
+
1370
1377
  def migration_files
1371
1378
  paths = Array(migrations_paths)
1372
1379
  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
@@ -1376,6 +1383,14 @@ module ActiveRecord
1376
1383
  File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1377
1384
  end
1378
1385
 
1386
+ def validate_timestamp?
1387
+ ActiveRecord.timestamped_migrations && ActiveRecord.validate_migration_timestamps
1388
+ end
1389
+
1390
+ def valid_migration_timestamp?(version)
1391
+ version.to_i < (Time.now.utc + 1.day).strftime("%Y%m%d%H%M%S").to_i
1392
+ end
1393
+
1379
1394
  def move(direction, steps)
1380
1395
  migrator = Migrator.new(direction, migrations, schema_migration, internal_metadata)
1381
1396
 
@@ -1402,9 +1417,9 @@ module ActiveRecord
1402
1417
 
1403
1418
  # For cases where a table doesn't exist like loading from schema cache
1404
1419
  def current_version
1405
- connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
1406
- schema_migration = SchemaMigration.new(connection)
1407
- internal_metadata = InternalMetadata.new(connection)
1420
+ connection_pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
1421
+ schema_migration = SchemaMigration.new(connection_pool)
1422
+ internal_metadata = InternalMetadata.new(connection_pool)
1408
1423
 
1409
1424
  MigrationContext.new(migrations_paths, schema_migration, internal_metadata).current_version
1410
1425
  end
@@ -1523,7 +1538,8 @@ module ActiveRecord
1523
1538
  return if down? && !migrated.include?(migration.version.to_i)
1524
1539
  return if up? && migrated.include?(migration.version.to_i)
1525
1540
 
1526
- Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
1541
+ message = up? ? "Migrating to" : "Reverting"
1542
+ Base.logger.info "#{message} #{migration.name} (#{migration.version})" if Base.logger
1527
1543
 
1528
1544
  ddl_transaction(migration) do
1529
1545
  migration.migrate(@direction)