activerecord 6.1.7.6 → 7.0.8

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 (251) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1570 -1016
  3. data/README.rdoc +3 -3
  4. data/lib/active_record/aggregations.rb +1 -1
  5. data/lib/active_record/association_relation.rb +0 -10
  6. data/lib/active_record/associations/association.rb +33 -17
  7. data/lib/active_record/associations/association_scope.rb +1 -3
  8. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  10. data/lib/active_record/associations/builder/association.rb +8 -2
  11. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  12. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  13. data/lib/active_record/associations/builder/has_many.rb +3 -2
  14. data/lib/active_record/associations/builder/has_one.rb +2 -1
  15. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  16. data/lib/active_record/associations/collection_association.rb +20 -22
  17. data/lib/active_record/associations/collection_proxy.rb +15 -5
  18. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  19. data/lib/active_record/associations/has_many_association.rb +8 -5
  20. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  21. data/lib/active_record/associations/has_one_association.rb +10 -7
  22. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  23. data/lib/active_record/associations/join_dependency.rb +23 -15
  24. data/lib/active_record/associations/preloader/association.rb +186 -52
  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 +50 -14
  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 +138 -100
  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 +8 -6
  39. data/lib/active_record/attribute_methods/serialization.rb +57 -19
  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 +19 -22
  43. data/lib/active_record/attributes.rb +24 -35
  44. data/lib/active_record/autosave_association.rb +8 -23
  45. data/lib/active_record/base.rb +19 -1
  46. data/lib/active_record/callbacks.rb +14 -16
  47. data/lib/active_record/coders/yaml_column.rb +4 -8
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +52 -23
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +82 -25
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +144 -82
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +115 -85
  63. data/lib/active_record/connection_adapters/column.rb +4 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +37 -25
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -23
  66. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  68. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  70. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -1
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -17
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  77. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  79. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  80. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  81. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  82. data/lib/active_record/connection_adapters/postgresql/quoting.rb +76 -73
  83. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
  84. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  85. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  86. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  87. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +40 -21
  88. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  89. data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -106
  90. data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
  91. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
  92. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +33 -18
  93. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -0
  94. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +19 -17
  95. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +98 -36
  96. data/lib/active_record/connection_adapters.rb +6 -5
  97. data/lib/active_record/connection_handling.rb +49 -55
  98. data/lib/active_record/core.rb +123 -148
  99. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  100. data/lib/active_record/database_configurations/database_config.rb +12 -9
  101. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  102. data/lib/active_record/database_configurations/url_config.rb +2 -2
  103. data/lib/active_record/database_configurations.rb +15 -32
  104. data/lib/active_record/delegated_type.rb +53 -12
  105. data/lib/active_record/destroy_association_async_job.rb +1 -1
  106. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  107. data/lib/active_record/dynamic_matchers.rb +1 -1
  108. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  109. data/lib/active_record/encryption/cipher.rb +53 -0
  110. data/lib/active_record/encryption/config.rb +44 -0
  111. data/lib/active_record/encryption/configurable.rb +67 -0
  112. data/lib/active_record/encryption/context.rb +35 -0
  113. data/lib/active_record/encryption/contexts.rb +72 -0
  114. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  115. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  116. data/lib/active_record/encryption/encryptable_record.rb +206 -0
  117. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  118. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  119. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  120. data/lib/active_record/encryption/encryptor.rb +155 -0
  121. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  122. data/lib/active_record/encryption/errors.rb +15 -0
  123. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  124. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  125. data/lib/active_record/encryption/key.rb +28 -0
  126. data/lib/active_record/encryption/key_generator.rb +42 -0
  127. data/lib/active_record/encryption/key_provider.rb +46 -0
  128. data/lib/active_record/encryption/message.rb +33 -0
  129. data/lib/active_record/encryption/message_serializer.rb +90 -0
  130. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  131. data/lib/active_record/encryption/properties.rb +76 -0
  132. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  133. data/lib/active_record/encryption/scheme.rb +99 -0
  134. data/lib/active_record/encryption.rb +55 -0
  135. data/lib/active_record/enum.rb +50 -43
  136. data/lib/active_record/errors.rb +67 -4
  137. data/lib/active_record/explain_registry.rb +11 -6
  138. data/lib/active_record/explain_subscriber.rb +1 -1
  139. data/lib/active_record/fixture_set/file.rb +15 -1
  140. data/lib/active_record/fixture_set/table_row.rb +41 -6
  141. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  142. data/lib/active_record/fixtures.rb +20 -23
  143. data/lib/active_record/future_result.rb +139 -0
  144. data/lib/active_record/gem_version.rb +5 -5
  145. data/lib/active_record/inheritance.rb +55 -17
  146. data/lib/active_record/insert_all.rb +80 -14
  147. data/lib/active_record/integration.rb +4 -3
  148. data/lib/active_record/internal_metadata.rb +1 -5
  149. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  150. data/lib/active_record/locking/optimistic.rb +36 -21
  151. data/lib/active_record/locking/pessimistic.rb +10 -4
  152. data/lib/active_record/log_subscriber.rb +23 -7
  153. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  154. data/lib/active_record/middleware/database_selector.rb +18 -6
  155. data/lib/active_record/middleware/shard_selector.rb +60 -0
  156. data/lib/active_record/migration/command_recorder.rb +8 -9
  157. data/lib/active_record/migration/compatibility.rb +93 -46
  158. data/lib/active_record/migration/join_table.rb +1 -1
  159. data/lib/active_record/migration.rb +167 -87
  160. data/lib/active_record/model_schema.rb +58 -59
  161. data/lib/active_record/nested_attributes.rb +13 -12
  162. data/lib/active_record/no_touching.rb +3 -3
  163. data/lib/active_record/null_relation.rb +2 -6
  164. data/lib/active_record/persistence.rb +231 -61
  165. data/lib/active_record/query_cache.rb +2 -2
  166. data/lib/active_record/query_logs.rb +149 -0
  167. data/lib/active_record/querying.rb +16 -6
  168. data/lib/active_record/railtie.rb +136 -22
  169. data/lib/active_record/railties/controller_runtime.rb +4 -5
  170. data/lib/active_record/railties/databases.rake +78 -136
  171. data/lib/active_record/readonly_attributes.rb +11 -0
  172. data/lib/active_record/reflection.rb +80 -49
  173. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  174. data/lib/active_record/relation/batches.rb +6 -6
  175. data/lib/active_record/relation/calculations.rb +92 -60
  176. data/lib/active_record/relation/delegation.rb +7 -7
  177. data/lib/active_record/relation/finder_methods.rb +31 -35
  178. data/lib/active_record/relation/merger.rb +20 -13
  179. data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
  180. data/lib/active_record/relation/predicate_builder.rb +1 -6
  181. data/lib/active_record/relation/query_attribute.rb +28 -11
  182. data/lib/active_record/relation/query_methods.rb +304 -68
  183. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  184. data/lib/active_record/relation/spawn_methods.rb +2 -2
  185. data/lib/active_record/relation/where_clause.rb +10 -19
  186. data/lib/active_record/relation.rb +189 -88
  187. data/lib/active_record/result.rb +23 -11
  188. data/lib/active_record/runtime_registry.rb +9 -13
  189. data/lib/active_record/sanitization.rb +17 -12
  190. data/lib/active_record/schema.rb +38 -23
  191. data/lib/active_record/schema_dumper.rb +29 -19
  192. data/lib/active_record/schema_migration.rb +4 -4
  193. data/lib/active_record/scoping/default.rb +60 -13
  194. data/lib/active_record/scoping/named.rb +3 -11
  195. data/lib/active_record/scoping.rb +64 -34
  196. data/lib/active_record/serialization.rb +6 -1
  197. data/lib/active_record/signed_id.rb +3 -3
  198. data/lib/active_record/store.rb +2 -2
  199. data/lib/active_record/suppressor.rb +11 -15
  200. data/lib/active_record/table_metadata.rb +6 -2
  201. data/lib/active_record/tasks/database_tasks.rb +127 -60
  202. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  203. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
  204. data/lib/active_record/test_databases.rb +1 -1
  205. data/lib/active_record/test_fixtures.rb +9 -6
  206. data/lib/active_record/timestamp.rb +3 -4
  207. data/lib/active_record/transactions.rb +12 -17
  208. data/lib/active_record/translation.rb +3 -3
  209. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  210. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  211. data/lib/active_record/type/internal/timezone.rb +2 -2
  212. data/lib/active_record/type/serialized.rb +9 -5
  213. data/lib/active_record/type/type_map.rb +17 -20
  214. data/lib/active_record/type.rb +1 -2
  215. data/lib/active_record/validations/associated.rb +4 -4
  216. data/lib/active_record/validations/presence.rb +2 -2
  217. data/lib/active_record/validations/uniqueness.rb +4 -4
  218. data/lib/active_record/version.rb +1 -1
  219. data/lib/active_record.rb +225 -27
  220. data/lib/arel/attributes/attribute.rb +0 -8
  221. data/lib/arel/crud.rb +28 -22
  222. data/lib/arel/delete_manager.rb +18 -4
  223. data/lib/arel/filter_predications.rb +9 -0
  224. data/lib/arel/insert_manager.rb +2 -3
  225. data/lib/arel/nodes/and.rb +4 -0
  226. data/lib/arel/nodes/casted.rb +1 -1
  227. data/lib/arel/nodes/delete_statement.rb +12 -13
  228. data/lib/arel/nodes/filter.rb +10 -0
  229. data/lib/arel/nodes/function.rb +1 -0
  230. data/lib/arel/nodes/insert_statement.rb +2 -2
  231. data/lib/arel/nodes/select_core.rb +2 -2
  232. data/lib/arel/nodes/select_statement.rb +2 -2
  233. data/lib/arel/nodes/update_statement.rb +8 -3
  234. data/lib/arel/nodes.rb +1 -0
  235. data/lib/arel/predications.rb +11 -3
  236. data/lib/arel/select_manager.rb +10 -4
  237. data/lib/arel/table.rb +0 -1
  238. data/lib/arel/tree_manager.rb +0 -12
  239. data/lib/arel/update_manager.rb +18 -4
  240. data/lib/arel/visitors/dot.rb +80 -90
  241. data/lib/arel/visitors/mysql.rb +8 -2
  242. data/lib/arel/visitors/postgresql.rb +0 -10
  243. data/lib/arel/visitors/to_sql.rb +58 -2
  244. data/lib/arel.rb +2 -1
  245. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  246. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  247. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  248. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  249. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  250. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  251. metadata +55 -11
@@ -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
@@ -326,7 +326,7 @@ module ActiveRecord
326
326
  # details.
327
327
  # * <tt>change_table(name, options)</tt>: Allows to make column alterations to
328
328
  # the table called +name+. It makes the table object available to a block that
329
- # can then add/remove columns, indexes or foreign keys to it.
329
+ # can then add/remove columns, indexes, or foreign keys to it.
330
330
  # * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames
331
331
  # a column but keeps the type and content.
332
332
  # * <tt>rename_index(table_name, old_name, new_name)</tt>: Renames an index.
@@ -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,53 @@ 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
+ def create_table(table_name, **options)
555
+ if block_given?
556
+ super { |t| yield compatible_table_definition(t) }
557
+ else
558
+ super
559
+ end
560
+ end
561
+
562
+ def change_table(table_name, **options)
563
+ if block_given?
564
+ super { |t| yield compatible_table_definition(t) }
565
+ else
566
+ super
567
+ end
568
+ end
569
+
570
+ def create_join_table(table_1, table_2, **options)
571
+ if block_given?
572
+ super { |t| yield compatible_table_definition(t) }
573
+ else
574
+ super
575
+ end
576
+ end
577
+
578
+ def drop_table(table_name, **options)
579
+ if block_given?
580
+ super { |t| yield compatible_table_definition(t) }
581
+ else
582
+ super
583
+ end
584
+ end
585
+
586
+ def compatible_table_definition(t)
587
+ t
588
+ end
554
589
  end
555
590
 
556
- def self.inherited(subclass) #:nodoc:
591
+ def self.inherited(subclass) # :nodoc:
557
592
  super
558
593
  if subclass.superclass == Migration
594
+ major = ActiveRecord::VERSION::MAJOR
595
+ minor = ActiveRecord::VERSION::MINOR
559
596
  raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
560
- "Please specify the Rails release the migration was written for:\n" \
597
+ "Please specify the Active Record release the migration was written for:\n" \
561
598
  "\n" \
562
- " class #{subclass} < ActiveRecord::Migration[4.2]"
599
+ " class #{subclass} < ActiveRecord::Migration[#{major}.#{minor}]"
563
600
  end
564
601
  end
565
602
 
@@ -571,10 +608,10 @@ module ActiveRecord
571
608
  ActiveRecord::VERSION::STRING.to_f
572
609
  end
573
610
 
574
- MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ #:nodoc:
611
+ MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
575
612
 
576
613
  # This class is used to verify that all migrations have been run before
577
- # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
614
+ # loading a web page if <tt>config.active_record.migration_error</tt> is set to +:page_load+.
578
615
  class CheckPending
579
616
  def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
580
617
  @app = app
@@ -613,10 +650,10 @@ module ActiveRecord
613
650
  end
614
651
 
615
652
  class << self
616
- attr_accessor :delegate #:nodoc:
617
- attr_accessor :disable_ddl_transaction #:nodoc:
653
+ attr_accessor :delegate # :nodoc:
654
+ attr_accessor :disable_ddl_transaction # :nodoc:
618
655
 
619
- def nearest_delegate #:nodoc:
656
+ def nearest_delegate # :nodoc:
620
657
  delegate || superclass.nearest_delegate
621
658
  end
622
659
 
@@ -630,7 +667,7 @@ module ActiveRecord
630
667
  all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
631
668
 
632
669
  needs_update = !all_configs.all? do |db_config|
633
- Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord::Base.schema_format)
670
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord.schema_format)
634
671
  end
635
672
 
636
673
  if needs_update
@@ -648,16 +685,16 @@ module ActiveRecord
648
685
  check_pending!
649
686
  end
650
687
 
651
- def maintain_test_schema! #:nodoc:
652
- if ActiveRecord::Base.maintain_test_schema
688
+ def maintain_test_schema! # :nodoc:
689
+ if ActiveRecord.maintain_test_schema
653
690
  suppress_messages { load_schema_if_pending! }
654
691
  end
655
692
  end
656
693
 
657
- def method_missing(name, *args, &block) #:nodoc:
694
+ def method_missing(name, *args, &block) # :nodoc:
658
695
  nearest_delegate.send(name, *args, &block)
659
696
  end
660
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
697
+ ruby2_keywords(:method_missing)
661
698
 
662
699
  def migrate(direction)
663
700
  new.migrate direction
@@ -672,7 +709,7 @@ module ActiveRecord
672
709
  end
673
710
  end
674
711
 
675
- def disable_ddl_transaction #:nodoc:
712
+ def disable_ddl_transaction # :nodoc:
676
713
  self.class.disable_ddl_transaction
677
714
  end
678
715
 
@@ -696,7 +733,7 @@ module ActiveRecord
696
733
  # and create the table 'apples' on the way up, and the reverse
697
734
  # on the way down.
698
735
  #
699
- # class FixTLMigration < ActiveRecord::Migration[6.0]
736
+ # class FixTLMigration < ActiveRecord::Migration[7.0]
700
737
  # def change
701
738
  # revert do
702
739
  # create_table(:horses) do |t|
@@ -715,7 +752,7 @@ module ActiveRecord
715
752
  #
716
753
  # require_relative "20121212123456_tenderlove_migration"
717
754
  #
718
- # class FixupTLMigration < ActiveRecord::Migration[6.0]
755
+ # class FixupTLMigration < ActiveRecord::Migration[7.0]
719
756
  # def change
720
757
  # revert TenderloveMigration
721
758
  #
@@ -726,16 +763,16 @@ module ActiveRecord
726
763
  # end
727
764
  #
728
765
  # This command can be nested.
729
- def revert(*migration_classes)
766
+ def revert(*migration_classes, &block)
730
767
  run(*migration_classes.reverse, revert: true) unless migration_classes.empty?
731
768
  if block_given?
732
769
  if connection.respond_to? :revert
733
- connection.revert { yield }
770
+ connection.revert(&block)
734
771
  else
735
772
  recorder = command_recorder
736
773
  @connection = recorder
737
774
  suppress_messages do
738
- connection.revert { yield }
775
+ connection.revert(&block)
739
776
  end
740
777
  @connection = recorder.delegate
741
778
  recorder.replay(self)
@@ -747,7 +784,7 @@ module ActiveRecord
747
784
  connection.respond_to?(:reverting) && connection.reverting
748
785
  end
749
786
 
750
- ReversibleBlockHelper = Struct.new(:reverting) do #:nodoc:
787
+ ReversibleBlockHelper = Struct.new(:reverting) do # :nodoc:
751
788
  def up
752
789
  yield unless reverting
753
790
  end
@@ -766,7 +803,7 @@ module ActiveRecord
766
803
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
767
804
  # even when migrating down:
768
805
  #
769
- # class SplitNameMigration < ActiveRecord::Migration[6.0]
806
+ # class SplitNameMigration < ActiveRecord::Migration[7.0]
770
807
  # def change
771
808
  # add_column :users, :first_name, :string
772
809
  # add_column :users, :last_name, :string
@@ -794,7 +831,7 @@ module ActiveRecord
794
831
  # In the following example, the new column +published+ will be given
795
832
  # the value +true+ for all existing records.
796
833
  #
797
- # class AddPublishedToPosts < ActiveRecord::Migration[6.0]
834
+ # class AddPublishedToPosts < ActiveRecord::Migration[7.0]
798
835
  # def change
799
836
  # add_column :posts, :published, :boolean, default: false
800
837
  # up_only do
@@ -802,14 +839,15 @@ module ActiveRecord
802
839
  # end
803
840
  # end
804
841
  # end
805
- def up_only
806
- execute_block { yield } unless reverting?
842
+ def up_only(&block)
843
+ execute_block(&block) unless reverting?
807
844
  end
808
845
 
809
846
  # Runs the given migration classes.
810
847
  # Last argument can specify options:
811
- # - :direction (default is :up)
812
- # - :revert (default is false)
848
+ #
849
+ # - +:direction+ - Default is +:up+.
850
+ # - +:revert+ - Default is +false+.
813
851
  def run(*migration_classes)
814
852
  opts = migration_classes.extract_options!
815
853
  dir = opts[:direction] || :up
@@ -913,13 +951,11 @@ module ActiveRecord
913
951
  end
914
952
 
915
953
  def method_missing(method, *arguments, &block)
916
- arg_list = arguments.map(&:inspect) * ", "
917
-
918
- say_with_time "#{method}(#{arg_list})" do
954
+ say_with_time "#{method}(#{format_arguments(arguments)})" do
919
955
  unless connection.respond_to? :revert
920
956
  unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
921
957
  arguments[0] = proper_table_name(arguments.first, table_name_options)
922
- if [:rename_table, :add_foreign_key].include?(method) ||
958
+ if method == :rename_table ||
923
959
  (method == :remove_foreign_key && !arguments.second.is_a?(Hash))
924
960
  arguments[1] = proper_table_name(arguments.second, table_name_options)
925
961
  end
@@ -929,7 +965,7 @@ module ActiveRecord
929
965
  connection.send(method, *arguments, &block)
930
966
  end
931
967
  end
932
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
968
+ ruby2_keywords(:method_missing)
933
969
 
934
970
  def copy(destination, sources, options = {})
935
971
  copied = []
@@ -955,6 +991,12 @@ module ActiveRecord
955
991
  magic_comments << magic_comment; ""
956
992
  end || break
957
993
  end
994
+
995
+ if !magic_comments.empty? && source.start_with?("\n")
996
+ magic_comments << "\n"
997
+ source = source[1..-1]
998
+ end
999
+
958
1000
  source = "#{magic_comments}#{inserted_comment}#{source}"
959
1001
 
960
1002
  if duplicate = destination_migrations.detect { |m| m.name == migration.name }
@@ -992,7 +1034,7 @@ module ActiveRecord
992
1034
 
993
1035
  # Determines the version number of the next migration.
994
1036
  def next_migration_number(number)
995
- if ActiveRecord::Base.timestamped_migrations
1037
+ if ActiveRecord.timestamped_migrations
996
1038
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
997
1039
  else
998
1040
  SchemaMigration.normalize_migration_number(number)
@@ -1001,7 +1043,7 @@ module ActiveRecord
1001
1043
 
1002
1044
  # Builds a hash for use in ActiveRecord::Migration#proper_table_name using
1003
1045
  # the Active Record object's table_name prefix and suffix
1004
- def table_name_options(config = ActiveRecord::Base) #:nodoc:
1046
+ def table_name_options(config = ActiveRecord::Base) # :nodoc:
1005
1047
  {
1006
1048
  table_name_prefix: config.table_name_prefix,
1007
1049
  table_name_suffix: config.table_name_suffix
@@ -1017,6 +1059,22 @@ module ActiveRecord
1017
1059
  end
1018
1060
  end
1019
1061
 
1062
+ def format_arguments(arguments)
1063
+ arg_list = arguments[0...-1].map(&:inspect)
1064
+ last_arg = arguments.last
1065
+ if last_arg.is_a?(Hash)
1066
+ last_arg = last_arg.reject { |k, _v| internal_option?(k) }
1067
+ arg_list << last_arg.inspect unless last_arg.empty?
1068
+ else
1069
+ arg_list << last_arg.inspect
1070
+ end
1071
+ arg_list.join(", ")
1072
+ end
1073
+
1074
+ def internal_option?(option_name)
1075
+ option_name.start_with?("_")
1076
+ end
1077
+
1020
1078
  def command_recorder
1021
1079
  CommandRecorder.new(connection)
1022
1080
  end
@@ -1042,19 +1100,41 @@ module ActiveRecord
1042
1100
  end
1043
1101
 
1044
1102
  def load_migration
1045
- require(File.expand_path(filename))
1103
+ Object.send(:remove_const, name) rescue nil
1104
+
1105
+ load(File.expand_path(filename))
1046
1106
  name.constantize.new(name, version)
1047
1107
  end
1048
1108
  end
1049
1109
 
1050
- class MigrationContext #:nodoc:
1110
+ # MigrationContext sets the context in which a migration is run.
1111
+ #
1112
+ # A migration context requires the path to the migrations is set
1113
+ # in the +migrations_paths+ parameter. Optionally a +schema_migration+
1114
+ # class can be provided. For most applications, +SchemaMigration+ is
1115
+ # sufficient. Multiple database applications need a +SchemaMigration+
1116
+ # per primary database.
1117
+ class MigrationContext
1051
1118
  attr_reader :migrations_paths, :schema_migration
1052
1119
 
1053
- def initialize(migrations_paths, schema_migration)
1120
+ def initialize(migrations_paths, schema_migration = SchemaMigration)
1054
1121
  @migrations_paths = migrations_paths
1055
1122
  @schema_migration = schema_migration
1056
1123
  end
1057
1124
 
1125
+ # Runs the migrations in the +migrations_path+.
1126
+ #
1127
+ # If +target_version+ is +nil+, +migrate+ will run +up+.
1128
+ #
1129
+ # If the +current_version+ and +target_version+ are both
1130
+ # 0 then an empty array will be returned and no migrations
1131
+ # will be run.
1132
+ #
1133
+ # If the +current_version+ in the schema is greater than
1134
+ # the +target_version+, then +down+ will be run.
1135
+ #
1136
+ # If none of the conditions are met, +up+ will be run with
1137
+ # the +target_version+.
1058
1138
  def migrate(target_version = nil, &block)
1059
1139
  case
1060
1140
  when target_version.nil?
@@ -1068,17 +1148,17 @@ module ActiveRecord
1068
1148
  end
1069
1149
  end
1070
1150
 
1071
- def rollback(steps = 1)
1151
+ def rollback(steps = 1) # :nodoc:
1072
1152
  move(:down, steps)
1073
1153
  end
1074
1154
 
1075
- def forward(steps = 1)
1155
+ def forward(steps = 1) # :nodoc:
1076
1156
  move(:up, steps)
1077
1157
  end
1078
1158
 
1079
- def up(target_version = nil)
1159
+ def up(target_version = nil, &block) # :nodoc:
1080
1160
  selected_migrations = if block_given?
1081
- migrations.select { |m| yield m }
1161
+ migrations.select(&block)
1082
1162
  else
1083
1163
  migrations
1084
1164
  end
@@ -1086,9 +1166,9 @@ module ActiveRecord
1086
1166
  Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1087
1167
  end
1088
1168
 
1089
- def down(target_version = nil)
1169
+ def down(target_version = nil, &block) # :nodoc:
1090
1170
  selected_migrations = if block_given?
1091
- migrations.select { |m| yield m }
1171
+ migrations.select(&block)
1092
1172
  else
1093
1173
  migrations
1094
1174
  end
@@ -1096,15 +1176,15 @@ module ActiveRecord
1096
1176
  Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1097
1177
  end
1098
1178
 
1099
- def run(direction, target_version)
1179
+ def run(direction, target_version) # :nodoc:
1100
1180
  Migrator.new(direction, migrations, schema_migration, target_version).run
1101
1181
  end
1102
1182
 
1103
- def open
1183
+ def open # :nodoc:
1104
1184
  Migrator.new(:up, migrations, schema_migration)
1105
1185
  end
1106
1186
 
1107
- def get_all_versions
1187
+ def get_all_versions # :nodoc:
1108
1188
  if schema_migration.table_exists?
1109
1189
  schema_migration.all_versions.map(&:to_i)
1110
1190
  else
@@ -1112,20 +1192,20 @@ module ActiveRecord
1112
1192
  end
1113
1193
  end
1114
1194
 
1115
- def current_version
1195
+ def current_version # :nodoc:
1116
1196
  get_all_versions.max || 0
1117
1197
  rescue ActiveRecord::NoDatabaseError
1118
1198
  end
1119
1199
 
1120
- def needs_migration?
1121
- (migrations.collect(&:version) - get_all_versions).size > 0
1200
+ def needs_migration? # :nodoc:
1201
+ pending_migration_versions.size > 0
1122
1202
  end
1123
1203
 
1124
- def any_migrations?
1125
- migrations.any?
1204
+ def pending_migration_versions # :nodoc:
1205
+ migrations.collect(&:version) - get_all_versions
1126
1206
  end
1127
1207
 
1128
- def migrations
1208
+ def migrations # :nodoc:
1129
1209
  migrations = migration_files.map do |file|
1130
1210
  version, name, scope = parse_migration_filename(file)
1131
1211
  raise IllegalMigrationNameError.new(file) unless version
@@ -1138,33 +1218,33 @@ module ActiveRecord
1138
1218
  migrations.sort_by(&:version)
1139
1219
  end
1140
1220
 
1141
- def migrations_status
1221
+ def migrations_status # :nodoc:
1142
1222
  db_list = schema_migration.normalized_versions
1143
1223
 
1144
- file_list = migration_files.map do |file|
1224
+ file_list = migration_files.filter_map do |file|
1145
1225
  version, name, scope = parse_migration_filename(file)
1146
1226
  raise IllegalMigrationNameError.new(file) unless version
1147
1227
  version = schema_migration.normalize_migration_number(version)
1148
1228
  status = db_list.delete(version) ? "up" : "down"
1149
1229
  [status, version, (name + scope).humanize]
1150
- end.compact
1230
+ end
1151
1231
 
1152
1232
  db_list.map! do |version|
1153
1233
  ["up", version, "********** NO FILE **********"]
1154
1234
  end
1155
1235
 
1156
- (db_list + file_list).sort_by { |_, version, _| version }
1236
+ (db_list + file_list).sort_by { |_, version, _| version.to_i }
1157
1237
  end
1158
1238
 
1159
- def current_environment
1239
+ def current_environment # :nodoc:
1160
1240
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
1161
1241
  end
1162
1242
 
1163
- def protected_environment?
1243
+ def protected_environment? # :nodoc:
1164
1244
  ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
1165
1245
  end
1166
1246
 
1167
- def last_stored_environment
1247
+ def last_stored_environment # :nodoc:
1168
1248
  return nil unless ActiveRecord::InternalMetadata.enabled?
1169
1249
  return nil if current_version == 0
1170
1250
  raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
@@ -1307,7 +1387,7 @@ module ActiveRecord
1307
1387
  # Stores the current environment in the database.
1308
1388
  def record_environment
1309
1389
  return if down?
1310
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.migration_context.current_environment
1390
+ ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.pool.db_config.env_name
1311
1391
  end
1312
1392
 
1313
1393
  def ran?(migration)
@@ -1375,9 +1455,9 @@ module ActiveRecord
1375
1455
  end
1376
1456
 
1377
1457
  # Wrap the migration in a transaction only if supported by the adapter.
1378
- def ddl_transaction(migration)
1458
+ def ddl_transaction(migration, &block)
1379
1459
  if use_transaction?(migration)
1380
- Base.transaction { yield }
1460
+ Base.transaction(&block)
1381
1461
  else
1382
1462
  yield
1383
1463
  end
@@ -1408,12 +1488,12 @@ module ActiveRecord
1408
1488
  end
1409
1489
  end
1410
1490
 
1411
- def with_advisory_lock_connection
1491
+ def with_advisory_lock_connection(&block)
1412
1492
  pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
1413
1493
  ActiveRecord::Base.connection_db_config
1414
1494
  )
1415
1495
 
1416
- pool.with_connection { |connection| yield(connection) }
1496
+ pool.with_connection(&block)
1417
1497
  ensure
1418
1498
  pool&.disconnect!
1419
1499
  end