activerecord 6.0.0 → 6.1.4

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 (270) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1178 -600
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_record/aggregations.rb +5 -6
  6. data/lib/active_record/association_relation.rb +30 -10
  7. data/lib/active_record/associations/alias_tracker.rb +19 -16
  8. data/lib/active_record/associations/association.rb +55 -29
  9. data/lib/active_record/associations/association_scope.rb +19 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +23 -10
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
  12. data/lib/active_record/associations/builder/association.rb +32 -5
  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 -3
  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 +25 -8
  20. data/lib/active_record/associations/collection_proxy.rb +14 -7
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -3
  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 +39 -16
  26. data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
  27. data/lib/active_record/associations/join_dependency.rb +77 -42
  28. data/lib/active_record/associations/preloader/association.rb +51 -25
  29. data/lib/active_record/associations/preloader/through_association.rb +2 -2
  30. data/lib/active_record/associations/preloader.rb +13 -8
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations/through_association.rb +1 -1
  33. data/lib/active_record/associations.rb +120 -13
  34. data/lib/active_record/attribute_assignment.rb +10 -9
  35. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
  36. data/lib/active_record/attribute_methods/dirty.rb +3 -13
  37. data/lib/active_record/attribute_methods/primary_key.rb +6 -4
  38. data/lib/active_record/attribute_methods/query.rb +3 -6
  39. data/lib/active_record/attribute_methods/read.rb +8 -12
  40. data/lib/active_record/attribute_methods/serialization.rb +11 -6
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  42. data/lib/active_record/attribute_methods/write.rb +12 -21
  43. data/lib/active_record/attribute_methods.rb +64 -54
  44. data/lib/active_record/attributes.rb +33 -9
  45. data/lib/active_record/autosave_association.rb +63 -44
  46. data/lib/active_record/base.rb +2 -14
  47. data/lib/active_record/callbacks.rb +153 -24
  48. data/lib/active_record/coders/yaml_column.rb +12 -3
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +87 -38
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -10
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  54. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +141 -52
  57. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  58. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +267 -105
  59. data/lib/active_record/connection_adapters/abstract/transaction.rb +94 -36
  60. data/lib/active_record/connection_adapters/abstract_adapter.rb +76 -79
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
  62. data/lib/active_record/connection_adapters/column.rb +15 -1
  63. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  64. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  65. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
  67. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  68. data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
  69. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
  70. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  71. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
  72. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
  73. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  74. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
  75. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  76. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
  79. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  81. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  96. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  97. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  102. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql_adapter.rb +83 -65
  104. data/lib/active_record/connection_adapters/schema_cache.rb +106 -15
  105. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  106. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
  107. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
  108. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  109. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
  110. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
  111. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  112. data/lib/active_record/connection_adapters.rb +52 -0
  113. data/lib/active_record/connection_handling.rb +219 -81
  114. data/lib/active_record/core.rb +268 -71
  115. data/lib/active_record/counter_cache.rb +4 -1
  116. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  117. data/lib/active_record/database_configurations/database_config.rb +52 -9
  118. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  119. data/lib/active_record/database_configurations/url_config.rb +15 -41
  120. data/lib/active_record/database_configurations.rb +124 -85
  121. data/lib/active_record/delegated_type.rb +209 -0
  122. data/lib/active_record/destroy_association_async_job.rb +36 -0
  123. data/lib/active_record/dynamic_matchers.rb +2 -3
  124. data/lib/active_record/enum.rb +80 -38
  125. data/lib/active_record/errors.rb +47 -12
  126. data/lib/active_record/explain.rb +9 -5
  127. data/lib/active_record/explain_subscriber.rb +1 -1
  128. data/lib/active_record/fixture_set/file.rb +10 -17
  129. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  130. data/lib/active_record/fixture_set/render_context.rb +1 -1
  131. data/lib/active_record/fixture_set/table_row.rb +2 -3
  132. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  133. data/lib/active_record/fixtures.rb +58 -12
  134. data/lib/active_record/gem_version.rb +2 -2
  135. data/lib/active_record/inheritance.rb +40 -21
  136. data/lib/active_record/insert_all.rb +43 -10
  137. data/lib/active_record/integration.rb +3 -5
  138. data/lib/active_record/internal_metadata.rb +16 -7
  139. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  140. data/lib/active_record/locking/optimistic.rb +33 -18
  141. data/lib/active_record/locking/pessimistic.rb +6 -2
  142. data/lib/active_record/log_subscriber.rb +28 -9
  143. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  144. data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
  145. data/lib/active_record/middleware/database_selector.rb +4 -2
  146. data/lib/active_record/migration/command_recorder.rb +53 -45
  147. data/lib/active_record/migration/compatibility.rb +71 -20
  148. data/lib/active_record/migration/join_table.rb +0 -1
  149. data/lib/active_record/migration.rb +115 -85
  150. data/lib/active_record/model_schema.rb +120 -15
  151. data/lib/active_record/nested_attributes.rb +2 -5
  152. data/lib/active_record/no_touching.rb +1 -1
  153. data/lib/active_record/null_relation.rb +0 -1
  154. data/lib/active_record/persistence.rb +50 -46
  155. data/lib/active_record/query_cache.rb +15 -5
  156. data/lib/active_record/querying.rb +12 -7
  157. data/lib/active_record/railtie.rb +65 -45
  158. data/lib/active_record/railties/console_sandbox.rb +2 -4
  159. data/lib/active_record/railties/databases.rake +280 -99
  160. data/lib/active_record/readonly_attributes.rb +4 -0
  161. data/lib/active_record/reflection.rb +77 -63
  162. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  163. data/lib/active_record/relation/batches.rb +38 -32
  164. data/lib/active_record/relation/calculations.rb +106 -45
  165. data/lib/active_record/relation/delegation.rb +9 -7
  166. data/lib/active_record/relation/finder_methods.rb +55 -17
  167. data/lib/active_record/relation/from_clause.rb +5 -1
  168. data/lib/active_record/relation/merger.rb +27 -26
  169. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  170. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  171. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
  172. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  173. data/lib/active_record/relation/predicate_builder.rb +59 -40
  174. data/lib/active_record/relation/query_methods.rb +344 -181
  175. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  176. data/lib/active_record/relation/spawn_methods.rb +8 -8
  177. data/lib/active_record/relation/where_clause.rb +111 -62
  178. data/lib/active_record/relation.rb +116 -82
  179. data/lib/active_record/result.rb +41 -34
  180. data/lib/active_record/runtime_registry.rb +2 -2
  181. data/lib/active_record/sanitization.rb +6 -17
  182. data/lib/active_record/schema_dumper.rb +34 -4
  183. data/lib/active_record/schema_migration.rb +2 -8
  184. data/lib/active_record/scoping/default.rb +1 -4
  185. data/lib/active_record/scoping/named.rb +7 -18
  186. data/lib/active_record/scoping.rb +0 -1
  187. data/lib/active_record/secure_token.rb +16 -8
  188. data/lib/active_record/serialization.rb +5 -3
  189. data/lib/active_record/signed_id.rb +116 -0
  190. data/lib/active_record/statement_cache.rb +20 -4
  191. data/lib/active_record/store.rb +3 -3
  192. data/lib/active_record/suppressor.rb +2 -2
  193. data/lib/active_record/table_metadata.rb +42 -36
  194. data/lib/active_record/tasks/database_tasks.rb +140 -113
  195. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
  196. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
  197. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
  198. data/lib/active_record/test_databases.rb +5 -4
  199. data/lib/active_record/test_fixtures.rb +79 -16
  200. data/lib/active_record/timestamp.rb +4 -7
  201. data/lib/active_record/touch_later.rb +20 -21
  202. data/lib/active_record/transactions.rb +26 -73
  203. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  204. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  205. data/lib/active_record/type/serialized.rb +6 -3
  206. data/lib/active_record/type/time.rb +10 -0
  207. data/lib/active_record/type/type_map.rb +0 -1
  208. data/lib/active_record/type/unsigned_integer.rb +0 -1
  209. data/lib/active_record/type.rb +8 -2
  210. data/lib/active_record/type_caster/connection.rb +0 -1
  211. data/lib/active_record/type_caster/map.rb +8 -5
  212. data/lib/active_record/validations/associated.rb +1 -2
  213. data/lib/active_record/validations/numericality.rb +35 -0
  214. data/lib/active_record/validations/uniqueness.rb +24 -4
  215. data/lib/active_record/validations.rb +3 -3
  216. data/lib/active_record.rb +7 -13
  217. data/lib/arel/attributes/attribute.rb +4 -0
  218. data/lib/arel/collectors/bind.rb +5 -0
  219. data/lib/arel/collectors/composite.rb +8 -0
  220. data/lib/arel/collectors/sql_string.rb +7 -0
  221. data/lib/arel/collectors/substitute_binds.rb +7 -0
  222. data/lib/arel/nodes/binary.rb +82 -8
  223. data/lib/arel/nodes/bind_param.rb +8 -0
  224. data/lib/arel/nodes/casted.rb +21 -9
  225. data/lib/arel/nodes/equality.rb +6 -9
  226. data/lib/arel/nodes/grouping.rb +3 -0
  227. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  228. data/lib/arel/nodes/in.rb +8 -1
  229. data/lib/arel/nodes/infix_operation.rb +13 -1
  230. data/lib/arel/nodes/join_source.rb +1 -1
  231. data/lib/arel/nodes/node.rb +7 -6
  232. data/lib/arel/nodes/ordering.rb +27 -0
  233. data/lib/arel/nodes/sql_literal.rb +3 -0
  234. data/lib/arel/nodes/table_alias.rb +7 -3
  235. data/lib/arel/nodes/unary.rb +0 -1
  236. data/lib/arel/nodes.rb +3 -1
  237. data/lib/arel/predications.rb +17 -24
  238. data/lib/arel/select_manager.rb +1 -2
  239. data/lib/arel/table.rb +13 -5
  240. data/lib/arel/visitors/dot.rb +14 -3
  241. data/lib/arel/visitors/mysql.rb +11 -1
  242. data/lib/arel/visitors/postgresql.rb +15 -5
  243. data/lib/arel/visitors/sqlite.rb +0 -1
  244. data/lib/arel/visitors/to_sql.rb +89 -79
  245. data/lib/arel/visitors/visitor.rb +0 -1
  246. data/lib/arel/visitors.rb +0 -7
  247. data/lib/arel.rb +15 -12
  248. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  249. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  250. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  251. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
  252. data/lib/rails/generators/active_record/migration.rb +6 -2
  253. data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
  254. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  255. metadata +27 -24
  256. data/lib/active_record/attribute_decorators.rb +0 -90
  257. data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
  258. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  259. data/lib/active_record/define_callbacks.rb +0 -22
  260. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  261. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  262. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  263. data/lib/arel/attributes.rb +0 -22
  264. data/lib/arel/visitors/depth_first.rb +0 -204
  265. data/lib/arel/visitors/ibm_db.rb +0 -34
  266. data/lib/arel/visitors/informix.rb +0 -62
  267. data/lib/arel/visitors/mssql.rb +0 -157
  268. data/lib/arel/visitors/oracle.rb +0 -159
  269. data/lib/arel/visitors/oracle12.rb +0 -66
  270. data/lib/arel/visitors/where_sql.rb +0 -23
@@ -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
@@ -293,7 +320,7 @@ module ActiveRecord
293
320
  # +table_name+. Passing a hash containing <tt>:from</tt> and <tt>:to</tt>
294
321
  # as +default_or_changes+ will make this change reversible in the migration.
295
322
  # * <tt>change_column_null(table_name, column_name, null, default = nil)</tt>:
296
- # Sets or removes a +NOT NULL+ constraint on +column_name+. The +null+ flag
323
+ # Sets or removes a <tt>NOT NULL</tt> constraint on +column_name+. The +null+ flag
297
324
  # indicates whether the value can be +NULL+. See
298
325
  # ActiveRecord::ConnectionAdapters::SchemaStatements#change_column_null for
299
326
  # details.
@@ -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,36 @@ 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
571
609
 
572
610
  def connection
573
611
  ActiveRecord::Base.connection
@@ -588,11 +626,11 @@ module ActiveRecord
588
626
  end
589
627
 
590
628
  def load_schema_if_pending!
591
- current_config = Base.connection_config
629
+ current_db_config = Base.connection_db_config
592
630
  all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
593
631
 
594
632
  needs_update = !all_configs.all? do |db_config|
595
- 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)
596
634
  end
597
635
 
598
636
  if needs_update
@@ -605,7 +643,7 @@ module ActiveRecord
605
643
  end
606
644
 
607
645
  # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
608
- Base.establish_connection(current_config)
646
+ Base.establish_connection(current_db_config)
609
647
 
610
648
  check_pending!
611
649
  end
@@ -619,6 +657,7 @@ module ActiveRecord
619
657
  def method_missing(name, *args, &block) #:nodoc:
620
658
  nearest_delegate.send(name, *args, &block)
621
659
  end
660
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
622
661
 
623
662
  def migrate(direction)
624
663
  new.migrate direction
@@ -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
@@ -890,6 +929,7 @@ module ActiveRecord
890
929
  connection.send(method, *arguments, &block)
891
930
  end
892
931
  end
932
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
893
933
 
894
934
  def copy(destination, sources, options = {})
895
935
  copied = []
@@ -994,14 +1034,9 @@ module ActiveRecord
994
1034
  File.basename(filename)
995
1035
  end
996
1036
 
997
- def mtime
998
- File.mtime filename
999
- end
1000
-
1001
1037
  delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration
1002
1038
 
1003
1039
  private
1004
-
1005
1040
  def migration
1006
1041
  @migration ||= load_migration
1007
1042
  end
@@ -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
 
@@ -1261,12 +1283,11 @@ module ActiveRecord
1261
1283
  end
1262
1284
 
1263
1285
  private
1264
-
1265
1286
  # Used for running a specific migration.
1266
1287
  def run_without_lock
1267
1288
  migration = migrations.detect { |m| m.version == @target_version }
1268
1289
  raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
1269
- result = execute_migration_in_transaction(migration, @direction)
1290
+ result = execute_migration_in_transaction(migration)
1270
1291
 
1271
1292
  record_environment
1272
1293
  result
@@ -1278,10 +1299,7 @@ module ActiveRecord
1278
1299
  raise UnknownMigrationVersionError.new(@target_version)
1279
1300
  end
1280
1301
 
1281
- result = runnable.each do |migration|
1282
- execute_migration_in_transaction(migration, @direction)
1283
- end
1284
-
1302
+ result = runnable.each(&method(:execute_migration_in_transaction))
1285
1303
  record_environment
1286
1304
  result
1287
1305
  end
@@ -1301,14 +1319,14 @@ module ActiveRecord
1301
1319
  @target_version && @target_version != 0 && !target
1302
1320
  end
1303
1321
 
1304
- def execute_migration_in_transaction(migration, direction)
1322
+ def execute_migration_in_transaction(migration)
1305
1323
  return if down? && !migrated.include?(migration.version.to_i)
1306
1324
  return if up? && migrated.include?(migration.version.to_i)
1307
1325
 
1308
1326
  Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
1309
1327
 
1310
1328
  ddl_transaction(migration) do
1311
- migration.migrate(direction)
1329
+ migration.migrate(@direction)
1312
1330
  record_version_state_after_migrating(migration.version)
1313
1331
  end
1314
1332
  rescue => e
@@ -1375,19 +1393,31 @@ module ActiveRecord
1375
1393
 
1376
1394
  def with_advisory_lock
1377
1395
  lock_id = generate_migrator_advisory_lock_id
1378
- connection = Base.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)