activerecord 5.2.1.1 → 6.0.1

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 +738 -445
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +4 -2
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +9 -2
  7. data/lib/active_record/aggregations.rb +4 -2
  8. data/lib/active_record/association_relation.rb +18 -9
  9. data/lib/active_record/associations.rb +20 -15
  10. data/lib/active_record/associations/association.rb +69 -20
  11. data/lib/active_record/associations/association_scope.rb +4 -6
  12. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  14. data/lib/active_record/associations/builder/association.rb +14 -18
  15. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  16. data/lib/active_record/associations/builder/collection_association.rb +5 -15
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +35 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +15 -29
  22. data/lib/active_record/associations/collection_proxy.rb +19 -48
  23. data/lib/active_record/associations/foreign_association.rb +7 -0
  24. data/lib/active_record/associations/has_many_association.rb +11 -10
  25. data/lib/active_record/associations/has_many_through_association.rb +42 -25
  26. data/lib/active_record/associations/has_one_association.rb +28 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  28. data/lib/active_record/associations/join_dependency.rb +28 -28
  29. data/lib/active_record/associations/join_dependency/join_association.rb +27 -7
  30. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  31. data/lib/active_record/associations/preloader.rb +39 -31
  32. data/lib/active_record/associations/preloader/association.rb +38 -36
  33. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  34. data/lib/active_record/associations/singular_association.rb +2 -16
  35. data/lib/active_record/attribute_assignment.rb +7 -10
  36. data/lib/active_record/attribute_methods.rb +28 -100
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
  38. data/lib/active_record/attribute_methods/dirty.rb +114 -38
  39. data/lib/active_record/attribute_methods/primary_key.rb +15 -22
  40. data/lib/active_record/attribute_methods/query.rb +2 -3
  41. data/lib/active_record/attribute_methods/read.rb +15 -53
  42. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  44. data/lib/active_record/attribute_methods/write.rb +17 -24
  45. data/lib/active_record/attributes.rb +13 -0
  46. data/lib/active_record/autosave_association.rb +27 -13
  47. data/lib/active_record/base.rb +2 -3
  48. data/lib/active_record/callbacks.rb +6 -20
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +140 -27
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +22 -4
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +116 -127
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +26 -11
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +135 -56
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +189 -43
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +151 -198
  61. data/lib/active_record/connection_adapters/column.rb +17 -13
  62. data/lib/active_record/connection_adapters/connection_specification.rb +55 -45
  63. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +9 -4
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +75 -13
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  66. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  67. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  68. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  69. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
  70. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  71. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
  72. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  73. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +22 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +8 -2
  75. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  76. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  77. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  81. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  82. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
  83. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  84. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +47 -0
  85. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  86. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +65 -77
  87. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  88. data/lib/active_record/connection_adapters/postgresql/utils.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql_adapter.rb +172 -74
  90. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  91. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  92. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  93. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -5
  94. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
  95. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +131 -143
  96. data/lib/active_record/connection_handling.rb +155 -26
  97. data/lib/active_record/core.rb +104 -59
  98. data/lib/active_record/counter_cache.rb +4 -29
  99. data/lib/active_record/database_configurations.rb +233 -0
  100. data/lib/active_record/database_configurations/database_config.rb +37 -0
  101. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  102. data/lib/active_record/database_configurations/url_config.rb +79 -0
  103. data/lib/active_record/dynamic_matchers.rb +1 -1
  104. data/lib/active_record/enum.rb +38 -7
  105. data/lib/active_record/errors.rb +30 -16
  106. data/lib/active_record/explain.rb +1 -1
  107. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  108. data/lib/active_record/fixture_set/render_context.rb +17 -0
  109. data/lib/active_record/fixture_set/table_row.rb +153 -0
  110. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  111. data/lib/active_record/fixtures.rb +145 -472
  112. data/lib/active_record/gem_version.rb +3 -3
  113. data/lib/active_record/inheritance.rb +13 -3
  114. data/lib/active_record/insert_all.rb +179 -0
  115. data/lib/active_record/integration.rb +68 -16
  116. data/lib/active_record/internal_metadata.rb +10 -2
  117. data/lib/active_record/locking/optimistic.rb +5 -6
  118. data/lib/active_record/locking/pessimistic.rb +3 -3
  119. data/lib/active_record/log_subscriber.rb +7 -26
  120. data/lib/active_record/middleware/database_selector.rb +75 -0
  121. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  122. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  123. data/lib/active_record/migration.rb +100 -81
  124. data/lib/active_record/migration/command_recorder.rb +50 -6
  125. data/lib/active_record/migration/compatibility.rb +91 -64
  126. data/lib/active_record/model_schema.rb +34 -10
  127. data/lib/active_record/nested_attributes.rb +2 -2
  128. data/lib/active_record/no_touching.rb +7 -0
  129. data/lib/active_record/persistence.rb +233 -28
  130. data/lib/active_record/query_cache.rb +11 -4
  131. data/lib/active_record/querying.rb +33 -21
  132. data/lib/active_record/railtie.rb +81 -46
  133. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  134. data/lib/active_record/railties/controller_runtime.rb +30 -35
  135. data/lib/active_record/railties/databases.rake +196 -46
  136. data/lib/active_record/reflection.rb +42 -44
  137. data/lib/active_record/relation.rb +320 -70
  138. data/lib/active_record/relation/batches.rb +13 -10
  139. data/lib/active_record/relation/calculations.rb +67 -57
  140. data/lib/active_record/relation/delegation.rb +48 -35
  141. data/lib/active_record/relation/finder_methods.rb +30 -30
  142. data/lib/active_record/relation/merger.rb +19 -25
  143. data/lib/active_record/relation/predicate_builder.rb +18 -15
  144. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -6
  145. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  146. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  147. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  148. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  149. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  150. data/lib/active_record/relation/query_attribute.rb +17 -10
  151. data/lib/active_record/relation/query_methods.rb +236 -73
  152. data/lib/active_record/relation/spawn_methods.rb +1 -1
  153. data/lib/active_record/relation/where_clause.rb +14 -10
  154. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  155. data/lib/active_record/result.rb +30 -11
  156. data/lib/active_record/sanitization.rb +32 -40
  157. data/lib/active_record/schema.rb +2 -11
  158. data/lib/active_record/schema_dumper.rb +22 -7
  159. data/lib/active_record/schema_migration.rb +5 -1
  160. data/lib/active_record/scoping.rb +8 -8
  161. data/lib/active_record/scoping/default.rb +6 -7
  162. data/lib/active_record/scoping/named.rb +21 -15
  163. data/lib/active_record/statement_cache.rb +32 -5
  164. data/lib/active_record/store.rb +87 -8
  165. data/lib/active_record/table_metadata.rb +10 -17
  166. data/lib/active_record/tasks/database_tasks.rb +195 -26
  167. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
  168. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  169. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  170. data/lib/active_record/test_databases.rb +23 -0
  171. data/lib/active_record/test_fixtures.rb +224 -0
  172. data/lib/active_record/timestamp.rb +39 -25
  173. data/lib/active_record/touch_later.rb +4 -2
  174. data/lib/active_record/transactions.rb +57 -66
  175. data/lib/active_record/translation.rb +1 -1
  176. data/lib/active_record/type.rb +3 -4
  177. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  178. data/lib/active_record/type_caster/connection.rb +15 -14
  179. data/lib/active_record/type_caster/map.rb +1 -4
  180. data/lib/active_record/validations.rb +1 -0
  181. data/lib/active_record/validations/uniqueness.rb +15 -27
  182. data/lib/arel.rb +58 -0
  183. data/lib/arel/alias_predication.rb +9 -0
  184. data/lib/arel/attributes.rb +22 -0
  185. data/lib/arel/attributes/attribute.rb +37 -0
  186. data/lib/arel/collectors/bind.rb +24 -0
  187. data/lib/arel/collectors/composite.rb +31 -0
  188. data/lib/arel/collectors/plain_string.rb +20 -0
  189. data/lib/arel/collectors/sql_string.rb +20 -0
  190. data/lib/arel/collectors/substitute_binds.rb +28 -0
  191. data/lib/arel/crud.rb +42 -0
  192. data/lib/arel/delete_manager.rb +18 -0
  193. data/lib/arel/errors.rb +9 -0
  194. data/lib/arel/expressions.rb +29 -0
  195. data/lib/arel/factory_methods.rb +49 -0
  196. data/lib/arel/insert_manager.rb +49 -0
  197. data/lib/arel/math.rb +45 -0
  198. data/lib/arel/nodes.rb +68 -0
  199. data/lib/arel/nodes/and.rb +32 -0
  200. data/lib/arel/nodes/ascending.rb +23 -0
  201. data/lib/arel/nodes/binary.rb +52 -0
  202. data/lib/arel/nodes/bind_param.rb +36 -0
  203. data/lib/arel/nodes/case.rb +55 -0
  204. data/lib/arel/nodes/casted.rb +50 -0
  205. data/lib/arel/nodes/comment.rb +29 -0
  206. data/lib/arel/nodes/count.rb +12 -0
  207. data/lib/arel/nodes/delete_statement.rb +45 -0
  208. data/lib/arel/nodes/descending.rb +23 -0
  209. data/lib/arel/nodes/equality.rb +18 -0
  210. data/lib/arel/nodes/extract.rb +24 -0
  211. data/lib/arel/nodes/false.rb +16 -0
  212. data/lib/arel/nodes/full_outer_join.rb +8 -0
  213. data/lib/arel/nodes/function.rb +44 -0
  214. data/lib/arel/nodes/grouping.rb +8 -0
  215. data/lib/arel/nodes/in.rb +8 -0
  216. data/lib/arel/nodes/infix_operation.rb +80 -0
  217. data/lib/arel/nodes/inner_join.rb +8 -0
  218. data/lib/arel/nodes/insert_statement.rb +37 -0
  219. data/lib/arel/nodes/join_source.rb +20 -0
  220. data/lib/arel/nodes/matches.rb +18 -0
  221. data/lib/arel/nodes/named_function.rb +23 -0
  222. data/lib/arel/nodes/node.rb +50 -0
  223. data/lib/arel/nodes/node_expression.rb +13 -0
  224. data/lib/arel/nodes/outer_join.rb +8 -0
  225. data/lib/arel/nodes/over.rb +15 -0
  226. data/lib/arel/nodes/regexp.rb +16 -0
  227. data/lib/arel/nodes/right_outer_join.rb +8 -0
  228. data/lib/arel/nodes/select_core.rb +67 -0
  229. data/lib/arel/nodes/select_statement.rb +41 -0
  230. data/lib/arel/nodes/sql_literal.rb +16 -0
  231. data/lib/arel/nodes/string_join.rb +11 -0
  232. data/lib/arel/nodes/table_alias.rb +27 -0
  233. data/lib/arel/nodes/terminal.rb +16 -0
  234. data/lib/arel/nodes/true.rb +16 -0
  235. data/lib/arel/nodes/unary.rb +45 -0
  236. data/lib/arel/nodes/unary_operation.rb +20 -0
  237. data/lib/arel/nodes/unqualified_column.rb +22 -0
  238. data/lib/arel/nodes/update_statement.rb +41 -0
  239. data/lib/arel/nodes/values_list.rb +9 -0
  240. data/lib/arel/nodes/window.rb +126 -0
  241. data/lib/arel/nodes/with.rb +11 -0
  242. data/lib/arel/order_predications.rb +13 -0
  243. data/lib/arel/predications.rb +257 -0
  244. data/lib/arel/select_manager.rb +271 -0
  245. data/lib/arel/table.rb +110 -0
  246. data/lib/arel/tree_manager.rb +72 -0
  247. data/lib/arel/update_manager.rb +34 -0
  248. data/lib/arel/visitors.rb +20 -0
  249. data/lib/arel/visitors/depth_first.rb +204 -0
  250. data/lib/arel/visitors/dot.rb +297 -0
  251. data/lib/arel/visitors/ibm_db.rb +34 -0
  252. data/lib/arel/visitors/informix.rb +62 -0
  253. data/lib/arel/visitors/mssql.rb +157 -0
  254. data/lib/arel/visitors/mysql.rb +83 -0
  255. data/lib/arel/visitors/oracle.rb +159 -0
  256. data/lib/arel/visitors/oracle12.rb +66 -0
  257. data/lib/arel/visitors/postgresql.rb +110 -0
  258. data/lib/arel/visitors/sqlite.rb +39 -0
  259. data/lib/arel/visitors/to_sql.rb +889 -0
  260. data/lib/arel/visitors/visitor.rb +46 -0
  261. data/lib/arel/visitors/where_sql.rb +23 -0
  262. data/lib/arel/window_predications.rb +9 -0
  263. data/lib/rails/generators/active_record/migration.rb +14 -1
  264. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  265. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  266. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  267. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  268. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  269. metadata +111 -27
  270. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -14,6 +14,8 @@ module ActiveRecord
14
14
  # * change_column
15
15
  # * change_column_default (must supply a :from and :to option)
16
16
  # * change_column_null
17
+ # * change_column_comment (must supply a :from and :to option)
18
+ # * change_table_comment (must supply a :from and :to option)
17
19
  # * create_join_table
18
20
  # * create_table
19
21
  # * disable_extension
@@ -35,7 +37,8 @@ module ActiveRecord
35
37
  :change_column_default, :add_reference, :remove_reference, :transaction,
36
38
  :drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension,
37
39
  :change_column, :execute, :remove_columns, :change_column_null,
38
- :add_foreign_key, :remove_foreign_key
40
+ :add_foreign_key, :remove_foreign_key,
41
+ :change_column_comment, :change_table_comment
39
42
  ]
40
43
  include JoinTable
41
44
 
@@ -85,7 +88,7 @@ module ActiveRecord
85
88
  # invert the +command+.
86
89
  def inverse_of(command, args, &block)
87
90
  method = :"invert_#{command}"
88
- raise IrreversibleMigration, <<-MSG.strip_heredoc unless respond_to?(method, true)
91
+ raise IrreversibleMigration, <<~MSG unless respond_to?(method, true)
89
92
  This migration uses #{command}, which is not automatically reversible.
90
93
  To make the migration reversible you can either:
91
94
  1. Define #up and #down methods in place of the #change method.
@@ -108,11 +111,17 @@ module ActiveRecord
108
111
  yield delegate.update_table_definition(table_name, self)
109
112
  end
110
113
 
114
+ def replay(migration)
115
+ commands.each do |cmd, args, block|
116
+ migration.send(cmd, *args, &block)
117
+ end
118
+ end
119
+
111
120
  private
112
121
 
113
122
  module StraightReversions # :nodoc:
114
123
  private
115
- { transaction: :transaction,
124
+ {
116
125
  execute_block: :execute_block,
117
126
  create_table: :drop_table,
118
127
  create_join_table: :drop_join_table,
@@ -133,6 +142,17 @@ module ActiveRecord
133
142
 
134
143
  include StraightReversions
135
144
 
145
+ def invert_transaction(args)
146
+ sub_recorder = CommandRecorder.new(delegate)
147
+ sub_recorder.revert { yield }
148
+
149
+ invertions_proc = proc {
150
+ sub_recorder.replay(self)
151
+ }
152
+
153
+ [:transaction, args, invertions_proc]
154
+ end
155
+
136
156
  def invert_drop_table(args, &block)
137
157
  if args.size == 1 && block == nil
138
158
  raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
@@ -214,15 +234,39 @@ module ActiveRecord
214
234
  end
215
235
 
216
236
  def invert_remove_foreign_key(args)
217
- from_table, to_table, remove_options = args
218
- raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil? || to_table.is_a?(Hash)
237
+ options = args.extract_options!
238
+ from_table, to_table = args
239
+
240
+ to_table ||= options.delete(:to_table)
241
+
242
+ raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil?
219
243
 
220
244
  reversed_args = [from_table, to_table]
221
- reversed_args << remove_options if remove_options
245
+ reversed_args << options unless options.empty?
222
246
 
223
247
  [:add_foreign_key, reversed_args]
224
248
  end
225
249
 
250
+ def invert_change_column_comment(args)
251
+ table, column, options = *args
252
+
253
+ unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
254
+ raise ActiveRecord::IrreversibleMigration, "change_column_comment is only reversible if given a :from and :to option."
255
+ end
256
+
257
+ [:change_column_comment, [table, column, from: options[:to], to: options[:from]]]
258
+ end
259
+
260
+ def invert_change_table_comment(args)
261
+ table, options = *args
262
+
263
+ unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
264
+ raise ActiveRecord::IrreversibleMigration, "change_table_comment is only reversible if given a :from and :to option."
265
+ end
266
+
267
+ [:change_table_comment, [table, from: options[:to], to: options[:from]]]
268
+ end
269
+
226
270
  def respond_to_missing?(method, _)
227
271
  super || delegate.respond_to?(method)
228
272
  end
@@ -13,24 +13,92 @@ module ActiveRecord
13
13
  const_get(name)
14
14
  end
15
15
 
16
- V5_2 = Current
16
+ V6_0 = Current
17
+
18
+ class V5_2 < V6_0
19
+ module TableDefinition
20
+ def timestamps(**options)
21
+ options[:precision] ||= nil
22
+ super
23
+ end
24
+ end
25
+
26
+ module CommandRecorder
27
+ def invert_transaction(args, &block)
28
+ [:transaction, args, block]
29
+ end
30
+
31
+ def invert_change_column_comment(args)
32
+ table_name, column_name, comment = args
33
+ [:change_column_comment, [table_name, column_name, from: comment, to: comment]]
34
+ end
35
+
36
+ def invert_change_table_comment(args)
37
+ table_name, comment = args
38
+ [:change_table_comment, [table_name, from: comment, to: comment]]
39
+ end
40
+ end
41
+
42
+ def create_table(table_name, **options)
43
+ if block_given?
44
+ super { |t| yield compatible_table_definition(t) }
45
+ else
46
+ super
47
+ end
48
+ end
49
+
50
+ def change_table(table_name, **options)
51
+ if block_given?
52
+ super { |t| yield compatible_table_definition(t) }
53
+ else
54
+ super
55
+ end
56
+ end
57
+
58
+ def create_join_table(table_1, table_2, **options)
59
+ if block_given?
60
+ super { |t| yield compatible_table_definition(t) }
61
+ else
62
+ super
63
+ end
64
+ end
65
+
66
+ def add_timestamps(table_name, **options)
67
+ options[:precision] ||= nil
68
+ super
69
+ end
70
+
71
+ private
72
+ def compatible_table_definition(t)
73
+ class << t
74
+ prepend TableDefinition
75
+ end
76
+ t
77
+ end
78
+
79
+ def command_recorder
80
+ recorder = super
81
+ class << recorder
82
+ prepend CommandRecorder
83
+ end
84
+ recorder
85
+ end
86
+ end
17
87
 
18
88
  class V5_1 < V5_2
19
89
  def change_column(table_name, column_name, type, options = {})
20
- if adapter_name == "PostgreSQL"
21
- clear_cache!
22
- sql = connection.send(:change_column_sql, table_name, column_name, type, options)
23
- execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}"
24
- change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
25
- change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
26
- change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
90
+ if connection.adapter_name == "PostgreSQL"
91
+ super(table_name, column_name, type, options.except(:default, :null, :comment))
92
+ connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
93
+ connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
94
+ connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
27
95
  else
28
96
  super
29
97
  end
30
98
  end
31
99
 
32
100
  def create_table(table_name, options = {})
33
- if adapter_name == "Mysql2"
101
+ if connection.adapter_name == "Mysql2"
34
102
  super(table_name, options: "ENGINE=InnoDB", **options)
35
103
  else
36
104
  super
@@ -52,13 +120,13 @@ module ActiveRecord
52
120
  end
53
121
 
54
122
  def create_table(table_name, options = {})
55
- if adapter_name == "PostgreSQL"
123
+ if connection.adapter_name == "PostgreSQL"
56
124
  if options[:id] == :uuid && !options.key?(:default)
57
125
  options[:default] = "uuid_generate_v4()"
58
126
  end
59
127
  end
60
128
 
61
- unless adapter_name == "Mysql2" && options[:id] == :bigint
129
+ unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
62
130
  if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
63
131
  options[:default] = nil
64
132
  end
@@ -71,35 +139,12 @@ module ActiveRecord
71
139
  options[:id] = :integer
72
140
  end
73
141
 
74
- if block_given?
75
- super do |t|
76
- yield compatible_table_definition(t)
77
- end
78
- else
79
- super
80
- end
81
- end
82
-
83
- def change_table(table_name, options = {})
84
- if block_given?
85
- super do |t|
86
- yield compatible_table_definition(t)
87
- end
88
- else
89
- super
90
- end
142
+ super
91
143
  end
92
144
 
93
145
  def create_join_table(table_1, table_2, column_options: {}, **options)
94
146
  column_options.reverse_merge!(type: :integer)
95
-
96
- if block_given?
97
- super do |t|
98
- yield compatible_table_definition(t)
99
- end
100
- else
101
- super
102
- end
147
+ super
103
148
  end
104
149
 
105
150
  def add_column(table_name, column_name, type, options = {})
@@ -120,7 +165,7 @@ module ActiveRecord
120
165
  class << t
121
166
  prepend TableDefinition
122
167
  end
123
- t
168
+ super
124
169
  end
125
170
  end
126
171
 
@@ -138,33 +183,13 @@ module ActiveRecord
138
183
  end
139
184
  end
140
185
 
141
- def create_table(table_name, options = {})
142
- if block_given?
143
- super do |t|
144
- yield compatible_table_definition(t)
145
- end
146
- else
147
- super
148
- end
149
- end
150
-
151
- def change_table(table_name, options = {})
152
- if block_given?
153
- super do |t|
154
- yield compatible_table_definition(t)
155
- end
156
- else
157
- super
158
- end
159
- end
160
-
161
- def add_reference(*, **options)
186
+ def add_reference(table_name, ref_name, **options)
162
187
  options[:index] ||= false
163
188
  super
164
189
  end
165
190
  alias :add_belongs_to :add_reference
166
191
 
167
- def add_timestamps(_, **options)
192
+ def add_timestamps(table_name, **options)
168
193
  options[:null] = true if options[:null].nil?
169
194
  super
170
195
  end
@@ -175,7 +200,7 @@ module ActiveRecord
175
200
  if options[:name].present?
176
201
  options[:name].to_s
177
202
  else
178
- index_name(table_name, column: column_names)
203
+ connection.index_name(table_name, column: column_names)
179
204
  end
180
205
  super
181
206
  end
@@ -195,15 +220,17 @@ module ActiveRecord
195
220
  end
196
221
 
197
222
  def index_name_for_remove(table_name, options = {})
198
- index_name = index_name(table_name, options)
223
+ index_name = connection.index_name(table_name, options)
199
224
 
200
- unless index_name_exists?(table_name, index_name)
225
+ unless connection.index_name_exists?(table_name, index_name)
201
226
  if options.is_a?(Hash) && options.has_key?(:name)
202
227
  options_without_column = options.dup
203
228
  options_without_column.delete :column
204
- index_name_without_column = index_name(table_name, options_without_column)
229
+ index_name_without_column = connection.index_name(table_name, options_without_column)
205
230
 
206
- return index_name_without_column if index_name_exists?(table_name, index_name_without_column)
231
+ if connection.index_name_exists?(table_name, index_name_without_column)
232
+ return index_name_without_column
233
+ end
207
234
  end
208
235
 
209
236
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
@@ -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
@@ -375,7 +391,7 @@ module ActiveRecord
375
391
  # default values when instantiating the Active Record object for this table.
376
392
  def column_defaults
377
393
  load_schema
378
- @column_defaults ||= _default_attributes.to_hash
394
+ @column_defaults ||= _default_attributes.deep_dup.to_hash
379
395
  end
380
396
 
381
397
  def _default_attributes # :nodoc:
@@ -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
@@ -459,6 +480,9 @@ module ActiveRecord
459
480
  load_schema!
460
481
 
461
482
  @schema_loaded = true
483
+ rescue
484
+ reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
485
+ raise
462
486
  end
463
487
  end
464
488
 
@@ -477,6 +501,7 @@ module ActiveRecord
477
501
  def reload_schema_from_cache
478
502
  @arel_table = nil
479
503
  @column_names = nil
504
+ @symbol_column_to_string_name_hash = nil
480
505
  @attribute_types = nil
481
506
  @content_columns = nil
482
507
  @default_attributes = nil
@@ -501,19 +526,18 @@ module ActiveRecord
501
526
 
502
527
  # Computes and returns a table name according to default conventions.
503
528
  def compute_table_name
504
- base = base_class
505
- if self == base
529
+ if base_class?
506
530
  # 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
531
+ if module_parent < Base && !module_parent.abstract_class?
532
+ contained = module_parent.table_name
533
+ contained = contained.singularize if module_parent.pluralize_table_names
510
534
  contained += "_"
511
535
  end
512
536
 
513
537
  "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
514
538
  else
515
539
  # STI subclasses always use their superclass' table.
516
- base.table_name
540
+ base_class.table_name
517
541
  end
518
542
  end
519
543
  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)