activerecord 6.0.6.1 → 6.1.0

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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +782 -928
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +22 -14
  7. data/lib/active_record/associations/alias_tracker.rb +19 -15
  8. data/lib/active_record/associations/association.rb +43 -26
  9. data/lib/active_record/associations/association_scope.rb +11 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  12. data/lib/active_record/associations/builder/association.rb +9 -3
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +19 -13
  20. data/lib/active_record/associations/collection_proxy.rb +12 -5
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -2
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +29 -14
  26. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +63 -49
  28. data/lib/active_record/associations/preloader/association.rb +13 -5
  29. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  30. data/lib/active_record/associations/preloader.rb +5 -3
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations.rb +114 -11
  33. data/lib/active_record/attribute_assignment.rb +10 -8
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  35. data/lib/active_record/attribute_methods/dirty.rb +1 -11
  36. data/lib/active_record/attribute_methods/primary_key.rb +6 -2
  37. data/lib/active_record/attribute_methods/query.rb +3 -6
  38. data/lib/active_record/attribute_methods/read.rb +8 -11
  39. data/lib/active_record/attribute_methods/serialization.rb +11 -5
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
  41. data/lib/active_record/attribute_methods/write.rb +12 -20
  42. data/lib/active_record/attribute_methods.rb +64 -54
  43. data/lib/active_record/attributes.rb +32 -7
  44. data/lib/active_record/autosave_association.rb +47 -30
  45. data/lib/active_record/base.rb +2 -14
  46. data/lib/active_record/callbacks.rb +152 -22
  47. data/lib/active_record/coders/yaml_column.rb +2 -24
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +185 -134
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +35 -44
  53. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +110 -30
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +80 -32
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +49 -72
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
  61. data/lib/active_record/connection_adapters/column.rb +15 -1
  62. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  63. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -24
  65. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
  68. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  69. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  70. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
  71. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
  73. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  74. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  75. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -53
  77. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  78. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  80. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  88. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  91. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
  93. data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
  94. data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
  95. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
  96. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  97. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  98. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  99. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  100. data/lib/active_record/connection_adapters.rb +50 -0
  101. data/lib/active_record/connection_handling.rb +210 -71
  102. data/lib/active_record/core.rb +223 -66
  103. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  104. data/lib/active_record/database_configurations/database_config.rb +52 -9
  105. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  106. data/lib/active_record/database_configurations/url_config.rb +15 -40
  107. data/lib/active_record/database_configurations.rb +124 -85
  108. data/lib/active_record/delegated_type.rb +209 -0
  109. data/lib/active_record/destroy_association_async_job.rb +36 -0
  110. data/lib/active_record/enum.rb +27 -10
  111. data/lib/active_record/errors.rb +47 -12
  112. data/lib/active_record/explain.rb +9 -4
  113. data/lib/active_record/explain_subscriber.rb +1 -1
  114. data/lib/active_record/fixture_set/file.rb +10 -17
  115. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  116. data/lib/active_record/fixture_set/render_context.rb +1 -1
  117. data/lib/active_record/fixture_set/table_row.rb +2 -2
  118. data/lib/active_record/fixtures.rb +54 -8
  119. data/lib/active_record/gem_version.rb +3 -3
  120. data/lib/active_record/inheritance.rb +40 -18
  121. data/lib/active_record/insert_all.rb +34 -5
  122. data/lib/active_record/integration.rb +3 -5
  123. data/lib/active_record/internal_metadata.rb +16 -7
  124. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  125. data/lib/active_record/locking/optimistic.rb +13 -16
  126. data/lib/active_record/locking/pessimistic.rb +6 -2
  127. data/lib/active_record/log_subscriber.rb +26 -8
  128. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  129. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  130. data/lib/active_record/middleware/database_selector.rb +4 -1
  131. data/lib/active_record/migration/command_recorder.rb +47 -27
  132. data/lib/active_record/migration/compatibility.rb +67 -17
  133. data/lib/active_record/migration.rb +113 -83
  134. data/lib/active_record/model_schema.rb +88 -13
  135. data/lib/active_record/nested_attributes.rb +2 -3
  136. data/lib/active_record/no_touching.rb +1 -1
  137. data/lib/active_record/persistence.rb +50 -45
  138. data/lib/active_record/query_cache.rb +15 -5
  139. data/lib/active_record/querying.rb +11 -6
  140. data/lib/active_record/railtie.rb +64 -44
  141. data/lib/active_record/railties/databases.rake +266 -95
  142. data/lib/active_record/readonly_attributes.rb +4 -0
  143. data/lib/active_record/reflection.rb +60 -44
  144. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  145. data/lib/active_record/relation/batches.rb +38 -31
  146. data/lib/active_record/relation/calculations.rb +100 -43
  147. data/lib/active_record/relation/finder_methods.rb +44 -14
  148. data/lib/active_record/relation/from_clause.rb +1 -1
  149. data/lib/active_record/relation/merger.rb +20 -23
  150. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  151. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  152. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
  153. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  154. data/lib/active_record/relation/predicate_builder.rb +57 -33
  155. data/lib/active_record/relation/query_methods.rb +318 -197
  156. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  157. data/lib/active_record/relation/spawn_methods.rb +8 -7
  158. data/lib/active_record/relation/where_clause.rb +104 -57
  159. data/lib/active_record/relation.rb +90 -64
  160. data/lib/active_record/result.rb +41 -33
  161. data/lib/active_record/runtime_registry.rb +2 -2
  162. data/lib/active_record/sanitization.rb +6 -17
  163. data/lib/active_record/schema_dumper.rb +34 -4
  164. data/lib/active_record/schema_migration.rb +2 -8
  165. data/lib/active_record/scoping/named.rb +1 -17
  166. data/lib/active_record/secure_token.rb +16 -8
  167. data/lib/active_record/serialization.rb +5 -3
  168. data/lib/active_record/signed_id.rb +116 -0
  169. data/lib/active_record/statement_cache.rb +20 -4
  170. data/lib/active_record/store.rb +2 -2
  171. data/lib/active_record/suppressor.rb +2 -2
  172. data/lib/active_record/table_metadata.rb +39 -51
  173. data/lib/active_record/tasks/database_tasks.rb +139 -113
  174. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  175. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  176. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  177. data/lib/active_record/test_databases.rb +5 -4
  178. data/lib/active_record/test_fixtures.rb +36 -33
  179. data/lib/active_record/timestamp.rb +4 -6
  180. data/lib/active_record/touch_later.rb +21 -21
  181. data/lib/active_record/transactions.rb +15 -64
  182. data/lib/active_record/type/serialized.rb +6 -2
  183. data/lib/active_record/type.rb +8 -1
  184. data/lib/active_record/type_caster/connection.rb +0 -1
  185. data/lib/active_record/type_caster/map.rb +8 -5
  186. data/lib/active_record/validations/associated.rb +1 -1
  187. data/lib/active_record/validations/numericality.rb +35 -0
  188. data/lib/active_record/validations/uniqueness.rb +24 -4
  189. data/lib/active_record/validations.rb +1 -0
  190. data/lib/active_record.rb +7 -14
  191. data/lib/arel/attributes/attribute.rb +4 -0
  192. data/lib/arel/collectors/bind.rb +5 -0
  193. data/lib/arel/collectors/composite.rb +8 -0
  194. data/lib/arel/collectors/sql_string.rb +7 -0
  195. data/lib/arel/collectors/substitute_binds.rb +7 -0
  196. data/lib/arel/nodes/binary.rb +82 -8
  197. data/lib/arel/nodes/bind_param.rb +8 -0
  198. data/lib/arel/nodes/casted.rb +21 -9
  199. data/lib/arel/nodes/equality.rb +6 -9
  200. data/lib/arel/nodes/grouping.rb +3 -0
  201. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  202. data/lib/arel/nodes/in.rb +8 -1
  203. data/lib/arel/nodes/infix_operation.rb +13 -1
  204. data/lib/arel/nodes/join_source.rb +1 -1
  205. data/lib/arel/nodes/node.rb +7 -6
  206. data/lib/arel/nodes/ordering.rb +27 -0
  207. data/lib/arel/nodes/sql_literal.rb +3 -0
  208. data/lib/arel/nodes/table_alias.rb +7 -3
  209. data/lib/arel/nodes/unary.rb +0 -1
  210. data/lib/arel/nodes.rb +3 -1
  211. data/lib/arel/predications.rb +12 -18
  212. data/lib/arel/select_manager.rb +1 -2
  213. data/lib/arel/table.rb +13 -5
  214. data/lib/arel/visitors/dot.rb +14 -2
  215. data/lib/arel/visitors/mysql.rb +11 -1
  216. data/lib/arel/visitors/postgresql.rb +15 -4
  217. data/lib/arel/visitors/to_sql.rb +89 -78
  218. data/lib/arel/visitors.rb +0 -7
  219. data/lib/arel.rb +5 -13
  220. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  221. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  222. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  223. data/lib/rails/generators/active_record/migration.rb +6 -1
  224. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  225. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  226. metadata +28 -30
  227. data/lib/active_record/advisory_lock_base.rb +0 -18
  228. data/lib/active_record/attribute_decorators.rb +0 -88
  229. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  230. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  231. data/lib/active_record/define_callbacks.rb +0 -22
  232. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  233. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  234. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  235. data/lib/arel/attributes.rb +0 -22
  236. data/lib/arel/visitors/depth_first.rb +0 -203
  237. data/lib/arel/visitors/ibm_db.rb +0 -34
  238. data/lib/arel/visitors/informix.rb +0 -62
  239. data/lib/arel/visitors/mssql.rb +0 -156
  240. data/lib/arel/visitors/oracle.rb +0 -158
  241. data/lib/arel/visitors/oracle12.rb +0 -65
  242. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -3,6 +3,8 @@
3
3
  require "benchmark"
4
4
  require "set"
5
5
  require "zlib"
6
+ require "active_support/core_ext/array/access"
7
+ require "active_support/core_ext/enumerable"
6
8
  require "active_support/core_ext/module/attribute_accessors"
7
9
  require "active_support/actionable_error"
8
10
 
@@ -18,7 +20,7 @@ module ActiveRecord
18
20
  # For example the following migration is not reversible.
19
21
  # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
20
22
  #
21
- # class IrreversibleMigrationExample < ActiveRecord::Migration[5.0]
23
+ # class IrreversibleMigrationExample < ActiveRecord::Migration[6.0]
22
24
  # def change
23
25
  # create_table :distributors do |t|
24
26
  # t.string :zipcode
@@ -36,7 +38,7 @@ module ActiveRecord
36
38
  #
37
39
  # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
38
40
  #
39
- # class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
41
+ # class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
40
42
  # def up
41
43
  # create_table :distributors do |t|
42
44
  # t.string :zipcode
@@ -61,7 +63,7 @@ module ActiveRecord
61
63
  #
62
64
  # 2. Use the #reversible method in <tt>#change</tt> method:
63
65
  #
64
- # class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
66
+ # class ReversibleMigrationExample < ActiveRecord::Migration[6.0]
65
67
  # def change
66
68
  # create_table :distributors do |t|
67
69
  # t.string :zipcode
@@ -133,17 +135,34 @@ module ActiveRecord
133
135
 
134
136
  action "Run pending migrations" do
135
137
  ActiveRecord::Tasks::DatabaseTasks.migrate
138
+
139
+ if ActiveRecord::Base.dump_schema_after_migration
140
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(
141
+ ActiveRecord::Base.connection_db_config
142
+ )
143
+ end
136
144
  end
137
145
 
138
146
  def initialize(message = nil)
139
- if !message && defined?(Rails.env)
140
- super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate RAILS_ENV=#{::Rails.env}")
141
- elsif !message
142
- super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate")
143
- else
144
- super
145
- end
147
+ super(message || detailed_migration_message)
146
148
  end
149
+
150
+ private
151
+ def detailed_migration_message
152
+ message = "Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate"
153
+ message += " RAILS_ENV=#{::Rails.env}" if defined?(Rails.env)
154
+ message += "\n\n"
155
+
156
+ pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
157
+
158
+ message += "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}\n\n"
159
+
160
+ pending_migrations.each do |pending_migration|
161
+ message += "#{pending_migration.basename}\n"
162
+ end
163
+
164
+ message
165
+ end
147
166
  end
148
167
 
149
168
  class ConcurrentMigrationError < MigrationError #:nodoc:
@@ -157,7 +176,7 @@ module ActiveRecord
157
176
 
158
177
  class NoEnvironmentInSchemaError < MigrationError #:nodoc:
159
178
  def initialize
160
- msg = "Environment data not found in the schema. To resolve this issue, run: \n\n rails db:environment:set"
179
+ msg = "Environment data not found in the schema. To resolve this issue, run: \n\n bin/rails db:environment:set"
161
180
  if defined?(Rails.env)
162
181
  super("#{msg} RAILS_ENV=#{::Rails.env}")
163
182
  else
@@ -180,7 +199,7 @@ module ActiveRecord
180
199
  msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
181
200
  msg << "You are running in `#{ current }` environment. "
182
201
  msg << "If you are sure you want to continue, first set the environment using:\n\n"
183
- msg << " rails db:environment:set"
202
+ msg << " bin/rails db:environment:set"
184
203
  if defined?(Rails.env)
185
204
  super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
186
205
  else
@@ -189,6 +208,14 @@ module ActiveRecord
189
208
  end
190
209
  end
191
210
 
211
+ class EnvironmentStorageError < ActiveRecordError # :nodoc:
212
+ def initialize
213
+ msg = +"You are attempting to store the environment in a database where metadata is disabled.\n"
214
+ msg << "Check your database configuration to see if this is intended."
215
+ super(msg)
216
+ end
217
+ end
218
+
192
219
  # = Active Record Migrations
193
220
  #
194
221
  # Migrations can manage the evolution of a schema used by several physical
@@ -201,7 +228,7 @@ module ActiveRecord
201
228
  #
202
229
  # Example of a simple migration:
203
230
  #
204
- # class AddSsl < ActiveRecord::Migration[5.0]
231
+ # class AddSsl < ActiveRecord::Migration[6.0]
205
232
  # def up
206
233
  # add_column :accounts, :ssl_enabled, :boolean, default: true
207
234
  # end
@@ -221,7 +248,7 @@ module ActiveRecord
221
248
  #
222
249
  # Example of a more complex migration that also needs to initialize data:
223
250
  #
224
- # class AddSystemSettings < ActiveRecord::Migration[5.0]
251
+ # class AddSystemSettings < ActiveRecord::Migration[6.0]
225
252
  # def up
226
253
  # create_table :system_settings do |t|
227
254
  # t.string :name
@@ -337,7 +364,7 @@ module ActiveRecord
337
364
  # The Rails package has several tools to help create and apply migrations.
338
365
  #
339
366
  # To generate a new migration, you can use
340
- # rails generate migration MyNewMigration
367
+ # bin/rails generate migration MyNewMigration
341
368
  #
342
369
  # where MyNewMigration is the name of your migration. The generator will
343
370
  # create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
@@ -346,41 +373,36 @@ module ActiveRecord
346
373
  #
347
374
  # There is a special syntactic shortcut to generate migrations that add fields to a table.
348
375
  #
349
- # rails generate migration add_fieldname_to_tablename fieldname:string
376
+ # bin/rails generate migration add_fieldname_to_tablename fieldname:string
350
377
  #
351
378
  # This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
352
- # class AddFieldnameToTablename < ActiveRecord::Migration[5.0]
379
+ # class AddFieldnameToTablename < ActiveRecord::Migration[6.0]
353
380
  # def change
354
381
  # add_column :tablenames, :fieldname, :string
355
382
  # end
356
383
  # end
357
384
  #
358
385
  # To run migrations against the currently configured database, use
359
- # <tt>rails db:migrate</tt>. This will update the database by running all of the
386
+ # <tt>bin/rails db:migrate</tt>. This will update the database by running all of the
360
387
  # pending migrations, creating the <tt>schema_migrations</tt> table
361
388
  # (see "About the schema_migrations table" section below) if missing. It will also
362
389
  # invoke the db:schema:dump command, which will update your db/schema.rb file
363
390
  # to match the structure of your database.
364
391
  #
365
392
  # To roll the database back to a previous migration version, use
366
- # <tt>rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
393
+ # <tt>bin/rails db:rollback VERSION=X</tt> where <tt>X</tt> is the version to which
367
394
  # you wish to downgrade. Alternatively, you can also use the STEP option if you
368
- # wish to rollback last few migrations. <tt>rails db:rollback STEP=2</tt> will rollback
395
+ # wish to rollback last few migrations. <tt>bin/rails db:rollback STEP=2</tt> will rollback
369
396
  # the latest two migrations.
370
397
  #
371
398
  # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
372
399
  # that step will fail and you'll have some manual work to do.
373
400
  #
374
- # == Database support
375
- #
376
- # Migrations are currently supported in MySQL, PostgreSQL, SQLite,
377
- # SQL Server, and Oracle (all supported databases except DB2).
378
- #
379
401
  # == More examples
380
402
  #
381
403
  # Not all migrations change the schema. Some just fix the data:
382
404
  #
383
- # class RemoveEmptyTags < ActiveRecord::Migration[5.0]
405
+ # class RemoveEmptyTags < ActiveRecord::Migration[6.0]
384
406
  # def up
385
407
  # Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
386
408
  # end
@@ -393,7 +415,7 @@ module ActiveRecord
393
415
  #
394
416
  # Others remove columns when they migrate up instead of down:
395
417
  #
396
- # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[5.0]
418
+ # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[6.0]
397
419
  # def up
398
420
  # remove_column :items, :incomplete_items_count
399
421
  # remove_column :items, :completed_items_count
@@ -407,7 +429,7 @@ module ActiveRecord
407
429
  #
408
430
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
409
431
  #
410
- # class MakeJoinUnique < ActiveRecord::Migration[5.0]
432
+ # class MakeJoinUnique < ActiveRecord::Migration[6.0]
411
433
  # def up
412
434
  # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
413
435
  # end
@@ -424,7 +446,7 @@ module ActiveRecord
424
446
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
425
447
  # latest column data from after the new column was added. Example:
426
448
  #
427
- # class AddPeopleSalary < ActiveRecord::Migration[5.0]
449
+ # class AddPeopleSalary < ActiveRecord::Migration[6.0]
428
450
  # def up
429
451
  # add_column :people, :salary, :integer
430
452
  # Person.reset_column_information
@@ -482,7 +504,7 @@ module ActiveRecord
482
504
  # To define a reversible migration, define the +change+ method in your
483
505
  # migration like this:
484
506
  #
485
- # class TenderloveMigration < ActiveRecord::Migration[5.0]
507
+ # class TenderloveMigration < ActiveRecord::Migration[6.0]
486
508
  # def change
487
509
  # create_table(:horses) do |t|
488
510
  # t.column :content, :text
@@ -512,7 +534,7 @@ module ActiveRecord
512
534
  # can't execute inside a transaction though, and for these situations
513
535
  # you can turn the automatic transactions off.
514
536
  #
515
- # class ChangeEnum < ActiveRecord::Migration[5.0]
537
+ # class ChangeEnum < ActiveRecord::Migration[6.0]
516
538
  # disable_ddl_transaction!
517
539
  #
518
540
  # def up
@@ -525,6 +547,7 @@ module ActiveRecord
525
547
  class Migration
526
548
  autoload :CommandRecorder, "active_record/migration/command_recorder"
527
549
  autoload :Compatibility, "active_record/migration/compatibility"
550
+ autoload :JoinTable, "active_record/migration/join_table"
528
551
 
529
552
  # This must be defined before the inherited hook, below
530
553
  class Current < Migration #:nodoc:
@@ -553,21 +576,37 @@ module ActiveRecord
553
576
  # This class is used to verify that all migrations have been run before
554
577
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
555
578
  class CheckPending
556
- def initialize(app)
579
+ def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
557
580
  @app = app
558
- @last_check = 0
581
+ @needs_check = true
582
+ @mutex = Mutex.new
583
+ @file_watcher = file_watcher
559
584
  end
560
585
 
561
586
  def call(env)
562
- mtime = ActiveRecord::Base.connection.migration_context.last_migration.mtime.to_i
563
- if @last_check < mtime
564
- ActiveRecord::Migration.check_pending!(connection)
565
- @last_check = mtime
587
+ @mutex.synchronize do
588
+ @watcher ||= build_watcher do
589
+ @needs_check = true
590
+ ActiveRecord::Migration.check_pending!(connection)
591
+ @needs_check = false
592
+ end
593
+
594
+ if @needs_check
595
+ @watcher.execute
596
+ else
597
+ @watcher.execute_if_updated
598
+ end
566
599
  end
600
+
567
601
  @app.call(env)
568
602
  end
569
603
 
570
604
  private
605
+ def build_watcher(&block)
606
+ paths = Array(connection.migration_context.migrations_paths)
607
+ @file_watcher.new([], paths.index_with(["rb"]), &block)
608
+ end
609
+
571
610
  def connection
572
611
  ActiveRecord::Base.connection
573
612
  end
@@ -587,11 +626,11 @@ module ActiveRecord
587
626
  end
588
627
 
589
628
  def load_schema_if_pending!
590
- current_config = Base.connection_config
629
+ current_db_config = Base.connection_db_config
591
630
  all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
592
631
 
593
632
  needs_update = !all_configs.all? do |db_config|
594
- Tasks::DatabaseTasks.schema_up_to_date?(db_config.config, ActiveRecord::Base.schema_format, nil, Rails.env, db_config.spec_name)
633
+ Tasks::DatabaseTasks.schema_up_to_date?(db_config, ActiveRecord::Base.schema_format)
595
634
  end
596
635
 
597
636
  if needs_update
@@ -604,7 +643,7 @@ module ActiveRecord
604
643
  end
605
644
 
606
645
  # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
607
- Base.establish_connection(current_config)
646
+ Base.establish_connection(current_db_config)
608
647
 
609
648
  check_pending!
610
649
  end
@@ -657,7 +696,7 @@ module ActiveRecord
657
696
  # and create the table 'apples' on the way up, and the reverse
658
697
  # on the way down.
659
698
  #
660
- # class FixTLMigration < ActiveRecord::Migration[5.0]
699
+ # class FixTLMigration < ActiveRecord::Migration[6.0]
661
700
  # def change
662
701
  # revert do
663
702
  # create_table(:horses) do |t|
@@ -674,9 +713,9 @@ module ActiveRecord
674
713
  # Or equivalently, if +TenderloveMigration+ is defined as in the
675
714
  # documentation for Migration:
676
715
  #
677
- # require_relative '20121212123456_tenderlove_migration'
716
+ # require_relative "20121212123456_tenderlove_migration"
678
717
  #
679
- # class FixupTLMigration < ActiveRecord::Migration[5.0]
718
+ # class FixupTLMigration < ActiveRecord::Migration[6.0]
680
719
  # def change
681
720
  # revert TenderloveMigration
682
721
  #
@@ -727,7 +766,7 @@ module ActiveRecord
727
766
  # when the three columns 'first_name', 'last_name' and 'full_name' exist,
728
767
  # even when migrating down:
729
768
  #
730
- # class SplitNameMigration < ActiveRecord::Migration[5.0]
769
+ # class SplitNameMigration < ActiveRecord::Migration[6.0]
731
770
  # def change
732
771
  # add_column :users, :first_name, :string
733
772
  # add_column :users, :last_name, :string
@@ -755,7 +794,7 @@ module ActiveRecord
755
794
  # In the following example, the new column +published+ will be given
756
795
  # the value +true+ for all existing records.
757
796
  #
758
- # class AddPublishedToPosts < ActiveRecord::Migration[5.2]
797
+ # class AddPublishedToPosts < ActiveRecord::Migration[6.0]
759
798
  # def change
760
799
  # add_column :posts, :published, :boolean, default: false
761
800
  # up_only do
@@ -828,7 +867,7 @@ module ActiveRecord
828
867
  change
829
868
  end
830
869
  else
831
- send(direction)
870
+ public_send(direction)
832
871
  end
833
872
  ensure
834
873
  @connection = nil
@@ -995,10 +1034,6 @@ module ActiveRecord
995
1034
  File.basename(filename)
996
1035
  end
997
1036
 
998
- def mtime
999
- File.mtime filename
1000
- end
1001
-
1002
1037
  delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration
1003
1038
 
1004
1039
  private
@@ -1012,16 +1047,6 @@ module ActiveRecord
1012
1047
  end
1013
1048
  end
1014
1049
 
1015
- class NullMigration < MigrationProxy #:nodoc:
1016
- def initialize
1017
- super(nil, 0, nil, nil)
1018
- end
1019
-
1020
- def mtime
1021
- 0
1022
- end
1023
- end
1024
-
1025
1050
  class MigrationContext #:nodoc:
1026
1051
  attr_reader :migrations_paths, :schema_migration
1027
1052
 
@@ -1100,10 +1125,6 @@ module ActiveRecord
1100
1125
  migrations.any?
1101
1126
  end
1102
1127
 
1103
- def last_migration #:nodoc:
1104
- migrations.last || NullMigration.new
1105
- end
1106
-
1107
1128
  def migrations
1108
1129
  migrations = migration_files.map do |file|
1109
1130
  version, name, scope = parse_migration_filename(file)
@@ -1144,6 +1165,7 @@ module ActiveRecord
1144
1165
  end
1145
1166
 
1146
1167
  def last_stored_environment
1168
+ return nil unless ActiveRecord::InternalMetadata.enabled?
1147
1169
  return nil if current_version == 0
1148
1170
  raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1149
1171
 
@@ -1178,7 +1200,7 @@ module ActiveRecord
1178
1200
 
1179
1201
  finish = migrator.migrations[start_index + steps]
1180
1202
  version = finish ? finish.version : 0
1181
- send(direction, version)
1203
+ public_send(direction, version)
1182
1204
  end
1183
1205
  end
1184
1206
 
@@ -1265,7 +1287,7 @@ module ActiveRecord
1265
1287
  def run_without_lock
1266
1288
  migration = migrations.detect { |m| m.version == @target_version }
1267
1289
  raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
1268
- result = execute_migration_in_transaction(migration, @direction)
1290
+ result = execute_migration_in_transaction(migration)
1269
1291
 
1270
1292
  record_environment
1271
1293
  result
@@ -1277,10 +1299,7 @@ module ActiveRecord
1277
1299
  raise UnknownMigrationVersionError.new(@target_version)
1278
1300
  end
1279
1301
 
1280
- result = runnable.each do |migration|
1281
- execute_migration_in_transaction(migration, @direction)
1282
- end
1283
-
1302
+ result = runnable.each(&method(:execute_migration_in_transaction))
1284
1303
  record_environment
1285
1304
  result
1286
1305
  end
@@ -1300,14 +1319,14 @@ module ActiveRecord
1300
1319
  @target_version && @target_version != 0 && !target
1301
1320
  end
1302
1321
 
1303
- def execute_migration_in_transaction(migration, direction)
1322
+ def execute_migration_in_transaction(migration)
1304
1323
  return if down? && !migrated.include?(migration.version.to_i)
1305
1324
  return if up? && migrated.include?(migration.version.to_i)
1306
1325
 
1307
1326
  Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
1308
1327
 
1309
1328
  ddl_transaction(migration) do
1310
- migration.migrate(direction)
1329
+ migration.migrate(@direction)
1311
1330
  record_version_state_after_migrating(migration.version)
1312
1331
  end
1313
1332
  rescue => e
@@ -1374,20 +1393,31 @@ module ActiveRecord
1374
1393
 
1375
1394
  def with_advisory_lock
1376
1395
  lock_id = generate_migrator_advisory_lock_id
1377
- AdvisoryLockBase.establish_connection(ActiveRecord::Base.connection_config) unless AdvisoryLockBase.connected?
1378
- connection = AdvisoryLockBase.connection
1379
- got_lock = connection.get_advisory_lock(lock_id)
1380
- raise ConcurrentMigrationError unless got_lock
1381
- load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1382
- yield
1383
- ensure
1384
- if got_lock && !connection.release_advisory_lock(lock_id)
1385
- raise ConcurrentMigrationError.new(
1386
- ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1387
- )
1396
+
1397
+ with_advisory_lock_connection do |connection|
1398
+ got_lock = connection.get_advisory_lock(lock_id)
1399
+ raise ConcurrentMigrationError unless got_lock
1400
+ load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
1401
+ yield
1402
+ ensure
1403
+ if got_lock && !connection.release_advisory_lock(lock_id)
1404
+ raise ConcurrentMigrationError.new(
1405
+ ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
1406
+ )
1407
+ end
1388
1408
  end
1389
1409
  end
1390
1410
 
1411
+ def with_advisory_lock_connection
1412
+ pool = ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
1413
+ ActiveRecord::Base.connection_db_config
1414
+ )
1415
+
1416
+ pool.with_connection { |connection| yield(connection) }
1417
+ ensure
1418
+ pool&.disconnect!
1419
+ end
1420
+
1391
1421
  MIGRATOR_SALT = 2053462845
1392
1422
  def generate_migrator_advisory_lock_id
1393
1423
  db_name_hash = Zlib.crc32(Base.connection.current_database)
@@ -115,8 +115,17 @@ module ActiveRecord
115
115
  #
116
116
  # Sets the column to sort records by when no explicit order clause is used
117
117
  # during an ordered finder call. Useful when the primary key is not an
118
- # auto-incrementing integer, for example when it's a UUID. Note that using
119
- # a non-unique column can result in non-deterministic results.
118
+ # auto-incrementing integer, for example when it's a UUID. Records are subsorted
119
+ # by the primary key if it exists to ensure deterministic results.
120
+
121
+ ##
122
+ # :singleton-method: immutable_strings_by_default=
123
+ # :call-seq: immutable_strings_by_default=(bool)
124
+ #
125
+ # Determines whether columns should infer their type as `:string` or
126
+ # `:immutable_string`. This setting does not affect the behavior of
127
+ # `attribute :foo, :string`. Defaults to false.
128
+
120
129
  included do
121
130
  mattr_accessor :primary_key_prefix_type, instance_writer: false
122
131
 
@@ -126,12 +135,13 @@ module ActiveRecord
126
135
  class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
127
136
  class_attribute :pluralize_table_names, instance_writer: false, default: true
128
137
  class_attribute :implicit_order_column, instance_accessor: false
138
+ class_attribute :immutable_strings_by_default, instance_accessor: false
129
139
 
130
140
  self.protected_environments = ["production"]
131
141
  self.inheritance_column = "type"
132
142
  self.ignored_columns = [].freeze
133
143
 
134
- delegate :type_for_attribute, to: :class
144
+ delegate :type_for_attribute, :column_for_attribute, to: :class
135
145
 
136
146
  initialize_load_schema_monitor
137
147
  end
@@ -317,7 +327,8 @@ module ActiveRecord
317
327
  # user = Project.create!(name: "First Project")
318
328
  # user.category # => raises NoMethodError
319
329
  def ignored_columns=(columns)
320
- @ignored_columns = columns.map(&:to_s)
330
+ reload_schema_from_cache
331
+ @ignored_columns = columns.map(&:to_s).freeze
321
332
  end
322
333
 
323
334
  def sequence_name
@@ -384,7 +395,7 @@ module ActiveRecord
384
395
 
385
396
  def columns
386
397
  load_schema
387
- @columns ||= columns_hash.values
398
+ @columns ||= columns_hash.values.freeze
388
399
  end
389
400
 
390
401
  def attribute_types # :nodoc:
@@ -409,6 +420,8 @@ module ActiveRecord
409
420
  # a string or a symbol.
410
421
  def type_for_attribute(attr_name, &block)
411
422
  attr_name = attr_name.to_s
423
+ attr_name = attribute_aliases[attr_name] || attr_name
424
+
412
425
  if block
413
426
  attribute_types.fetch(attr_name, &block)
414
427
  else
@@ -416,11 +429,31 @@ module ActiveRecord
416
429
  end
417
430
  end
418
431
 
432
+ # Returns the column object for the named attribute.
433
+ # Returns an +ActiveRecord::ConnectionAdapters::NullColumn+ if the
434
+ # named attribute does not exist.
435
+ #
436
+ # class Person < ActiveRecord::Base
437
+ # end
438
+ #
439
+ # person = Person.new
440
+ # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
441
+ # # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
442
+ #
443
+ # person.column_for_attribute(:nothing)
444
+ # # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
445
+ def column_for_attribute(name)
446
+ name = name.to_s
447
+ columns_hash.fetch(name) do
448
+ ConnectionAdapters::NullColumn.new(name)
449
+ end
450
+ end
451
+
419
452
  # Returns a hash where the keys are column names and the values are
420
453
  # default values when instantiating the Active Record object for this table.
421
454
  def column_defaults
422
455
  load_schema
423
- @column_defaults ||= _default_attributes.deep_dup.to_hash
456
+ @column_defaults ||= _default_attributes.deep_dup.to_hash.freeze
424
457
  end
425
458
 
426
459
  def _default_attributes # :nodoc:
@@ -430,7 +463,7 @@ module ActiveRecord
430
463
 
431
464
  # Returns an array of column names as strings.
432
465
  def column_names
433
- @column_names ||= columns.map(&:name)
466
+ @column_names ||= columns.map(&:name).freeze
434
467
  end
435
468
 
436
469
  def symbol_column_to_string(name_symbol) # :nodoc:
@@ -444,9 +477,8 @@ module ActiveRecord
444
477
  @content_columns ||= columns.reject do |c|
445
478
  c.name == primary_key ||
446
479
  c.name == inheritance_column ||
447
- c.name.end_with?("_id") ||
448
- c.name.end_with?("_count")
449
- end
480
+ c.name.end_with?("_id", "_count")
481
+ end.freeze
450
482
  end
451
483
 
452
484
  # Resets all the cached information about columns, which will cause them
@@ -456,7 +488,7 @@ module ActiveRecord
456
488
  # when just after creating a table you want to populate it with some default
457
489
  # values, eg:
458
490
  #
459
- # class CreateJobLevels < ActiveRecord::Migration[5.0]
491
+ # class CreateJobLevels < ActiveRecord::Migration[6.0]
460
492
  # def up
461
493
  # create_table :job_levels do |t|
462
494
  # t.integer :id
@@ -514,11 +546,20 @@ module ActiveRecord
514
546
  end
515
547
 
516
548
  def load_schema!
517
- @columns_hash = connection.schema_cache.columns_hash(table_name).except(*ignored_columns)
549
+ unless table_name
550
+ raise ActiveRecord::TableNotSpecified, "#{self} has no table configured. Set one with #{self}.table_name="
551
+ end
552
+
553
+ columns_hash = connection.schema_cache.columns_hash(table_name)
554
+ columns_hash = columns_hash.except(*ignored_columns) unless ignored_columns.empty?
555
+ @columns_hash = columns_hash.freeze
518
556
  @columns_hash.each do |name, column|
557
+ type = connection.lookup_cast_type_from_column(column)
558
+ type = _convert_type_from_options(type)
559
+ warn_if_deprecated_type(column)
519
560
  define_attribute(
520
561
  name,
521
- connection.lookup_cast_type_from_column(column),
562
+ type,
522
563
  default: column.default,
523
564
  user_provided_default: false
524
565
  )
@@ -567,6 +608,40 @@ module ActiveRecord
567
608
  base_class.table_name
568
609
  end
569
610
  end
611
+
612
+ def _convert_type_from_options(type)
613
+ if immutable_strings_by_default && type.respond_to?(:to_immutable_string)
614
+ type.to_immutable_string
615
+ else
616
+ type
617
+ end
618
+ end
619
+
620
+ def warn_if_deprecated_type(column)
621
+ return if attributes_to_define_after_schema_loads.key?(column.name)
622
+ return unless column.respond_to?(:oid)
623
+
624
+ if column.array?
625
+ array_arguments = ", array: true"
626
+ else
627
+ array_arguments = ""
628
+ end
629
+
630
+ if column.sql_type.start_with?("interval")
631
+ precision_arguments = column.precision.presence && ", precision: #{column.precision}"
632
+ ActiveSupport::Deprecation.warn(<<~WARNING)
633
+ The behavior of the `:interval` type will be changing in Rails 6.2
634
+ to return an `ActiveSupport::Duration` object. If you'd like to keep
635
+ the old behavior, you can add this line to #{self.name} model:
636
+
637
+ attribute :#{column.name}, :string#{precision_arguments}#{array_arguments}
638
+
639
+ If you'd like the new behavior today, you can add this line:
640
+
641
+ attribute :#{column.name}, :interval#{precision_arguments}#{array_arguments}
642
+ WARNING
643
+ end
644
+ end
570
645
  end
571
646
  end
572
647
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "active_support/core_ext/hash/except"
4
4
  require "active_support/core_ext/module/redefine_method"
5
- require "active_support/core_ext/object/try"
6
5
  require "active_support/core_ext/hash/indifferent_access"
7
6
 
8
7
  module ActiveRecord
@@ -289,7 +288,7 @@ module ActiveRecord
289
288
  # [:allow_destroy]
290
289
  # If true, destroys any members from the attributes hash with a
291
290
  # <tt>_destroy</tt> key and a value that evaluates to +true+
292
- # (eg. 1, '1', true, or 'true'). This option is off by default.
291
+ # (e.g. 1, '1', true, or 'true'). This option is off by default.
293
292
  # [:reject_if]
294
293
  # Allows you to specify a Proc or a Symbol pointing to a method
295
294
  # that checks whether a record should be built for a certain attribute
@@ -510,7 +509,7 @@ module ActiveRecord
510
509
  if target_record
511
510
  existing_record = target_record
512
511
  else
513
- association.add_to_target(existing_record, :skip_callbacks)
512
+ association.add_to_target(existing_record, skip_callbacks: true)
514
513
  end
515
514
 
516
515
  assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])