activerecord 6.1.4 → 7.0.0.rc1

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.

Files changed (234) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1049 -977
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +0 -10
  7. data/lib/active_record/associations/association.rb +33 -17
  8. data/lib/active_record/associations/association_scope.rb +1 -3
  9. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +8 -2
  12. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_many.rb +3 -2
  15. data/lib/active_record/associations/builder/has_one.rb +2 -1
  16. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  17. data/lib/active_record/associations/collection_association.rb +34 -27
  18. data/lib/active_record/associations/collection_proxy.rb +8 -3
  19. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  20. data/lib/active_record/associations/has_many_association.rb +1 -1
  21. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  22. data/lib/active_record/associations/has_one_association.rb +10 -7
  23. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  24. data/lib/active_record/associations/preloader/association.rb +187 -55
  25. data/lib/active_record/associations/preloader/batch.rb +48 -0
  26. data/lib/active_record/associations/preloader/branch.rb +147 -0
  27. data/lib/active_record/associations/preloader/through_association.rb +49 -13
  28. data/lib/active_record/associations/preloader.rb +39 -113
  29. data/lib/active_record/associations/singular_association.rb +8 -2
  30. data/lib/active_record/associations/through_association.rb +3 -3
  31. data/lib/active_record/associations.rb +90 -82
  32. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  33. data/lib/active_record/attribute_assignment.rb +1 -1
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
  35. data/lib/active_record/attribute_methods/dirty.rb +49 -16
  36. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  37. data/lib/active_record/attribute_methods/query.rb +2 -2
  38. data/lib/active_record/attribute_methods/read.rb +7 -5
  39. data/lib/active_record/attribute_methods/serialization.rb +66 -12
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  41. data/lib/active_record/attribute_methods/write.rb +7 -10
  42. data/lib/active_record/attribute_methods.rb +13 -14
  43. data/lib/active_record/attributes.rb +24 -35
  44. data/lib/active_record/autosave_association.rb +6 -21
  45. data/lib/active_record/base.rb +19 -1
  46. data/lib/active_record/callbacks.rb +2 -2
  47. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  48. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  51. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  52. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  53. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  54. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +34 -9
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +69 -18
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +97 -81
  61. data/lib/active_record/connection_adapters/column.rb +4 -0
  62. data/lib/active_record/connection_adapters/mysql/database_statements.rb +35 -23
  63. data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
  64. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +4 -1
  65. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  66. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  67. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
  68. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
  69. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  70. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  71. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  72. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  73. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  76. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  77. data/lib/active_record/connection_adapters/postgresql/quoting.rb +50 -50
  78. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
  79. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  80. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  81. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +27 -16
  83. data/lib/active_record/connection_adapters/postgresql_adapter.rb +205 -105
  84. data/lib/active_record/connection_adapters/schema_cache.rb +29 -4
  85. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
  86. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +15 -16
  87. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
  88. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
  89. data/lib/active_record/connection_adapters.rb +6 -5
  90. data/lib/active_record/connection_handling.rb +47 -53
  91. data/lib/active_record/core.rb +122 -132
  92. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  93. data/lib/active_record/database_configurations/database_config.rb +12 -9
  94. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  95. data/lib/active_record/database_configurations/url_config.rb +2 -2
  96. data/lib/active_record/database_configurations.rb +16 -32
  97. data/lib/active_record/delegated_type.rb +52 -11
  98. data/lib/active_record/destroy_association_async_job.rb +1 -1
  99. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  100. data/lib/active_record/dynamic_matchers.rb +1 -1
  101. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  102. data/lib/active_record/encryption/cipher.rb +53 -0
  103. data/lib/active_record/encryption/config.rb +44 -0
  104. data/lib/active_record/encryption/configurable.rb +61 -0
  105. data/lib/active_record/encryption/context.rb +35 -0
  106. data/lib/active_record/encryption/contexts.rb +72 -0
  107. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  108. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  109. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  110. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  111. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  112. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  113. data/lib/active_record/encryption/encryptor.rb +155 -0
  114. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  115. data/lib/active_record/encryption/errors.rb +15 -0
  116. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  117. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  118. data/lib/active_record/encryption/key.rb +28 -0
  119. data/lib/active_record/encryption/key_generator.rb +42 -0
  120. data/lib/active_record/encryption/key_provider.rb +46 -0
  121. data/lib/active_record/encryption/message.rb +33 -0
  122. data/lib/active_record/encryption/message_serializer.rb +90 -0
  123. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  124. data/lib/active_record/encryption/properties.rb +76 -0
  125. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  126. data/lib/active_record/encryption/scheme.rb +99 -0
  127. data/lib/active_record/encryption.rb +55 -0
  128. data/lib/active_record/enum.rb +49 -42
  129. data/lib/active_record/errors.rb +67 -4
  130. data/lib/active_record/explain_registry.rb +11 -6
  131. data/lib/active_record/fixture_set/file.rb +15 -1
  132. data/lib/active_record/fixture_set/table_row.rb +41 -6
  133. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  134. data/lib/active_record/fixtures.rb +17 -20
  135. data/lib/active_record/future_result.rb +139 -0
  136. data/lib/active_record/gem_version.rb +4 -4
  137. data/lib/active_record/inheritance.rb +55 -17
  138. data/lib/active_record/insert_all.rb +80 -14
  139. data/lib/active_record/integration.rb +4 -3
  140. data/lib/active_record/internal_metadata.rb +3 -5
  141. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  142. data/lib/active_record/locking/optimistic.rb +10 -9
  143. data/lib/active_record/locking/pessimistic.rb +9 -3
  144. data/lib/active_record/log_subscriber.rb +14 -3
  145. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  146. data/lib/active_record/middleware/database_selector.rb +8 -3
  147. data/lib/active_record/middleware/shard_selector.rb +60 -0
  148. data/lib/active_record/migration/command_recorder.rb +4 -4
  149. data/lib/active_record/migration/compatibility.rb +83 -1
  150. data/lib/active_record/migration/join_table.rb +1 -1
  151. data/lib/active_record/migration.rb +109 -79
  152. data/lib/active_record/model_schema.rb +45 -58
  153. data/lib/active_record/nested_attributes.rb +13 -12
  154. data/lib/active_record/no_touching.rb +3 -3
  155. data/lib/active_record/null_relation.rb +2 -6
  156. data/lib/active_record/persistence.rb +219 -52
  157. data/lib/active_record/query_cache.rb +2 -2
  158. data/lib/active_record/query_logs.rb +138 -0
  159. data/lib/active_record/querying.rb +15 -5
  160. data/lib/active_record/railtie.rb +127 -17
  161. data/lib/active_record/railties/controller_runtime.rb +1 -1
  162. data/lib/active_record/railties/databases.rake +66 -129
  163. data/lib/active_record/readonly_attributes.rb +11 -0
  164. data/lib/active_record/reflection.rb +67 -50
  165. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  166. data/lib/active_record/relation/batches.rb +3 -3
  167. data/lib/active_record/relation/calculations.rb +40 -36
  168. data/lib/active_record/relation/delegation.rb +6 -6
  169. data/lib/active_record/relation/finder_methods.rb +31 -35
  170. data/lib/active_record/relation/merger.rb +20 -13
  171. data/lib/active_record/relation/predicate_builder.rb +1 -6
  172. data/lib/active_record/relation/query_attribute.rb +5 -11
  173. data/lib/active_record/relation/query_methods.rb +235 -61
  174. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  175. data/lib/active_record/relation/spawn_methods.rb +2 -2
  176. data/lib/active_record/relation/where_clause.rb +10 -19
  177. data/lib/active_record/relation.rb +171 -84
  178. data/lib/active_record/result.rb +17 -7
  179. data/lib/active_record/runtime_registry.rb +9 -13
  180. data/lib/active_record/sanitization.rb +11 -7
  181. data/lib/active_record/schema_dumper.rb +10 -3
  182. data/lib/active_record/schema_migration.rb +0 -4
  183. data/lib/active_record/scoping/default.rb +61 -12
  184. data/lib/active_record/scoping/named.rb +3 -11
  185. data/lib/active_record/scoping.rb +64 -34
  186. data/lib/active_record/serialization.rb +1 -1
  187. data/lib/active_record/signed_id.rb +1 -1
  188. data/lib/active_record/suppressor.rb +11 -15
  189. data/lib/active_record/tasks/database_tasks.rb +116 -58
  190. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  191. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
  192. data/lib/active_record/test_databases.rb +1 -1
  193. data/lib/active_record/test_fixtures.rb +4 -4
  194. data/lib/active_record/timestamp.rb +3 -4
  195. data/lib/active_record/transactions.rb +9 -14
  196. data/lib/active_record/translation.rb +2 -2
  197. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  198. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  199. data/lib/active_record/type/internal/timezone.rb +2 -2
  200. data/lib/active_record/type/serialized.rb +1 -1
  201. data/lib/active_record/type/type_map.rb +17 -20
  202. data/lib/active_record/type.rb +1 -2
  203. data/lib/active_record/validations/associated.rb +1 -1
  204. data/lib/active_record/validations/uniqueness.rb +1 -1
  205. data/lib/active_record.rb +204 -28
  206. data/lib/arel/attributes/attribute.rb +0 -8
  207. data/lib/arel/crud.rb +28 -22
  208. data/lib/arel/delete_manager.rb +18 -4
  209. data/lib/arel/filter_predications.rb +9 -0
  210. data/lib/arel/insert_manager.rb +2 -3
  211. data/lib/arel/nodes/casted.rb +1 -1
  212. data/lib/arel/nodes/delete_statement.rb +12 -13
  213. data/lib/arel/nodes/filter.rb +10 -0
  214. data/lib/arel/nodes/function.rb +1 -0
  215. data/lib/arel/nodes/insert_statement.rb +2 -2
  216. data/lib/arel/nodes/select_core.rb +2 -2
  217. data/lib/arel/nodes/select_statement.rb +2 -2
  218. data/lib/arel/nodes/update_statement.rb +8 -3
  219. data/lib/arel/nodes.rb +1 -0
  220. data/lib/arel/predications.rb +11 -3
  221. data/lib/arel/select_manager.rb +10 -4
  222. data/lib/arel/table.rb +0 -1
  223. data/lib/arel/tree_manager.rb +0 -12
  224. data/lib/arel/update_manager.rb +18 -4
  225. data/lib/arel/visitors/dot.rb +80 -90
  226. data/lib/arel/visitors/mysql.rb +8 -2
  227. data/lib/arel/visitors/postgresql.rb +0 -10
  228. data/lib/arel/visitors/to_sql.rb +58 -2
  229. data/lib/arel.rb +2 -1
  230. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  231. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  232. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  233. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  234. metadata +56 -13
@@ -9,7 +9,7 @@ require "active_support/core_ext/module/attribute_accessors"
9
9
  require "active_support/actionable_error"
10
10
 
11
11
  module ActiveRecord
12
- class MigrationError < ActiveRecordError #:nodoc:
12
+ class MigrationError < ActiveRecordError # :nodoc:
13
13
  def initialize(message = nil)
14
14
  message = "\n\n#{message}\n\n" if message
15
15
  super
@@ -20,7 +20,7 @@ module ActiveRecord
20
20
  # For example the following migration is not reversible.
21
21
  # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
22
22
  #
23
- # class IrreversibleMigrationExample < ActiveRecord::Migration[6.0]
23
+ # class IrreversibleMigrationExample < ActiveRecord::Migration[7.0]
24
24
  # def change
25
25
  # create_table :distributors do |t|
26
26
  # t.string :zipcode
@@ -38,7 +38,7 @@ module ActiveRecord
38
38
  #
39
39
  # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
40
40
  #
41
- # class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
41
+ # class ReversibleMigrationExample < ActiveRecord::Migration[7.0]
42
42
  # def up
43
43
  # create_table :distributors do |t|
44
44
  # t.string :zipcode
@@ -63,7 +63,7 @@ module ActiveRecord
63
63
  #
64
64
  # 2. Use the #reversible method in <tt>#change</tt> method:
65
65
  #
66
- # class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
66
+ # class ReversibleMigrationExample < ActiveRecord::Migration[7.0]
67
67
  # def change
68
68
  # create_table :distributors do |t|
69
69
  # t.string :zipcode
@@ -90,7 +90,7 @@ module ActiveRecord
90
90
  class IrreversibleMigration < MigrationError
91
91
  end
92
92
 
93
- class DuplicateMigrationVersionError < MigrationError #:nodoc:
93
+ class DuplicateMigrationVersionError < MigrationError # :nodoc:
94
94
  def initialize(version = nil)
95
95
  if version
96
96
  super("Multiple migrations have the version number #{version}.")
@@ -100,7 +100,7 @@ module ActiveRecord
100
100
  end
101
101
  end
102
102
 
103
- class DuplicateMigrationNameError < MigrationError #:nodoc:
103
+ class DuplicateMigrationNameError < MigrationError # :nodoc:
104
104
  def initialize(name = nil)
105
105
  if name
106
106
  super("Multiple migrations have the name #{name}.")
@@ -110,7 +110,7 @@ module ActiveRecord
110
110
  end
111
111
  end
112
112
 
113
- class UnknownMigrationVersionError < MigrationError #:nodoc:
113
+ class UnknownMigrationVersionError < MigrationError # :nodoc:
114
114
  def initialize(version = nil)
115
115
  if version
116
116
  super("No migration with version number #{version}.")
@@ -120,7 +120,7 @@ module ActiveRecord
120
120
  end
121
121
  end
122
122
 
123
- class IllegalMigrationNameError < MigrationError #:nodoc:
123
+ class IllegalMigrationNameError < MigrationError # :nodoc:
124
124
  def initialize(name = nil)
125
125
  if name
126
126
  super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed).")
@@ -130,13 +130,13 @@ module ActiveRecord
130
130
  end
131
131
  end
132
132
 
133
- class PendingMigrationError < MigrationError #:nodoc:
133
+ class PendingMigrationError < MigrationError # :nodoc:
134
134
  include ActiveSupport::ActionableError
135
135
 
136
136
  action "Run pending migrations" do
137
137
  ActiveRecord::Tasks::DatabaseTasks.migrate
138
138
 
139
- if ActiveRecord::Base.dump_schema_after_migration
139
+ if ActiveRecord.dump_schema_after_migration
140
140
  ActiveRecord::Tasks::DatabaseTasks.dump_schema(
141
141
  ActiveRecord::Base.connection_db_config
142
142
  )
@@ -165,7 +165,7 @@ module ActiveRecord
165
165
  end
166
166
  end
167
167
 
168
- class ConcurrentMigrationError < MigrationError #:nodoc:
168
+ class ConcurrentMigrationError < MigrationError # :nodoc:
169
169
  DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running."
170
170
  RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock"
171
171
 
@@ -174,7 +174,7 @@ module ActiveRecord
174
174
  end
175
175
  end
176
176
 
177
- class NoEnvironmentInSchemaError < MigrationError #:nodoc:
177
+ class NoEnvironmentInSchemaError < MigrationError # :nodoc:
178
178
  def initialize
179
179
  msg = "Environment data not found in the schema. To resolve this issue, run: \n\n bin/rails db:environment:set"
180
180
  if defined?(Rails.env)
@@ -185,7 +185,7 @@ module ActiveRecord
185
185
  end
186
186
  end
187
187
 
188
- class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
188
+ class ProtectedEnvironmentError < ActiveRecordError # :nodoc:
189
189
  def initialize(env = "production")
190
190
  msg = +"You are attempting to run a destructive action against your '#{env}' database.\n"
191
191
  msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
@@ -228,7 +228,7 @@ module ActiveRecord
228
228
  #
229
229
  # Example of a simple migration:
230
230
  #
231
- # class AddSsl < ActiveRecord::Migration[6.0]
231
+ # class AddSsl < ActiveRecord::Migration[7.0]
232
232
  # def up
233
233
  # add_column :accounts, :ssl_enabled, :boolean, default: true
234
234
  # end
@@ -248,7 +248,7 @@ module ActiveRecord
248
248
  #
249
249
  # Example of a more complex migration that also needs to initialize data:
250
250
  #
251
- # class AddSystemSettings < ActiveRecord::Migration[6.0]
251
+ # class AddSystemSettings < ActiveRecord::Migration[7.0]
252
252
  # def up
253
253
  # create_table :system_settings do |t|
254
254
  # t.string :name
@@ -376,7 +376,7 @@ module ActiveRecord
376
376
  # bin/rails generate migration add_fieldname_to_tablename fieldname:string
377
377
  #
378
378
  # This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
379
- # class AddFieldnameToTablename < ActiveRecord::Migration[6.0]
379
+ # class AddFieldnameToTablename < ActiveRecord::Migration[7.0]
380
380
  # def change
381
381
  # add_column :tablenames, :fieldname, :string
382
382
  # end
@@ -402,7 +402,7 @@ module ActiveRecord
402
402
  #
403
403
  # Not all migrations change the schema. Some just fix the data:
404
404
  #
405
- # class RemoveEmptyTags < ActiveRecord::Migration[6.0]
405
+ # class RemoveEmptyTags < ActiveRecord::Migration[7.0]
406
406
  # def up
407
407
  # Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
408
408
  # end
@@ -415,7 +415,7 @@ module ActiveRecord
415
415
  #
416
416
  # Others remove columns when they migrate up instead of down:
417
417
  #
418
- # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[6.0]
418
+ # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[7.0]
419
419
  # def up
420
420
  # remove_column :items, :incomplete_items_count
421
421
  # remove_column :items, :completed_items_count
@@ -429,7 +429,7 @@ module ActiveRecord
429
429
  #
430
430
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
431
431
  #
432
- # class MakeJoinUnique < ActiveRecord::Migration[6.0]
432
+ # class MakeJoinUnique < ActiveRecord::Migration[7.0]
433
433
  # def up
434
434
  # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
435
435
  # end
@@ -446,7 +446,7 @@ module ActiveRecord
446
446
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
447
447
  # latest column data from after the new column was added. Example:
448
448
  #
449
- # class AddPeopleSalary < ActiveRecord::Migration[6.0]
449
+ # class AddPeopleSalary < ActiveRecord::Migration[7.0]
450
450
  # def up
451
451
  # add_column :people, :salary, :integer
452
452
  # Person.reset_column_information
@@ -504,7 +504,7 @@ module ActiveRecord
504
504
  # To define a reversible migration, define the +change+ method in your
505
505
  # migration like this:
506
506
  #
507
- # class TenderloveMigration < ActiveRecord::Migration[6.0]
507
+ # class TenderloveMigration < ActiveRecord::Migration[7.0]
508
508
  # def change
509
509
  # create_table(:horses) do |t|
510
510
  # t.column :content, :text
@@ -534,7 +534,7 @@ module ActiveRecord
534
534
  # can't execute inside a transaction though, and for these situations
535
535
  # you can turn the automatic transactions off.
536
536
  #
537
- # class ChangeEnum < ActiveRecord::Migration[6.0]
537
+ # class ChangeEnum < ActiveRecord::Migration[7.0]
538
538
  # disable_ddl_transaction!
539
539
  #
540
540
  # def up
@@ -550,16 +550,18 @@ module ActiveRecord
550
550
  autoload :JoinTable, "active_record/migration/join_table"
551
551
 
552
552
  # This must be defined before the inherited hook, below
553
- class Current < Migration #:nodoc:
553
+ class Current < Migration # :nodoc:
554
554
  end
555
555
 
556
- def self.inherited(subclass) #:nodoc:
556
+ def self.inherited(subclass) # :nodoc:
557
557
  super
558
558
  if subclass.superclass == Migration
559
+ major = ActiveRecord::VERSION::MAJOR
560
+ minor = ActiveRecord::VERSION::MINOR
559
561
  raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
560
- "Please specify the Rails release the migration was written for:\n" \
562
+ "Please specify the Active Record release the migration was written for:\n" \
561
563
  "\n" \
562
- " class #{subclass} < ActiveRecord::Migration[4.2]"
564
+ " class #{subclass} < ActiveRecord::Migration[#{major}.#{minor}]"
563
565
  end
564
566
  end
565
567
 
@@ -571,7 +573,7 @@ module ActiveRecord
571
573
  ActiveRecord::VERSION::STRING.to_f
572
574
  end
573
575
 
574
- MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ #:nodoc:
576
+ MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
575
577
 
576
578
  # This class is used to verify that all migrations have been run before
577
579
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
@@ -613,10 +615,10 @@ module ActiveRecord
613
615
  end
614
616
 
615
617
  class << self
616
- attr_accessor :delegate #:nodoc:
617
- attr_accessor :disable_ddl_transaction #:nodoc:
618
+ attr_accessor :delegate # :nodoc:
619
+ attr_accessor :disable_ddl_transaction # :nodoc:
618
620
 
619
- def nearest_delegate #:nodoc:
621
+ def nearest_delegate # :nodoc:
620
622
  delegate || superclass.nearest_delegate
621
623
  end
622
624
 
@@ -630,7 +632,7 @@ module ActiveRecord
630
632
  all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
631
633
 
632
634
  needs_update = !all_configs.all? do |db_config|
633
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord::Base.schema_format)
635
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
634
636
  end
635
637
 
636
638
  if needs_update
@@ -648,16 +650,16 @@ module ActiveRecord
648
650
  check_pending!
649
651
  end
650
652
 
651
- def maintain_test_schema! #:nodoc:
652
- if ActiveRecord::Base.maintain_test_schema
653
+ def maintain_test_schema! # :nodoc:
654
+ if ActiveRecord.maintain_test_schema
653
655
  suppress_messages { load_schema_if_pending! }
654
656
  end
655
657
  end
656
658
 
657
- def method_missing(name, *args, &block) #:nodoc:
659
+ def method_missing(name, *args, &block) # :nodoc:
658
660
  nearest_delegate.send(name, *args, &block)
659
661
  end
660
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
662
+ ruby2_keywords(:method_missing)
661
663
 
662
664
  def migrate(direction)
663
665
  new.migrate direction
@@ -672,7 +674,7 @@ module ActiveRecord
672
674
  end
673
675
  end
674
676
 
675
- def disable_ddl_transaction #:nodoc:
677
+ def disable_ddl_transaction # :nodoc:
676
678
  self.class.disable_ddl_transaction
677
679
  end
678
680
 
@@ -696,7 +698,7 @@ module ActiveRecord
696
698
  # and create the table 'apples' on the way up, and the reverse
697
699
  # on the way down.
698
700
  #
699
- # class FixTLMigration < ActiveRecord::Migration[6.0]
701
+ # class FixTLMigration < ActiveRecord::Migration[7.0]
700
702
  # def change
701
703
  # revert do
702
704
  # create_table(:horses) do |t|
@@ -715,7 +717,7 @@ module ActiveRecord
715
717
  #
716
718
  # require_relative "20121212123456_tenderlove_migration"
717
719
  #
718
- # class FixupTLMigration < ActiveRecord::Migration[6.0]
720
+ # class FixupTLMigration < ActiveRecord::Migration[7.0]
719
721
  # def change
720
722
  # revert TenderloveMigration
721
723
  #
@@ -726,16 +728,16 @@ module ActiveRecord
726
728
  # end
727
729
  #
728
730
  # This command can be nested.
729
- def revert(*migration_classes)
731
+ def revert(*migration_classes, &block)
730
732
  run(*migration_classes.reverse, revert: true) unless migration_classes.empty?
731
733
  if block_given?
732
734
  if connection.respond_to? :revert
733
- connection.revert { yield }
735
+ connection.revert(&block)
734
736
  else
735
737
  recorder = command_recorder
736
738
  @connection = recorder
737
739
  suppress_messages do
738
- connection.revert { yield }
740
+ connection.revert(&block)
739
741
  end
740
742
  @connection = recorder.delegate
741
743
  recorder.replay(self)
@@ -747,7 +749,7 @@ module ActiveRecord
747
749
  connection.respond_to?(:reverting) && connection.reverting
748
750
  end
749
751
 
750
- ReversibleBlockHelper = Struct.new(:reverting) do #:nodoc:
752
+ ReversibleBlockHelper = Struct.new(:reverting) do # :nodoc:
751
753
  def up
752
754
  yield unless reverting
753
755
  end
@@ -766,7 +768,7 @@ module ActiveRecord
766
768
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
767
769
  # even when migrating down:
768
770
  #
769
- # class SplitNameMigration < ActiveRecord::Migration[6.0]
771
+ # class SplitNameMigration < ActiveRecord::Migration[7.0]
770
772
  # def change
771
773
  # add_column :users, :first_name, :string
772
774
  # add_column :users, :last_name, :string
@@ -794,7 +796,7 @@ module ActiveRecord
794
796
  # In the following example, the new column +published+ will be given
795
797
  # the value +true+ for all existing records.
796
798
  #
797
- # class AddPublishedToPosts < ActiveRecord::Migration[6.0]
799
+ # class AddPublishedToPosts < ActiveRecord::Migration[7.0]
798
800
  # def change
799
801
  # add_column :posts, :published, :boolean, default: false
800
802
  # up_only do
@@ -802,8 +804,8 @@ module ActiveRecord
802
804
  # end
803
805
  # end
804
806
  # end
805
- def up_only
806
- execute_block { yield } unless reverting?
807
+ def up_only(&block)
808
+ execute_block(&block) unless reverting?
807
809
  end
808
810
 
809
811
  # Runs the given migration classes.
@@ -919,7 +921,7 @@ module ActiveRecord
919
921
  unless connection.respond_to? :revert
920
922
  unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
921
923
  arguments[0] = proper_table_name(arguments.first, table_name_options)
922
- if [:rename_table, :add_foreign_key].include?(method) ||
924
+ if method == :rename_table ||
923
925
  (method == :remove_foreign_key && !arguments.second.is_a?(Hash))
924
926
  arguments[1] = proper_table_name(arguments.second, table_name_options)
925
927
  end
@@ -929,7 +931,7 @@ module ActiveRecord
929
931
  connection.send(method, *arguments, &block)
930
932
  end
931
933
  end
932
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
934
+ ruby2_keywords(:method_missing)
933
935
 
934
936
  def copy(destination, sources, options = {})
935
937
  copied = []
@@ -955,6 +957,12 @@ module ActiveRecord
955
957
  magic_comments << magic_comment; ""
956
958
  end || break
957
959
  end
960
+
961
+ if !magic_comments.empty? && source.start_with?("\n")
962
+ magic_comments << "\n"
963
+ source = source[1..-1]
964
+ end
965
+
958
966
  source = "#{magic_comments}#{inserted_comment}#{source}"
959
967
 
960
968
  if duplicate = destination_migrations.detect { |m| m.name == migration.name }
@@ -992,7 +1000,7 @@ module ActiveRecord
992
1000
 
993
1001
  # Determines the version number of the next migration.
994
1002
  def next_migration_number(number)
995
- if ActiveRecord::Base.timestamped_migrations
1003
+ if ActiveRecord.timestamped_migrations
996
1004
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
997
1005
  else
998
1006
  SchemaMigration.normalize_migration_number(number)
@@ -1001,7 +1009,7 @@ module ActiveRecord
1001
1009
 
1002
1010
  # Builds a hash for use in ActiveRecord::Migration#proper_table_name using
1003
1011
  # the Active Record object's table_name prefix and suffix
1004
- def table_name_options(config = ActiveRecord::Base) #:nodoc:
1012
+ def table_name_options(config = ActiveRecord::Base) # :nodoc:
1005
1013
  {
1006
1014
  table_name_prefix: config.table_name_prefix,
1007
1015
  table_name_suffix: config.table_name_suffix
@@ -1042,19 +1050,41 @@ module ActiveRecord
1042
1050
  end
1043
1051
 
1044
1052
  def load_migration
1045
- require(File.expand_path(filename))
1053
+ Object.send(:remove_const, name) rescue nil
1054
+
1055
+ load(File.expand_path(filename))
1046
1056
  name.constantize.new(name, version)
1047
1057
  end
1048
1058
  end
1049
1059
 
1050
- class MigrationContext #:nodoc:
1060
+ # MigrationContext sets the context in which a migration is run.
1061
+ #
1062
+ # A migration context requires the path to the migrations is set
1063
+ # in the +migrations_paths+ parameter. Optionally a +schema_migration+
1064
+ # class can be provided. For most applications, +SchemaMigration+ is
1065
+ # sufficient. Multiple database applications need a +SchemaMigration+
1066
+ # per primary database.
1067
+ class MigrationContext
1051
1068
  attr_reader :migrations_paths, :schema_migration
1052
1069
 
1053
- def initialize(migrations_paths, schema_migration)
1070
+ def initialize(migrations_paths, schema_migration = SchemaMigration)
1054
1071
  @migrations_paths = migrations_paths
1055
1072
  @schema_migration = schema_migration
1056
1073
  end
1057
1074
 
1075
+ # Runs the migrations in the +migrations_path+.
1076
+ #
1077
+ # If +target_version+ is +nil+, +migrate+ will run +up+.
1078
+ #
1079
+ # If the +current_version+ and +target_version+ are both
1080
+ # 0 then an empty array will be returned and no migrations
1081
+ # will be run.
1082
+ #
1083
+ # If the +current_version+ in the schema is less than
1084
+ # the +target_version+, then +down+ will be run.
1085
+ #
1086
+ # If none of the conditions are met, +up+ will be run with
1087
+ # the +target_version+.
1058
1088
  def migrate(target_version = nil, &block)
1059
1089
  case
1060
1090
  when target_version.nil?
@@ -1068,17 +1098,17 @@ module ActiveRecord
1068
1098
  end
1069
1099
  end
1070
1100
 
1071
- def rollback(steps = 1)
1101
+ def rollback(steps = 1) # :nodoc:
1072
1102
  move(:down, steps)
1073
1103
  end
1074
1104
 
1075
- def forward(steps = 1)
1105
+ def forward(steps = 1) # :nodoc:
1076
1106
  move(:up, steps)
1077
1107
  end
1078
1108
 
1079
- def up(target_version = nil)
1109
+ def up(target_version = nil, &block) # :nodoc:
1080
1110
  selected_migrations = if block_given?
1081
- migrations.select { |m| yield m }
1111
+ migrations.select(&block)
1082
1112
  else
1083
1113
  migrations
1084
1114
  end
@@ -1086,9 +1116,9 @@ module ActiveRecord
1086
1116
  Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1087
1117
  end
1088
1118
 
1089
- def down(target_version = nil)
1119
+ def down(target_version = nil, &block) # :nodoc:
1090
1120
  selected_migrations = if block_given?
1091
- migrations.select { |m| yield m }
1121
+ migrations.select(&block)
1092
1122
  else
1093
1123
  migrations
1094
1124
  end
@@ -1096,15 +1126,15 @@ module ActiveRecord
1096
1126
  Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1097
1127
  end
1098
1128
 
1099
- def run(direction, target_version)
1129
+ def run(direction, target_version) # :nodoc:
1100
1130
  Migrator.new(direction, migrations, schema_migration, target_version).run
1101
1131
  end
1102
1132
 
1103
- def open
1133
+ def open # :nodoc:
1104
1134
  Migrator.new(:up, migrations, schema_migration)
1105
1135
  end
1106
1136
 
1107
- def get_all_versions
1137
+ def get_all_versions # :nodoc:
1108
1138
  if schema_migration.table_exists?
1109
1139
  schema_migration.all_versions.map(&:to_i)
1110
1140
  else
@@ -1112,20 +1142,20 @@ module ActiveRecord
1112
1142
  end
1113
1143
  end
1114
1144
 
1115
- def current_version
1145
+ def current_version # :nodoc:
1116
1146
  get_all_versions.max || 0
1117
1147
  rescue ActiveRecord::NoDatabaseError
1118
1148
  end
1119
1149
 
1120
- def needs_migration?
1121
- (migrations.collect(&:version) - get_all_versions).size > 0
1150
+ def needs_migration? # :nodoc:
1151
+ pending_migration_versions.size > 0
1122
1152
  end
1123
1153
 
1124
- def any_migrations?
1125
- migrations.any?
1154
+ def pending_migration_versions # :nodoc:
1155
+ migrations.collect(&:version) - get_all_versions
1126
1156
  end
1127
1157
 
1128
- def migrations
1158
+ def migrations # :nodoc:
1129
1159
  migrations = migration_files.map do |file|
1130
1160
  version, name, scope = parse_migration_filename(file)
1131
1161
  raise IllegalMigrationNameError.new(file) unless version
@@ -1138,33 +1168,33 @@ module ActiveRecord
1138
1168
  migrations.sort_by(&:version)
1139
1169
  end
1140
1170
 
1141
- def migrations_status
1171
+ def migrations_status # :nodoc:
1142
1172
  db_list = schema_migration.normalized_versions
1143
1173
 
1144
- file_list = migration_files.map do |file|
1174
+ file_list = migration_files.filter_map do |file|
1145
1175
  version, name, scope = parse_migration_filename(file)
1146
1176
  raise IllegalMigrationNameError.new(file) unless version
1147
1177
  version = schema_migration.normalize_migration_number(version)
1148
1178
  status = db_list.delete(version) ? "up" : "down"
1149
1179
  [status, version, (name + scope).humanize]
1150
- end.compact
1180
+ end
1151
1181
 
1152
1182
  db_list.map! do |version|
1153
1183
  ["up", version, "********** NO FILE **********"]
1154
1184
  end
1155
1185
 
1156
- (db_list + file_list).sort_by { |_, version, _| version }
1186
+ (db_list + file_list).sort_by { |_, version, _| version.to_i }
1157
1187
  end
1158
1188
 
1159
- def current_environment
1189
+ def current_environment # :nodoc:
1160
1190
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
1161
1191
  end
1162
1192
 
1163
- def protected_environment?
1193
+ def protected_environment? # :nodoc:
1164
1194
  ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
1165
1195
  end
1166
1196
 
1167
- def last_stored_environment
1197
+ def last_stored_environment # :nodoc:
1168
1198
  return nil unless ActiveRecord::InternalMetadata.enabled?
1169
1199
  return nil if current_version == 0
1170
1200
  raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
@@ -1375,9 +1405,9 @@ module ActiveRecord
1375
1405
  end
1376
1406
 
1377
1407
  # Wrap the migration in a transaction only if supported by the adapter.
1378
- def ddl_transaction(migration)
1408
+ def ddl_transaction(migration, &block)
1379
1409
  if use_transaction?(migration)
1380
- Base.transaction { yield }
1410
+ Base.transaction(&block)
1381
1411
  else
1382
1412
  yield
1383
1413
  end
@@ -1408,12 +1438,12 @@ module ActiveRecord
1408
1438
  end
1409
1439
  end
1410
1440
 
1411
- def with_advisory_lock_connection
1441
+ def with_advisory_lock_connection(&block)
1412
1442
  pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
1413
1443
  ActiveRecord::Base.connection_db_config
1414
1444
  )
1415
1445
 
1416
- pool.with_connection { |connection| yield(connection) }
1446
+ pool.with_connection(&block)
1417
1447
  ensure
1418
1448
  pool&.disconnect!
1419
1449
  end