activerecord 5.2.8.1 → 6.1.6.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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1255 -596
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +8 -17
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +44 -34
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -18
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +69 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +47 -34
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +137 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +46 -9
  47. data/lib/active_record/autosave_association.rb +57 -42
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +1 -2
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +211 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +333 -98
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +116 -59
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +109 -93
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +476 -187
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +4 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +49 -6
  199. data/lib/active_record/store.rb +88 -9
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +287 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +62 -118
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +116 -30
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -8,12 +8,15 @@ module ActiveRecord
8
8
  #
9
9
  # * add_column
10
10
  # * add_foreign_key
11
+ # * add_check_constraint
11
12
  # * add_index
12
13
  # * add_reference
13
14
  # * add_timestamps
14
15
  # * change_column
15
16
  # * change_column_default (must supply a :from and :to option)
16
17
  # * change_column_null
18
+ # * change_column_comment (must supply a :from and :to option)
19
+ # * change_table_comment (must supply a :from and :to option)
17
20
  # * create_join_table
18
21
  # * create_table
19
22
  # * disable_extension
@@ -23,6 +26,7 @@ module ActiveRecord
23
26
  # * remove_column (must supply a type)
24
27
  # * remove_columns (must specify at least one column name or more)
25
28
  # * remove_foreign_key (must supply a second table)
29
+ # * remove_check_constraint
26
30
  # * remove_index
27
31
  # * remove_reference
28
32
  # * remove_timestamps
@@ -30,12 +34,15 @@ module ActiveRecord
30
34
  # * rename_index
31
35
  # * rename_table
32
36
  class CommandRecorder
33
- ReversibleAndIrreversibleMethods = [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
37
+ ReversibleAndIrreversibleMethods = [
38
+ :create_table, :create_join_table, :rename_table, :add_column, :remove_column,
34
39
  :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
35
40
  :change_column_default, :add_reference, :remove_reference, :transaction,
36
41
  :drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension,
37
42
  :change_column, :execute, :remove_columns, :change_column_null,
38
- :add_foreign_key, :remove_foreign_key
43
+ :add_foreign_key, :remove_foreign_key,
44
+ :change_column_comment, :change_table_comment,
45
+ :add_check_constraint, :remove_check_constraint
39
46
  ]
40
47
  include JoinTable
41
48
 
@@ -81,11 +88,16 @@ module ActiveRecord
81
88
  # recorder.inverse_of(:rename_table, [:old, :new])
82
89
  # # => [:rename_table, [:new, :old]]
83
90
  #
91
+ # If the inverse of a command requires several commands, returns array of commands.
92
+ #
93
+ # recorder.inverse_of(:remove_columns, [:some_table, :foo, :bar, type: :string])
94
+ # # => [[:add_column, :some_table, :foo, :string], [:add_column, :some_table, :bar, :string]]
95
+ #
84
96
  # This method will raise an +IrreversibleMigration+ exception if it cannot
85
97
  # invert the +command+.
86
98
  def inverse_of(command, args, &block)
87
99
  method = :"invert_#{command}"
88
- raise IrreversibleMigration, <<-MSG.strip_heredoc unless respond_to?(method, true)
100
+ raise IrreversibleMigration, <<~MSG unless respond_to?(method, true)
89
101
  This migration uses #{command}, which is not automatically reversible.
90
102
  To make the migration reversible you can either:
91
103
  1. Define #up and #down methods in place of the #change method.
@@ -100,25 +112,34 @@ module ActiveRecord
100
112
  record(:"#{method}", args, &block) # record(:create_table, args, &block)
101
113
  end # end
102
114
  EOV
115
+ ruby2_keywords(method) if respond_to?(:ruby2_keywords, true)
103
116
  end
104
117
  alias :add_belongs_to :add_reference
105
118
  alias :remove_belongs_to :remove_reference
106
119
 
107
- def change_table(table_name, options = {}) # :nodoc:
120
+ def change_table(table_name, **options) # :nodoc:
108
121
  yield delegate.update_table_definition(table_name, self)
109
122
  end
110
123
 
111
- private
124
+ def replay(migration)
125
+ commands.each do |cmd, args, block|
126
+ migration.send(cmd, *args, &block)
127
+ end
128
+ end
112
129
 
130
+ private
113
131
  module StraightReversions # :nodoc:
114
132
  private
115
- { transaction: :transaction,
133
+ {
116
134
  execute_block: :execute_block,
117
135
  create_table: :drop_table,
118
136
  create_join_table: :drop_join_table,
119
137
  add_column: :remove_column,
138
+ add_index: :remove_index,
120
139
  add_timestamps: :remove_timestamps,
121
140
  add_reference: :remove_reference,
141
+ add_foreign_key: :remove_foreign_key,
142
+ add_check_constraint: :remove_check_constraint,
122
143
  enable_extension: :disable_extension
123
144
  }.each do |cmd, inv|
124
145
  [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
@@ -133,6 +154,17 @@ module ActiveRecord
133
154
 
134
155
  include StraightReversions
135
156
 
157
+ def invert_transaction(args)
158
+ sub_recorder = CommandRecorder.new(delegate)
159
+ sub_recorder.revert { yield }
160
+
161
+ invertions_proc = proc {
162
+ sub_recorder.replay(self)
163
+ }
164
+
165
+ [:transaction, args, invertions_proc]
166
+ end
167
+
136
168
  def invert_drop_table(args, &block)
137
169
  if args.size == 1 && block == nil
138
170
  raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
@@ -149,44 +181,49 @@ module ActiveRecord
149
181
  super
150
182
  end
151
183
 
184
+ def invert_remove_columns(args)
185
+ unless args[-1].is_a?(Hash) && args[-1].has_key?(:type)
186
+ raise ActiveRecord::IrreversibleMigration, "remove_columns is only reversible if given a type."
187
+ end
188
+
189
+ [:add_columns, args]
190
+ end
191
+
152
192
  def invert_rename_index(args)
153
- [:rename_index, [args.first] + args.last(2).reverse]
193
+ table_name, old_name, new_name = args
194
+ [:rename_index, [table_name, new_name, old_name]]
154
195
  end
155
196
 
156
197
  def invert_rename_column(args)
157
- [:rename_column, [args.first] + args.last(2).reverse]
198
+ table_name, old_name, new_name = args
199
+ [:rename_column, [table_name, new_name, old_name]]
158
200
  end
159
201
 
160
- def invert_add_index(args)
161
- table, columns, options = *args
162
- options ||= {}
163
-
164
- options_hash = options.slice(:name, :algorithm)
165
- options_hash[:column] = columns if !options_hash[:name]
202
+ def invert_remove_index(args)
203
+ options = args.extract_options!
204
+ table, columns = args
166
205
 
167
- [:remove_index, [table, options_hash]]
168
- end
206
+ columns ||= options.delete(:column)
169
207
 
170
- def invert_remove_index(args)
171
- table, options_or_column = *args
172
- if (options = options_or_column).is_a?(Hash)
173
- unless options[:column]
174
- raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option."
175
- end
176
- options = options.dup
177
- [:add_index, [table, options.delete(:column), options]]
178
- elsif (column = options_or_column).present?
179
- [:add_index, [table, column]]
208
+ unless columns
209
+ raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option."
180
210
  end
211
+
212
+ options.delete(:if_exists)
213
+
214
+ args = [table, columns]
215
+ args << options unless options.empty?
216
+
217
+ [:add_index, args]
181
218
  end
182
219
 
183
220
  alias :invert_add_belongs_to :invert_add_reference
184
221
  alias :invert_remove_belongs_to :invert_remove_reference
185
222
 
186
223
  def invert_change_column_default(args)
187
- table, column, options = *args
224
+ table, column, options = args
188
225
 
189
- unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
226
+ unless options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
190
227
  raise ActiveRecord::IrreversibleMigration, "change_column_default is only reversible if given a :from and :to option."
191
228
  end
192
229
 
@@ -198,29 +235,43 @@ module ActiveRecord
198
235
  [:change_column_null, args]
199
236
  end
200
237
 
201
- def invert_add_foreign_key(args)
202
- from_table, to_table, add_options = args
203
- add_options ||= {}
238
+ def invert_remove_foreign_key(args)
239
+ options = args.extract_options!
240
+ from_table, to_table = args
204
241
 
205
- if add_options[:name]
206
- options = { name: add_options[:name] }
207
- elsif add_options[:column]
208
- options = { column: add_options[:column] }
209
- else
210
- options = to_table
242
+ to_table ||= options.delete(:to_table)
243
+
244
+ raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil?
245
+
246
+ reversed_args = [from_table, to_table]
247
+ reversed_args << options unless options.empty?
248
+
249
+ [:add_foreign_key, reversed_args]
250
+ end
251
+
252
+ def invert_change_column_comment(args)
253
+ table, column, options = args
254
+
255
+ unless options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
256
+ raise ActiveRecord::IrreversibleMigration, "change_column_comment is only reversible if given a :from and :to option."
211
257
  end
212
258
 
213
- [:remove_foreign_key, [from_table, options]]
259
+ [:change_column_comment, [table, column, from: options[:to], to: options[:from]]]
214
260
  end
215
261
 
216
- 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)
262
+ def invert_change_table_comment(args)
263
+ table, options = args
219
264
 
220
- reversed_args = [from_table, to_table]
221
- reversed_args << remove_options if remove_options
265
+ unless options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
266
+ raise ActiveRecord::IrreversibleMigration, "change_table_comment is only reversible if given a :from and :to option."
267
+ end
222
268
 
223
- [:add_foreign_key, reversed_args]
269
+ [:change_table_comment, [table, from: options[:to], to: options[:from]]]
270
+ end
271
+
272
+ def invert_remove_check_constraint(args)
273
+ raise ActiveRecord::IrreversibleMigration, "remove_check_constraint is only reversible if given an expression." if args.size < 2
274
+ super
224
275
  end
225
276
 
226
277
  def respond_to_missing?(method, _)
@@ -235,6 +286,7 @@ module ActiveRecord
235
286
  super
236
287
  end
237
288
  end
289
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
238
290
  end
239
291
  end
240
292
  end
@@ -13,12 +13,138 @@ module ActiveRecord
13
13
  const_get(name)
14
14
  end
15
15
 
16
- V5_2 = Current
16
+ V6_1 = Current
17
+
18
+ class V6_0 < V6_1
19
+ class ReferenceDefinition < ConnectionAdapters::ReferenceDefinition
20
+ def index_options(table_name)
21
+ as_options(index)
22
+ end
23
+ end
24
+
25
+ module TableDefinition
26
+ def references(*args, **options)
27
+ options[:_uses_legacy_reference_index_name] = true
28
+ super
29
+ end
30
+ alias :belongs_to :references
31
+ end
32
+
33
+ def create_table(table_name, **options)
34
+ if block_given?
35
+ super { |t| yield compatible_table_definition(t) }
36
+ else
37
+ super
38
+ end
39
+ end
40
+
41
+ def change_table(table_name, **options)
42
+ if block_given?
43
+ super { |t| yield compatible_table_definition(t) }
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ def create_join_table(table_1, table_2, **options)
50
+ if block_given?
51
+ super { |t| yield compatible_table_definition(t) }
52
+ else
53
+ super
54
+ end
55
+ end
56
+
57
+ def add_reference(table_name, ref_name, **options)
58
+ if connection.adapter_name == "SQLite"
59
+ options[:type] = :integer
60
+ end
61
+
62
+ options[:_uses_legacy_reference_index_name] = true
63
+ super
64
+ end
65
+ alias :add_belongs_to :add_reference
66
+
67
+ private
68
+ def compatible_table_definition(t)
69
+ class << t
70
+ prepend TableDefinition
71
+ end
72
+ t
73
+ end
74
+ end
75
+
76
+ class V5_2 < V6_0
77
+ module TableDefinition
78
+ def timestamps(**options)
79
+ options[:precision] ||= nil
80
+ super
81
+ end
82
+ end
83
+
84
+ module CommandRecorder
85
+ def invert_transaction(args, &block)
86
+ [:transaction, args, block]
87
+ end
88
+
89
+ def invert_change_column_comment(args)
90
+ [:change_column_comment, args]
91
+ end
92
+
93
+ def invert_change_table_comment(args)
94
+ [:change_table_comment, args]
95
+ end
96
+ end
97
+
98
+ def create_table(table_name, **options)
99
+ if block_given?
100
+ super { |t| yield compatible_table_definition(t) }
101
+ else
102
+ super
103
+ end
104
+ end
105
+
106
+ def change_table(table_name, **options)
107
+ if block_given?
108
+ super { |t| yield compatible_table_definition(t) }
109
+ else
110
+ super
111
+ end
112
+ end
113
+
114
+ def create_join_table(table_1, table_2, **options)
115
+ if block_given?
116
+ super { |t| yield compatible_table_definition(t) }
117
+ else
118
+ super
119
+ end
120
+ end
121
+
122
+ def add_timestamps(table_name, **options)
123
+ options[:precision] ||= nil
124
+ super
125
+ end
126
+
127
+ private
128
+ def compatible_table_definition(t)
129
+ class << t
130
+ prepend TableDefinition
131
+ end
132
+ super
133
+ end
134
+
135
+ def command_recorder
136
+ recorder = super
137
+ class << recorder
138
+ prepend CommandRecorder
139
+ end
140
+ recorder
141
+ end
142
+ end
17
143
 
18
144
  class V5_1 < V5_2
19
- def change_column(table_name, column_name, type, options = {})
145
+ def change_column(table_name, column_name, type, **options)
20
146
  if connection.adapter_name == "PostgreSQL"
21
- super(table_name, column_name, type, options.except(:default, :null, :comment))
147
+ super(table_name, column_name, type, **options.except(:default, :null, :comment))
22
148
  connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
23
149
  connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
24
150
  connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
@@ -27,7 +153,7 @@ module ActiveRecord
27
153
  end
28
154
  end
29
155
 
30
- def create_table(table_name, options = {})
156
+ def create_table(table_name, **options)
31
157
  if connection.adapter_name == "Mysql2"
32
158
  super(table_name, options: "ENGINE=InnoDB", **options)
33
159
  else
@@ -49,7 +175,7 @@ module ActiveRecord
49
175
  alias :belongs_to :references
50
176
  end
51
177
 
52
- def create_table(table_name, options = {})
178
+ def create_table(table_name, **options)
53
179
  if connection.adapter_name == "PostgreSQL"
54
180
  if options[:id] == :uuid && !options.key?(:default)
55
181
  options[:default] = "uuid_generate_v4()"
@@ -69,38 +195,15 @@ module ActiveRecord
69
195
  options[:id] = :integer
70
196
  end
71
197
 
72
- if block_given?
73
- super do |t|
74
- yield compatible_table_definition(t)
75
- end
76
- else
77
- super
78
- end
79
- end
80
-
81
- def change_table(table_name, options = {})
82
- if block_given?
83
- super do |t|
84
- yield compatible_table_definition(t)
85
- end
86
- else
87
- super
88
- end
198
+ super
89
199
  end
90
200
 
91
201
  def create_join_table(table_1, table_2, column_options: {}, **options)
92
202
  column_options.reverse_merge!(type: :integer)
93
-
94
- if block_given?
95
- super do |t|
96
- yield compatible_table_definition(t)
97
- end
98
- else
99
- super
100
- end
203
+ super
101
204
  end
102
205
 
103
- def add_column(table_name, column_name, type, options = {})
206
+ def add_column(table_name, column_name, type, **options)
104
207
  if type == :primary_key
105
208
  type = :integer
106
209
  options[:primary_key] = true
@@ -118,7 +221,7 @@ module ActiveRecord
118
221
  class << t
119
222
  prepend TableDefinition
120
223
  end
121
- t
224
+ super
122
225
  end
123
226
  end
124
227
 
@@ -136,38 +239,18 @@ module ActiveRecord
136
239
  end
137
240
  end
138
241
 
139
- def create_table(table_name, options = {})
140
- if block_given?
141
- super do |t|
142
- yield compatible_table_definition(t)
143
- end
144
- else
145
- super
146
- end
147
- end
148
-
149
- def change_table(table_name, options = {})
150
- if block_given?
151
- super do |t|
152
- yield compatible_table_definition(t)
153
- end
154
- else
155
- super
156
- end
157
- end
158
-
159
- def add_reference(*, **options)
242
+ def add_reference(table_name, ref_name, **options)
160
243
  options[:index] ||= false
161
244
  super
162
245
  end
163
246
  alias :add_belongs_to :add_reference
164
247
 
165
- def add_timestamps(_, **options)
248
+ def add_timestamps(table_name, **options)
166
249
  options[:null] = true if options[:null].nil?
167
250
  super
168
251
  end
169
252
 
170
- def index_exists?(table_name, column_name, options = {})
253
+ def index_exists?(table_name, column_name, **options)
171
254
  column_names = Array(column_name).map(&:to_s)
172
255
  options[:name] =
173
256
  if options[:name].present?
@@ -178,10 +261,9 @@ module ActiveRecord
178
261
  super
179
262
  end
180
263
 
181
- def remove_index(table_name, options = {})
182
- options = { column: options } unless options.is_a?(Hash)
183
- options[:name] = index_name_for_remove(table_name, options)
184
- super(table_name, options)
264
+ def remove_index(table_name, column_name = nil, **options)
265
+ options[:name] = index_name_for_remove(table_name, column_name, options)
266
+ super
185
267
  end
186
268
 
187
269
  private
@@ -192,13 +274,12 @@ module ActiveRecord
192
274
  super
193
275
  end
194
276
 
195
- def index_name_for_remove(table_name, options = {})
196
- index_name = connection.index_name(table_name, options)
277
+ def index_name_for_remove(table_name, column_name, options)
278
+ index_name = connection.index_name(table_name, column_name || options)
197
279
 
198
280
  unless connection.index_name_exists?(table_name, index_name)
199
- if options.is_a?(Hash) && options.has_key?(:name)
200
- options_without_column = options.dup
201
- options_without_column.delete :column
281
+ if options.key?(:name)
282
+ options_without_column = options.except(:column)
202
283
  index_name_without_column = connection.index_name(table_name, options_without_column)
203
284
 
204
285
  if connection.index_name_exists?(table_name, index_name_without_column)
@@ -4,7 +4,6 @@ module ActiveRecord
4
4
  class Migration
5
5
  module JoinTable #:nodoc:
6
6
  private
7
-
8
7
  def find_join_table_name(table_1, table_2, options = {})
9
8
  options.delete(:table_name) || join_table_name(table_1, table_2)
10
9
  end