activerecord 5.2.6 → 6.0.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 (268) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +609 -622
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +4 -2
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +4 -2
  7. data/lib/active_record/associations/association.rb +52 -19
  8. data/lib/active_record/associations/association_scope.rb +4 -6
  9. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  11. data/lib/active_record/associations/builder/association.rb +14 -18
  12. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  13. data/lib/active_record/associations/builder/collection_association.rb +3 -13
  14. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  15. data/lib/active_record/associations/builder/has_many.rb +2 -0
  16. data/lib/active_record/associations/builder/has_one.rb +35 -1
  17. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  18. data/lib/active_record/associations/collection_association.rb +6 -21
  19. data/lib/active_record/associations/collection_proxy.rb +12 -15
  20. data/lib/active_record/associations/foreign_association.rb +7 -0
  21. data/lib/active_record/associations/has_many_association.rb +2 -10
  22. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  23. data/lib/active_record/associations/has_one_association.rb +28 -30
  24. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  25. data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
  26. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  27. data/lib/active_record/associations/join_dependency.rb +24 -28
  28. data/lib/active_record/associations/preloader/association.rb +38 -36
  29. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  30. data/lib/active_record/associations/preloader.rb +40 -32
  31. data/lib/active_record/associations/singular_association.rb +2 -16
  32. data/lib/active_record/associations.rb +19 -14
  33. data/lib/active_record/attribute_assignment.rb +7 -10
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  35. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  36. data/lib/active_record/attribute_methods/primary_key.rb +15 -22
  37. data/lib/active_record/attribute_methods/query.rb +2 -3
  38. data/lib/active_record/attribute_methods/read.rb +15 -53
  39. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  41. data/lib/active_record/attribute_methods/write.rb +17 -24
  42. data/lib/active_record/attribute_methods.rb +28 -100
  43. data/lib/active_record/attributes.rb +13 -0
  44. data/lib/active_record/autosave_association.rb +5 -9
  45. data/lib/active_record/base.rb +2 -3
  46. data/lib/active_record/callbacks.rb +5 -19
  47. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +94 -16
  48. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  49. data/lib/active_record/connection_adapters/abstract/database_statements.rb +95 -123
  50. data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -8
  51. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  52. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
  53. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
  54. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  55. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
  56. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
  57. data/lib/active_record/connection_adapters/abstract_adapter.rb +180 -47
  58. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +128 -194
  59. data/lib/active_record/connection_adapters/column.rb +17 -13
  60. data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
  61. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  62. data/lib/active_record/connection_adapters/mysql/database_statements.rb +73 -13
  63. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  64. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  65. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  66. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
  68. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
  70. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -1
  72. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  73. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  74. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  75. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  76. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  77. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  79. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  80. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  81. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  82. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
  83. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  84. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
  85. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  86. data/lib/active_record/connection_adapters/postgresql_adapter.rb +160 -74
  87. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  88. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  89. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  90. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
  91. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
  92. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -141
  93. data/lib/active_record/connection_handling.rb +149 -27
  94. data/lib/active_record/core.rb +100 -60
  95. data/lib/active_record/counter_cache.rb +4 -29
  96. data/lib/active_record/database_configurations/database_config.rb +37 -0
  97. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  98. data/lib/active_record/database_configurations/url_config.rb +79 -0
  99. data/lib/active_record/database_configurations.rb +233 -0
  100. data/lib/active_record/dynamic_matchers.rb +1 -1
  101. data/lib/active_record/enum.rb +37 -7
  102. data/lib/active_record/errors.rb +15 -7
  103. data/lib/active_record/explain.rb +1 -1
  104. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  105. data/lib/active_record/fixture_set/render_context.rb +17 -0
  106. data/lib/active_record/fixture_set/table_row.rb +153 -0
  107. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  108. data/lib/active_record/fixtures.rb +145 -472
  109. data/lib/active_record/gem_version.rb +3 -3
  110. data/lib/active_record/inheritance.rb +13 -3
  111. data/lib/active_record/insert_all.rb +179 -0
  112. data/lib/active_record/integration.rb +68 -16
  113. data/lib/active_record/internal_metadata.rb +10 -2
  114. data/lib/active_record/locking/optimistic.rb +5 -6
  115. data/lib/active_record/locking/pessimistic.rb +3 -3
  116. data/lib/active_record/log_subscriber.rb +7 -26
  117. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  118. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  119. data/lib/active_record/middleware/database_selector.rb +75 -0
  120. data/lib/active_record/migration/command_recorder.rb +50 -6
  121. data/lib/active_record/migration/compatibility.rb +76 -49
  122. data/lib/active_record/migration.rb +100 -81
  123. data/lib/active_record/model_schema.rb +30 -9
  124. data/lib/active_record/nested_attributes.rb +2 -2
  125. data/lib/active_record/no_touching.rb +7 -0
  126. data/lib/active_record/persistence.rb +228 -24
  127. data/lib/active_record/query_cache.rb +11 -4
  128. data/lib/active_record/querying.rb +32 -20
  129. data/lib/active_record/railtie.rb +80 -43
  130. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  131. data/lib/active_record/railties/controller_runtime.rb +30 -35
  132. data/lib/active_record/railties/databases.rake +196 -46
  133. data/lib/active_record/reflection.rb +32 -30
  134. data/lib/active_record/relation/batches.rb +13 -10
  135. data/lib/active_record/relation/calculations.rb +53 -47
  136. data/lib/active_record/relation/delegation.rb +26 -43
  137. data/lib/active_record/relation/finder_methods.rb +13 -26
  138. data/lib/active_record/relation/merger.rb +11 -20
  139. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  140. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  141. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  142. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  143. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  144. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  145. data/lib/active_record/relation/predicate_builder.rb +4 -6
  146. data/lib/active_record/relation/query_attribute.rb +13 -8
  147. data/lib/active_record/relation/query_methods.rb +189 -63
  148. data/lib/active_record/relation/spawn_methods.rb +1 -1
  149. data/lib/active_record/relation/where_clause.rb +14 -10
  150. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  151. data/lib/active_record/relation.rb +310 -80
  152. data/lib/active_record/result.rb +30 -11
  153. data/lib/active_record/sanitization.rb +32 -40
  154. data/lib/active_record/schema.rb +2 -11
  155. data/lib/active_record/schema_dumper.rb +22 -7
  156. data/lib/active_record/schema_migration.rb +5 -1
  157. data/lib/active_record/scoping/default.rb +4 -5
  158. data/lib/active_record/scoping/named.rb +19 -15
  159. data/lib/active_record/scoping.rb +8 -8
  160. data/lib/active_record/statement_cache.rb +30 -3
  161. data/lib/active_record/store.rb +87 -8
  162. data/lib/active_record/table_metadata.rb +10 -17
  163. data/lib/active_record/tasks/database_tasks.rb +194 -25
  164. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
  165. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  166. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  167. data/lib/active_record/test_databases.rb +23 -0
  168. data/lib/active_record/test_fixtures.rb +224 -0
  169. data/lib/active_record/timestamp.rb +39 -25
  170. data/lib/active_record/touch_later.rb +4 -2
  171. data/lib/active_record/transactions.rb +57 -66
  172. data/lib/active_record/translation.rb +1 -1
  173. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  174. data/lib/active_record/type.rb +3 -4
  175. data/lib/active_record/type_caster/connection.rb +15 -14
  176. data/lib/active_record/type_caster/map.rb +1 -4
  177. data/lib/active_record/validations/uniqueness.rb +15 -27
  178. data/lib/active_record/validations.rb +1 -0
  179. data/lib/active_record.rb +9 -2
  180. data/lib/arel/alias_predication.rb +9 -0
  181. data/lib/arel/attributes/attribute.rb +37 -0
  182. data/lib/arel/attributes.rb +22 -0
  183. data/lib/arel/collectors/bind.rb +24 -0
  184. data/lib/arel/collectors/composite.rb +31 -0
  185. data/lib/arel/collectors/plain_string.rb +20 -0
  186. data/lib/arel/collectors/sql_string.rb +20 -0
  187. data/lib/arel/collectors/substitute_binds.rb +28 -0
  188. data/lib/arel/crud.rb +42 -0
  189. data/lib/arel/delete_manager.rb +18 -0
  190. data/lib/arel/errors.rb +9 -0
  191. data/lib/arel/expressions.rb +29 -0
  192. data/lib/arel/factory_methods.rb +49 -0
  193. data/lib/arel/insert_manager.rb +49 -0
  194. data/lib/arel/math.rb +45 -0
  195. data/lib/arel/nodes/and.rb +32 -0
  196. data/lib/arel/nodes/ascending.rb +23 -0
  197. data/lib/arel/nodes/binary.rb +52 -0
  198. data/lib/arel/nodes/bind_param.rb +36 -0
  199. data/lib/arel/nodes/case.rb +55 -0
  200. data/lib/arel/nodes/casted.rb +50 -0
  201. data/lib/arel/nodes/comment.rb +29 -0
  202. data/lib/arel/nodes/count.rb +12 -0
  203. data/lib/arel/nodes/delete_statement.rb +45 -0
  204. data/lib/arel/nodes/descending.rb +23 -0
  205. data/lib/arel/nodes/equality.rb +18 -0
  206. data/lib/arel/nodes/extract.rb +24 -0
  207. data/lib/arel/nodes/false.rb +16 -0
  208. data/lib/arel/nodes/full_outer_join.rb +8 -0
  209. data/lib/arel/nodes/function.rb +44 -0
  210. data/lib/arel/nodes/grouping.rb +8 -0
  211. data/lib/arel/nodes/in.rb +8 -0
  212. data/lib/arel/nodes/infix_operation.rb +80 -0
  213. data/lib/arel/nodes/inner_join.rb +8 -0
  214. data/lib/arel/nodes/insert_statement.rb +37 -0
  215. data/lib/arel/nodes/join_source.rb +20 -0
  216. data/lib/arel/nodes/matches.rb +18 -0
  217. data/lib/arel/nodes/named_function.rb +23 -0
  218. data/lib/arel/nodes/node.rb +50 -0
  219. data/lib/arel/nodes/node_expression.rb +13 -0
  220. data/lib/arel/nodes/outer_join.rb +8 -0
  221. data/lib/arel/nodes/over.rb +15 -0
  222. data/lib/arel/nodes/regexp.rb +16 -0
  223. data/lib/arel/nodes/right_outer_join.rb +8 -0
  224. data/lib/arel/nodes/select_core.rb +67 -0
  225. data/lib/arel/nodes/select_statement.rb +41 -0
  226. data/lib/arel/nodes/sql_literal.rb +16 -0
  227. data/lib/arel/nodes/string_join.rb +11 -0
  228. data/lib/arel/nodes/table_alias.rb +27 -0
  229. data/lib/arel/nodes/terminal.rb +16 -0
  230. data/lib/arel/nodes/true.rb +16 -0
  231. data/lib/arel/nodes/unary.rb +45 -0
  232. data/lib/arel/nodes/unary_operation.rb +20 -0
  233. data/lib/arel/nodes/unqualified_column.rb +22 -0
  234. data/lib/arel/nodes/update_statement.rb +41 -0
  235. data/lib/arel/nodes/values_list.rb +9 -0
  236. data/lib/arel/nodes/window.rb +126 -0
  237. data/lib/arel/nodes/with.rb +11 -0
  238. data/lib/arel/nodes.rb +68 -0
  239. data/lib/arel/order_predications.rb +13 -0
  240. data/lib/arel/predications.rb +257 -0
  241. data/lib/arel/select_manager.rb +271 -0
  242. data/lib/arel/table.rb +110 -0
  243. data/lib/arel/tree_manager.rb +72 -0
  244. data/lib/arel/update_manager.rb +34 -0
  245. data/lib/arel/visitors/depth_first.rb +204 -0
  246. data/lib/arel/visitors/dot.rb +297 -0
  247. data/lib/arel/visitors/ibm_db.rb +34 -0
  248. data/lib/arel/visitors/informix.rb +62 -0
  249. data/lib/arel/visitors/mssql.rb +157 -0
  250. data/lib/arel/visitors/mysql.rb +83 -0
  251. data/lib/arel/visitors/oracle.rb +159 -0
  252. data/lib/arel/visitors/oracle12.rb +66 -0
  253. data/lib/arel/visitors/postgresql.rb +110 -0
  254. data/lib/arel/visitors/sqlite.rb +39 -0
  255. data/lib/arel/visitors/to_sql.rb +889 -0
  256. data/lib/arel/visitors/visitor.rb +46 -0
  257. data/lib/arel/visitors/where_sql.rb +23 -0
  258. data/lib/arel/visitors.rb +20 -0
  259. data/lib/arel/window_predications.rb +9 -0
  260. data/lib/arel.rb +51 -0
  261. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  262. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  263. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  264. data/lib/rails/generators/active_record/migration.rb +14 -1
  265. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  266. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  267. metadata +108 -26
  268. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "benchmark"
3
4
  require "set"
4
5
  require "zlib"
5
6
  require "active_support/core_ext/module/attribute_accessors"
7
+ require "active_support/actionable_error"
6
8
 
7
9
  module ActiveRecord
8
- class MigrationError < ActiveRecordError#:nodoc:
10
+ class MigrationError < ActiveRecordError #:nodoc:
9
11
  def initialize(message = nil)
10
12
  message = "\n\n#{message}\n\n" if message
11
13
  super
@@ -22,7 +24,7 @@ module ActiveRecord
22
24
  # t.string :zipcode
23
25
  # end
24
26
  #
25
- # execute <<-SQL
27
+ # execute <<~SQL
26
28
  # ALTER TABLE distributors
27
29
  # ADD CONSTRAINT zipchk
28
30
  # CHECK (char_length(zipcode) = 5) NO INHERIT;
@@ -40,7 +42,7 @@ module ActiveRecord
40
42
  # t.string :zipcode
41
43
  # end
42
44
  #
43
- # execute <<-SQL
45
+ # execute <<~SQL
44
46
  # ALTER TABLE distributors
45
47
  # ADD CONSTRAINT zipchk
46
48
  # CHECK (char_length(zipcode) = 5) NO INHERIT;
@@ -48,7 +50,7 @@ module ActiveRecord
48
50
  # end
49
51
  #
50
52
  # def down
51
- # execute <<-SQL
53
+ # execute <<~SQL
52
54
  # ALTER TABLE distributors
53
55
  # DROP CONSTRAINT zipchk
54
56
  # SQL
@@ -67,7 +69,7 @@ module ActiveRecord
67
69
  #
68
70
  # reversible do |dir|
69
71
  # dir.up do
70
- # execute <<-SQL
72
+ # execute <<~SQL
71
73
  # ALTER TABLE distributors
72
74
  # ADD CONSTRAINT zipchk
73
75
  # CHECK (char_length(zipcode) = 5) NO INHERIT;
@@ -75,7 +77,7 @@ module ActiveRecord
75
77
  # end
76
78
  #
77
79
  # dir.down do
78
- # execute <<-SQL
80
+ # execute <<~SQL
79
81
  # ALTER TABLE distributors
80
82
  # DROP CONSTRAINT zipchk
81
83
  # SQL
@@ -86,7 +88,7 @@ module ActiveRecord
86
88
  class IrreversibleMigration < MigrationError
87
89
  end
88
90
 
89
- class DuplicateMigrationVersionError < MigrationError#:nodoc:
91
+ class DuplicateMigrationVersionError < MigrationError #:nodoc:
90
92
  def initialize(version = nil)
91
93
  if version
92
94
  super("Multiple migrations have the version number #{version}.")
@@ -96,7 +98,7 @@ module ActiveRecord
96
98
  end
97
99
  end
98
100
 
99
- class DuplicateMigrationNameError < MigrationError#:nodoc:
101
+ class DuplicateMigrationNameError < MigrationError #:nodoc:
100
102
  def initialize(name = nil)
101
103
  if name
102
104
  super("Multiple migrations have the name #{name}.")
@@ -116,7 +118,7 @@ module ActiveRecord
116
118
  end
117
119
  end
118
120
 
119
- class IllegalMigrationNameError < MigrationError#:nodoc:
121
+ class IllegalMigrationNameError < MigrationError #:nodoc:
120
122
  def initialize(name = nil)
121
123
  if name
122
124
  super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed).")
@@ -126,12 +128,18 @@ module ActiveRecord
126
128
  end
127
129
  end
128
130
 
129
- class PendingMigrationError < MigrationError#:nodoc:
131
+ class PendingMigrationError < MigrationError #:nodoc:
132
+ include ActiveSupport::ActionableError
133
+
134
+ action "Run pending migrations" do
135
+ ActiveRecord::Tasks::DatabaseTasks.migrate
136
+ end
137
+
130
138
  def initialize(message = nil)
131
139
  if !message && defined?(Rails.env)
132
- super("Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate RAILS_ENV=#{::Rails.env}")
140
+ super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate RAILS_ENV=#{::Rails.env}")
133
141
  elsif !message
134
- super("Migrations are pending. To resolve this issue, run:\n\n bin/rails db:migrate")
142
+ super("Migrations are pending. To resolve this issue, run:\n\n rails db:migrate")
135
143
  else
136
144
  super
137
145
  end
@@ -139,8 +147,8 @@ module ActiveRecord
139
147
  end
140
148
 
141
149
  class ConcurrentMigrationError < MigrationError #:nodoc:
142
- DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running.".freeze
143
- RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock".freeze
150
+ DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running."
151
+ RELEASE_LOCK_FAILED_MESSAGE = "Failed to release advisory lock"
144
152
 
145
153
  def initialize(message = DEFAULT_MESSAGE)
146
154
  super
@@ -149,7 +157,7 @@ module ActiveRecord
149
157
 
150
158
  class NoEnvironmentInSchemaError < MigrationError #:nodoc:
151
159
  def initialize
152
- msg = "Environment data not found in the schema. To resolve this issue, run: \n\n bin/rails db:environment:set"
160
+ msg = "Environment data not found in the schema. To resolve this issue, run: \n\n rails db:environment:set"
153
161
  if defined?(Rails.env)
154
162
  super("#{msg} RAILS_ENV=#{::Rails.env}")
155
163
  else
@@ -160,7 +168,7 @@ module ActiveRecord
160
168
 
161
169
  class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
162
170
  def initialize(env = "production")
163
- msg = "You are attempting to run a destructive action against your '#{env}' database.\n".dup
171
+ msg = +"You are attempting to run a destructive action against your '#{env}' database.\n"
164
172
  msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
165
173
  msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
166
174
  super(msg)
@@ -169,10 +177,10 @@ module ActiveRecord
169
177
 
170
178
  class EnvironmentMismatchError < ActiveRecordError
171
179
  def initialize(current: nil, stored: nil)
172
- msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n".dup
180
+ msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
173
181
  msg << "You are running in `#{ current }` environment. "
174
182
  msg << "If you are sure you want to continue, first set the environment using:\n\n"
175
- msg << " bin/rails db:environment:set"
183
+ msg << " rails db:environment:set"
176
184
  if defined?(Rails.env)
177
185
  super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
178
186
  else
@@ -307,7 +315,7 @@ module ActiveRecord
307
315
  # named +column_name+ from the table called +table_name+.
308
316
  # * <tt>remove_columns(table_name, *column_names)</tt>: Removes the given
309
317
  # columns from the table definition.
310
- # * <tt>remove_foreign_key(from_table, options_or_to_table)</tt>: Removes the
318
+ # * <tt>remove_foreign_key(from_table, to_table = nil, **options)</tt>: Removes the
311
319
  # given foreign key from the table called +table_name+.
312
320
  # * <tt>remove_index(table_name, column: column_names)</tt>: Removes the index
313
321
  # specified by +column_names+.
@@ -351,7 +359,7 @@ module ActiveRecord
351
359
  # <tt>rails db:migrate</tt>. This will update the database by running all of the
352
360
  # pending migrations, creating the <tt>schema_migrations</tt> table
353
361
  # (see "About the schema_migrations table" section below) if missing. It will also
354
- # invoke the db:schema:dump task, which will update your db/schema.rb file
362
+ # invoke the db:schema:dump command, which will update your db/schema.rb file
355
363
  # to match the structure of your database.
356
364
  #
357
365
  # To roll the database back to a previous migration version, use
@@ -486,9 +494,9 @@ module ActiveRecord
486
494
  # This migration will create the horses table for you on the way up, and
487
495
  # automatically figure out how to drop the table on the way down.
488
496
  #
489
- # Some commands like +remove_column+ cannot be reversed. If you care to
490
- # define how to move up and down in these cases, you should define the +up+
491
- # and +down+ methods as before.
497
+ # Some commands cannot be reversed. If you care to define how to move up
498
+ # and down in these cases, you should define the +up+ and +down+ methods
499
+ # as before.
492
500
  #
493
501
  # If a command cannot be reversed, an
494
502
  # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
@@ -519,10 +527,10 @@ module ActiveRecord
519
527
  autoload :Compatibility, "active_record/migration/compatibility"
520
528
 
521
529
  # This must be defined before the inherited hook, below
522
- class Current < Migration # :nodoc:
530
+ class Current < Migration #:nodoc:
523
531
  end
524
532
 
525
- def self.inherited(subclass) # :nodoc:
533
+ def self.inherited(subclass) #:nodoc:
526
534
  super
527
535
  if subclass.superclass == Migration
528
536
  raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
@@ -540,7 +548,7 @@ module ActiveRecord
540
548
  ActiveRecord::VERSION::STRING.to_f
541
549
  end
542
550
 
543
- MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
551
+ MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ #:nodoc:
544
552
 
545
553
  # This class is used to verify that all migrations have been run before
546
554
  # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
@@ -567,10 +575,10 @@ module ActiveRecord
567
575
  end
568
576
 
569
577
  class << self
570
- attr_accessor :delegate # :nodoc:
571
- attr_accessor :disable_ddl_transaction # :nodoc:
578
+ attr_accessor :delegate #:nodoc:
579
+ attr_accessor :disable_ddl_transaction #:nodoc:
572
580
 
573
- def nearest_delegate # :nodoc:
581
+ def nearest_delegate #:nodoc:
574
582
  delegate || superclass.nearest_delegate
575
583
  end
576
584
 
@@ -580,27 +588,35 @@ module ActiveRecord
580
588
  end
581
589
 
582
590
  def load_schema_if_pending!
583
- if Base.connection.migration_context.needs_migration? || !Base.connection.migration_context.any_migrations?
591
+ current_config = Base.connection_config
592
+ all_configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
593
+
594
+ 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)
596
+ end
597
+
598
+ if needs_update
584
599
  # Roundtrip to Rake to allow plugins to hook into database initialization.
585
600
  root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
586
601
  FileUtils.cd(root) do
587
- current_config = Base.connection_config
588
602
  Base.clear_all_connections!
589
603
  system("bin/rails db:test:prepare")
590
- # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
591
- Base.establish_connection(current_config)
592
604
  end
593
- check_pending!
594
605
  end
606
+
607
+ # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
608
+ Base.establish_connection(current_config)
609
+
610
+ check_pending!
595
611
  end
596
612
 
597
- def maintain_test_schema! # :nodoc:
613
+ def maintain_test_schema! #:nodoc:
598
614
  if ActiveRecord::Base.maintain_test_schema
599
615
  suppress_messages { load_schema_if_pending! }
600
616
  end
601
617
  end
602
618
 
603
- def method_missing(name, *args, &block) # :nodoc:
619
+ def method_missing(name, *args, &block) #:nodoc:
604
620
  nearest_delegate.send(name, *args, &block)
605
621
  end
606
622
 
@@ -617,7 +633,7 @@ module ActiveRecord
617
633
  end
618
634
  end
619
635
 
620
- def disable_ddl_transaction # :nodoc:
636
+ def disable_ddl_transaction #:nodoc:
621
637
  self.class.disable_ddl_transaction
622
638
  end
623
639
 
@@ -677,15 +693,13 @@ module ActiveRecord
677
693
  if connection.respond_to? :revert
678
694
  connection.revert { yield }
679
695
  else
680
- recorder = CommandRecorder.new(connection)
696
+ recorder = command_recorder
681
697
  @connection = recorder
682
698
  suppress_messages do
683
699
  connection.revert { yield }
684
700
  end
685
701
  @connection = recorder.delegate
686
- recorder.commands.each do |cmd, args, block|
687
- send(cmd, *args, &block)
688
- end
702
+ recorder.replay(self)
689
703
  end
690
704
  end
691
705
  end
@@ -694,7 +708,7 @@ module ActiveRecord
694
708
  connection.respond_to?(:reverting) && connection.reverting
695
709
  end
696
710
 
697
- ReversibleBlockHelper = Struct.new(:reverting) do # :nodoc:
711
+ ReversibleBlockHelper = Struct.new(:reverting) do #:nodoc:
698
712
  def up
699
713
  yield unless reverting
700
714
  end
@@ -830,10 +844,14 @@ module ActiveRecord
830
844
  write "== %s %s" % [text, "=" * length]
831
845
  end
832
846
 
847
+ # Takes a message argument and outputs it as is.
848
+ # A second boolean argument can be passed to specify whether to indent or not.
833
849
  def say(message, subitem = false)
834
850
  write "#{subitem ? " ->" : "--"} #{message}"
835
851
  end
836
852
 
853
+ # Outputs text along with how long it took to run its block.
854
+ # If the block returns an integer it assumes it is the number of rows affected.
837
855
  def say_with_time(message)
838
856
  say(message)
839
857
  result = nil
@@ -843,6 +861,7 @@ module ActiveRecord
843
861
  result
844
862
  end
845
863
 
864
+ # Takes a block as an argument and suppresses any output generated by the block.
846
865
  def suppress_messages
847
866
  save, self.verbose = verbose, false
848
867
  yield
@@ -874,18 +893,19 @@ module ActiveRecord
874
893
 
875
894
  def copy(destination, sources, options = {})
876
895
  copied = []
896
+ schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
877
897
 
878
898
  FileUtils.mkdir_p(destination) unless File.exist?(destination)
879
899
 
880
- destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
900
+ destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
881
901
  last = destination_migrations.last
882
902
  sources.each do |scope, path|
883
- source_migrations = ActiveRecord::MigrationContext.new(path).migrations
903
+ source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
884
904
 
885
905
  source_migrations.each do |migration|
886
906
  source = File.binread(migration.filename)
887
907
  inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
888
- magic_comments = "".dup
908
+ magic_comments = +""
889
909
  loop do
890
910
  # If we have a magic comment in the original migration,
891
911
  # insert our comment after the first newline(end of the magic comment line)
@@ -956,6 +976,10 @@ module ActiveRecord
956
976
  yield
957
977
  end
958
978
  end
979
+
980
+ def command_recorder
981
+ CommandRecorder.new(connection)
982
+ end
959
983
  end
960
984
 
961
985
  # MigrationProxy is used to defer loading of the actual migration classes
@@ -998,11 +1022,12 @@ module ActiveRecord
998
1022
  end
999
1023
  end
1000
1024
 
1001
- class MigrationContext # :nodoc:
1002
- attr_reader :migrations_paths
1025
+ class MigrationContext #:nodoc:
1026
+ attr_reader :migrations_paths, :schema_migration
1003
1027
 
1004
- def initialize(migrations_paths)
1028
+ def initialize(migrations_paths, schema_migration)
1005
1029
  @migrations_paths = migrations_paths
1030
+ @schema_migration = schema_migration
1006
1031
  end
1007
1032
 
1008
1033
  def migrate(target_version = nil, &block)
@@ -1033,7 +1058,7 @@ module ActiveRecord
1033
1058
  migrations
1034
1059
  end
1035
1060
 
1036
- Migrator.new(:up, selected_migrations, target_version).migrate
1061
+ Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
1037
1062
  end
1038
1063
 
1039
1064
  def down(target_version = nil)
@@ -1043,20 +1068,20 @@ module ActiveRecord
1043
1068
  migrations
1044
1069
  end
1045
1070
 
1046
- Migrator.new(:down, selected_migrations, target_version).migrate
1071
+ Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
1047
1072
  end
1048
1073
 
1049
1074
  def run(direction, target_version)
1050
- Migrator.new(direction, migrations, target_version).run
1075
+ Migrator.new(direction, migrations, schema_migration, target_version).run
1051
1076
  end
1052
1077
 
1053
1078
  def open
1054
- Migrator.new(:up, migrations, nil)
1079
+ Migrator.new(:up, migrations, schema_migration)
1055
1080
  end
1056
1081
 
1057
1082
  def get_all_versions
1058
- if SchemaMigration.table_exists?
1059
- SchemaMigration.all_versions.map(&:to_i)
1083
+ if schema_migration.table_exists?
1084
+ schema_migration.all_versions.map(&:to_i)
1060
1085
  else
1061
1086
  []
1062
1087
  end
@@ -1079,10 +1104,6 @@ module ActiveRecord
1079
1104
  migrations.last || NullMigration.new
1080
1105
  end
1081
1106
 
1082
- def parse_migration_filename(filename) # :nodoc:
1083
- File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1084
- end
1085
-
1086
1107
  def migrations
1087
1108
  migrations = migration_files.map do |file|
1088
1109
  version, name, scope = parse_migration_filename(file)
@@ -1097,12 +1118,12 @@ module ActiveRecord
1097
1118
  end
1098
1119
 
1099
1120
  def migrations_status
1100
- db_list = ActiveRecord::SchemaMigration.normalized_versions
1121
+ db_list = schema_migration.normalized_versions
1101
1122
 
1102
1123
  file_list = migration_files.map do |file|
1103
1124
  version, name, scope = parse_migration_filename(file)
1104
1125
  raise IllegalMigrationNameError.new(file) unless version
1105
- version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
1126
+ version = schema_migration.normalize_migration_number(version)
1106
1127
  status = db_list.delete(version) ? "up" : "down"
1107
1128
  [status, version, (name + scope).humanize]
1108
1129
  end.compact
@@ -1114,11 +1135,6 @@ module ActiveRecord
1114
1135
  (db_list + file_list).sort_by { |_, version, _| version }
1115
1136
  end
1116
1137
 
1117
- def migration_files
1118
- paths = Array(migrations_paths)
1119
- Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
1120
- end
1121
-
1122
1138
  def current_environment
1123
1139
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
1124
1140
  end
@@ -1137,8 +1153,17 @@ module ActiveRecord
1137
1153
  end
1138
1154
 
1139
1155
  private
1156
+ def migration_files
1157
+ paths = Array(migrations_paths)
1158
+ Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
1159
+ end
1160
+
1161
+ def parse_migration_filename(filename)
1162
+ File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
1163
+ end
1164
+
1140
1165
  def move(direction, steps)
1141
- migrator = Migrator.new(direction, migrations)
1166
+ migrator = Migrator.new(direction, migrations, schema_migration)
1142
1167
 
1143
1168
  if current_version != 0 && !migrator.current_migration
1144
1169
  raise UnknownMigrationVersionError.new(current_version)
@@ -1161,30 +1186,24 @@ module ActiveRecord
1161
1186
  class << self
1162
1187
  attr_accessor :migrations_paths
1163
1188
 
1164
- def migrations_path=(path)
1165
- ActiveSupport::Deprecation.warn \
1166
- "`ActiveRecord::Migrator.migrations_path=` is now deprecated and will be removed in Rails 6.0. " \
1167
- "You can set the `migrations_paths` on the `connection` instead through the `database.yml`."
1168
- self.migrations_paths = [path]
1169
- end
1170
-
1171
1189
  # For cases where a table doesn't exist like loading from schema cache
1172
1190
  def current_version
1173
- MigrationContext.new(migrations_paths).current_version
1191
+ MigrationContext.new(migrations_paths, SchemaMigration).current_version
1174
1192
  end
1175
1193
  end
1176
1194
 
1177
1195
  self.migrations_paths = ["db/migrate"]
1178
1196
 
1179
- def initialize(direction, migrations, target_version = nil)
1197
+ def initialize(direction, migrations, schema_migration, target_version = nil)
1180
1198
  @direction = direction
1181
1199
  @target_version = target_version
1182
1200
  @migrated_versions = nil
1183
1201
  @migrations = migrations
1202
+ @schema_migration = schema_migration
1184
1203
 
1185
1204
  validate(@migrations)
1186
1205
 
1187
- ActiveRecord::SchemaMigration.create_table
1206
+ @schema_migration.create_table
1188
1207
  ActiveRecord::InternalMetadata.create_table
1189
1208
  end
1190
1209
 
@@ -1238,7 +1257,7 @@ module ActiveRecord
1238
1257
  end
1239
1258
 
1240
1259
  def load_migrated
1241
- @migrated_versions = Set.new(Base.connection.migration_context.get_all_versions)
1260
+ @migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
1242
1261
  end
1243
1262
 
1244
1263
  private
@@ -1293,7 +1312,7 @@ module ActiveRecord
1293
1312
  record_version_state_after_migrating(migration.version)
1294
1313
  end
1295
1314
  rescue => e
1296
- msg = "An error has occurred, ".dup
1315
+ msg = +"An error has occurred, "
1297
1316
  msg << "this and " if use_transaction?(migration)
1298
1317
  msg << "all later migrations canceled:\n\n#{e}"
1299
1318
  raise StandardError, msg, e.backtrace
@@ -1322,10 +1341,10 @@ module ActiveRecord
1322
1341
  def record_version_state_after_migrating(version)
1323
1342
  if down?
1324
1343
  migrated.delete(version)
1325
- ActiveRecord::SchemaMigration.where(version: version.to_s).delete_all
1344
+ @schema_migration.delete_by(version: version.to_s)
1326
1345
  else
1327
1346
  migrated << version
1328
- ActiveRecord::SchemaMigration.create!(version: version.to_s)
1347
+ @schema_migration.create!(version: version.to_s)
1329
1348
  end
1330
1349
  end
1331
1350
 
@@ -1351,7 +1370,7 @@ module ActiveRecord
1351
1370
  end
1352
1371
 
1353
1372
  def use_advisory_lock?
1354
- Base.connection.supports_advisory_locks?
1373
+ Base.connection.advisory_locks_enabled?
1355
1374
  end
1356
1375
 
1357
1376
  def with_advisory_lock
@@ -102,6 +102,21 @@ module ActiveRecord
102
102
  # If true, the default table name for a Product class will be "products". If false, it would just be "product".
103
103
  # See table_name for the full rules on table/class naming. This is true, by default.
104
104
 
105
+ ##
106
+ # :singleton-method: implicit_order_column
107
+ # :call-seq: implicit_order_column
108
+ #
109
+ # The name of the column records are ordered by if no explicit order clause
110
+ # is used during an ordered finder call. If not set the primary key is used.
111
+
112
+ ##
113
+ # :singleton-method: implicit_order_column=
114
+ # :call-seq: implicit_order_column=(column_name)
115
+ #
116
+ # Sets the column to sort records by when no explicit order clause is used
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.
105
120
  included do
106
121
  mattr_accessor :primary_key_prefix_type, instance_writer: false
107
122
 
@@ -110,6 +125,7 @@ module ActiveRecord
110
125
  class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
111
126
  class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
112
127
  class_attribute :pluralize_table_names, instance_writer: false, default: true
128
+ class_attribute :implicit_order_column, instance_accessor: false
113
129
 
114
130
  self.protected_environments = ["production"]
115
131
  self.inheritance_column = "type"
@@ -218,11 +234,11 @@ module ActiveRecord
218
234
  end
219
235
 
220
236
  def full_table_name_prefix #:nodoc:
221
- (parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
237
+ (module_parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
222
238
  end
223
239
 
224
240
  def full_table_name_suffix #:nodoc:
225
- (parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
241
+ (module_parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
226
242
  end
227
243
 
228
244
  # The array of names of environments where destructive actions should be prohibited. By default,
@@ -276,7 +292,7 @@ module ActiveRecord
276
292
  end
277
293
 
278
294
  def sequence_name
279
- if base_class == self
295
+ if base_class?
280
296
  @sequence_name ||= reset_sequence_name
281
297
  else
282
298
  (@sequence_name ||= nil) || base_class.sequence_name
@@ -388,6 +404,11 @@ module ActiveRecord
388
404
  @column_names ||= columns.map(&:name)
389
405
  end
390
406
 
407
+ def symbol_column_to_string(name_symbol) # :nodoc:
408
+ @symbol_column_to_string_name_hash ||= column_names.index_by(&:to_sym)
409
+ @symbol_column_to_string_name_hash[name_symbol]
410
+ end
411
+
391
412
  # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
392
413
  # and columns used for single table inheritance have been removed.
393
414
  def content_columns
@@ -477,6 +498,7 @@ module ActiveRecord
477
498
  def reload_schema_from_cache
478
499
  @arel_table = nil
479
500
  @column_names = nil
501
+ @symbol_column_to_string_name_hash = nil
480
502
  @attribute_types = nil
481
503
  @content_columns = nil
482
504
  @default_attributes = nil
@@ -501,19 +523,18 @@ module ActiveRecord
501
523
 
502
524
  # Computes and returns a table name according to default conventions.
503
525
  def compute_table_name
504
- base = base_class
505
- if self == base
526
+ if base_class?
506
527
  # Nested classes are prefixed with singular parent table name.
507
- if parent < Base && !parent.abstract_class?
508
- contained = parent.table_name
509
- contained = contained.singularize if parent.pluralize_table_names
528
+ if module_parent < Base && !module_parent.abstract_class?
529
+ contained = module_parent.table_name
530
+ contained = contained.singularize if module_parent.pluralize_table_names
510
531
  contained += "_"
511
532
  end
512
533
 
513
534
  "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
514
535
  else
515
536
  # STI subclasses always use their superclass' table.
516
- base.table_name
537
+ base_class.table_name
517
538
  end
518
539
  end
519
540
  end
@@ -426,7 +426,7 @@ module ActiveRecord
426
426
  existing_record.assign_attributes(assignable_attributes)
427
427
  association(association_name).initialize_attributes(existing_record)
428
428
  else
429
- method = "build_#{association_name}"
429
+ method = :"build_#{association_name}"
430
430
  if respond_to?(method)
431
431
  send(method, assignable_attributes)
432
432
  else
@@ -501,7 +501,7 @@ module ActiveRecord
501
501
 
502
502
  if attributes["id"].blank?
503
503
  unless reject_new_record?(association_name, attributes)
504
- association.build(attributes.except(*UNASSIGNABLE_KEYS))
504
+ association.reader.build(attributes.except(*UNASSIGNABLE_KEYS))
505
505
  end
506
506
  elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s }
507
507
  unless call_reject_if(association_name, attributes)
@@ -43,6 +43,13 @@ module ActiveRecord
43
43
  end
44
44
  end
45
45
 
46
+ # Returns +true+ if the class has +no_touching+ set, +false+ otherwise.
47
+ #
48
+ # Project.no_touching do
49
+ # Project.first.no_touching? # true
50
+ # Message.first.no_touching? # false
51
+ # end
52
+ #
46
53
  def no_touching?
47
54
  NoTouching.applied_to?(self.class)
48
55
  end