activerecord 5.2.8.1 → 6.0.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 (294) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +938 -573
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +5 -3
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/advisory_lock_base.rb +18 -0
  7. data/lib/active_record/aggregations.rb +4 -3
  8. data/lib/active_record/association_relation.rb +10 -8
  9. data/lib/active_record/associations/alias_tracker.rb +0 -1
  10. data/lib/active_record/associations/association.rb +55 -19
  11. data/lib/active_record/associations/association_scope.rb +11 -7
  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 +3 -13
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
  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 +19 -23
  22. data/lib/active_record/associations/collection_proxy.rb +14 -17
  23. data/lib/active_record/associations/foreign_association.rb +7 -0
  24. data/lib/active_record/associations/has_many_association.rb +2 -11
  25. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  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/join_association.rb +16 -10
  29. data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
  30. data/lib/active_record/associations/join_dependency.rb +47 -30
  31. data/lib/active_record/associations/preloader/association.rb +61 -41
  32. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  33. data/lib/active_record/associations/preloader.rb +44 -33
  34. data/lib/active_record/associations/singular_association.rb +2 -16
  35. data/lib/active_record/associations/through_association.rb +1 -1
  36. data/lib/active_record/associations.rb +21 -16
  37. data/lib/active_record/attribute_assignment.rb +7 -11
  38. data/lib/active_record/attribute_decorators.rb +0 -2
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
  40. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  41. data/lib/active_record/attribute_methods/primary_key.rb +15 -24
  42. data/lib/active_record/attribute_methods/query.rb +2 -3
  43. data/lib/active_record/attribute_methods/read.rb +15 -54
  44. data/lib/active_record/attribute_methods/serialization.rb +1 -2
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
  46. data/lib/active_record/attribute_methods/write.rb +17 -25
  47. data/lib/active_record/attribute_methods.rb +28 -100
  48. data/lib/active_record/attributes.rb +13 -1
  49. data/lib/active_record/autosave_association.rb +12 -14
  50. data/lib/active_record/base.rb +2 -3
  51. data/lib/active_record/callbacks.rb +6 -21
  52. data/lib/active_record/coders/yaml_column.rb +15 -6
  53. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
  54. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  55. data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
  56. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
  57. data/lib/active_record/connection_adapters/abstract/quoting.rb +77 -17
  58. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
  65. data/lib/active_record/connection_adapters/column.rb +17 -13
  66. data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
  67. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  68. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  69. data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
  70. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  71. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  72. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
  73. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  74. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  75. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
  76. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
  78. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  79. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  89. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  91. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
  92. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  93. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  94. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  96. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  97. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
  98. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  99. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
  101. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  102. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  103. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  104. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  105. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
  107. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  108. data/lib/active_record/connection_handling.rb +139 -26
  109. data/lib/active_record/core.rb +108 -67
  110. data/lib/active_record/counter_cache.rb +8 -30
  111. data/lib/active_record/database_configurations/database_config.rb +37 -0
  112. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  113. data/lib/active_record/database_configurations/url_config.rb +78 -0
  114. data/lib/active_record/database_configurations.rb +233 -0
  115. data/lib/active_record/dynamic_matchers.rb +3 -4
  116. data/lib/active_record/enum.rb +44 -7
  117. data/lib/active_record/errors.rb +15 -7
  118. data/lib/active_record/explain.rb +1 -2
  119. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  120. data/lib/active_record/fixture_set/render_context.rb +17 -0
  121. data/lib/active_record/fixture_set/table_row.rb +152 -0
  122. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  123. data/lib/active_record/fixtures.rb +144 -474
  124. data/lib/active_record/gem_version.rb +3 -3
  125. data/lib/active_record/inheritance.rb +13 -6
  126. data/lib/active_record/insert_all.rb +179 -0
  127. data/lib/active_record/integration.rb +68 -16
  128. data/lib/active_record/internal_metadata.rb +11 -3
  129. data/lib/active_record/locking/optimistic.rb +14 -7
  130. data/lib/active_record/locking/pessimistic.rb +3 -3
  131. data/lib/active_record/log_subscriber.rb +8 -27
  132. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  133. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  134. data/lib/active_record/middleware/database_selector.rb +74 -0
  135. data/lib/active_record/migration/command_recorder.rb +54 -22
  136. data/lib/active_record/migration/compatibility.rb +79 -52
  137. data/lib/active_record/migration/join_table.rb +0 -1
  138. data/lib/active_record/migration.rb +104 -85
  139. data/lib/active_record/model_schema.rb +62 -11
  140. data/lib/active_record/nested_attributes.rb +2 -4
  141. data/lib/active_record/no_touching.rb +9 -2
  142. data/lib/active_record/null_relation.rb +0 -1
  143. data/lib/active_record/persistence.rb +232 -29
  144. data/lib/active_record/query_cache.rb +11 -4
  145. data/lib/active_record/querying.rb +33 -21
  146. data/lib/active_record/railtie.rb +80 -61
  147. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  148. data/lib/active_record/railties/controller_runtime.rb +30 -35
  149. data/lib/active_record/railties/databases.rake +199 -46
  150. data/lib/active_record/reflection.rb +51 -51
  151. data/lib/active_record/relation/batches.rb +13 -11
  152. data/lib/active_record/relation/calculations.rb +55 -49
  153. data/lib/active_record/relation/delegation.rb +35 -50
  154. data/lib/active_record/relation/finder_methods.rb +23 -28
  155. data/lib/active_record/relation/from_clause.rb +4 -0
  156. data/lib/active_record/relation/merger.rb +12 -17
  157. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  158. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  159. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  160. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  161. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  162. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  163. data/lib/active_record/relation/predicate_builder.rb +5 -11
  164. data/lib/active_record/relation/query_attribute.rb +13 -8
  165. data/lib/active_record/relation/query_methods.rb +234 -69
  166. data/lib/active_record/relation/spawn_methods.rb +1 -2
  167. data/lib/active_record/relation/where_clause.rb +14 -11
  168. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  169. data/lib/active_record/relation.rb +326 -81
  170. data/lib/active_record/result.rb +30 -12
  171. data/lib/active_record/sanitization.rb +32 -40
  172. data/lib/active_record/schema.rb +2 -11
  173. data/lib/active_record/schema_dumper.rb +22 -7
  174. data/lib/active_record/schema_migration.rb +6 -2
  175. data/lib/active_record/scoping/default.rb +4 -6
  176. data/lib/active_record/scoping/named.rb +25 -16
  177. data/lib/active_record/scoping.rb +8 -9
  178. data/lib/active_record/statement_cache.rb +30 -3
  179. data/lib/active_record/store.rb +87 -8
  180. data/lib/active_record/suppressor.rb +2 -2
  181. data/lib/active_record/table_metadata.rb +23 -15
  182. data/lib/active_record/tasks/database_tasks.rb +194 -25
  183. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
  184. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
  185. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
  186. data/lib/active_record/test_databases.rb +23 -0
  187. data/lib/active_record/test_fixtures.rb +243 -0
  188. data/lib/active_record/timestamp.rb +39 -26
  189. data/lib/active_record/touch_later.rb +5 -4
  190. data/lib/active_record/transactions.rb +64 -73
  191. data/lib/active_record/translation.rb +1 -1
  192. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  193. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  194. data/lib/active_record/type/serialized.rb +0 -1
  195. data/lib/active_record/type/time.rb +10 -0
  196. data/lib/active_record/type/type_map.rb +0 -1
  197. data/lib/active_record/type/unsigned_integer.rb +0 -1
  198. data/lib/active_record/type.rb +3 -5
  199. data/lib/active_record/type_caster/connection.rb +15 -14
  200. data/lib/active_record/type_caster/map.rb +1 -4
  201. data/lib/active_record/validations/associated.rb +0 -1
  202. data/lib/active_record/validations/uniqueness.rb +15 -27
  203. data/lib/active_record/validations.rb +3 -3
  204. data/lib/active_record.rb +10 -2
  205. data/lib/arel/alias_predication.rb +9 -0
  206. data/lib/arel/attributes/attribute.rb +37 -0
  207. data/lib/arel/attributes.rb +22 -0
  208. data/lib/arel/collectors/bind.rb +24 -0
  209. data/lib/arel/collectors/composite.rb +31 -0
  210. data/lib/arel/collectors/plain_string.rb +20 -0
  211. data/lib/arel/collectors/sql_string.rb +20 -0
  212. data/lib/arel/collectors/substitute_binds.rb +28 -0
  213. data/lib/arel/crud.rb +42 -0
  214. data/lib/arel/delete_manager.rb +18 -0
  215. data/lib/arel/errors.rb +9 -0
  216. data/lib/arel/expressions.rb +29 -0
  217. data/lib/arel/factory_methods.rb +49 -0
  218. data/lib/arel/insert_manager.rb +49 -0
  219. data/lib/arel/math.rb +45 -0
  220. data/lib/arel/nodes/and.rb +32 -0
  221. data/lib/arel/nodes/ascending.rb +23 -0
  222. data/lib/arel/nodes/binary.rb +52 -0
  223. data/lib/arel/nodes/bind_param.rb +36 -0
  224. data/lib/arel/nodes/case.rb +55 -0
  225. data/lib/arel/nodes/casted.rb +50 -0
  226. data/lib/arel/nodes/comment.rb +29 -0
  227. data/lib/arel/nodes/count.rb +12 -0
  228. data/lib/arel/nodes/delete_statement.rb +45 -0
  229. data/lib/arel/nodes/descending.rb +23 -0
  230. data/lib/arel/nodes/equality.rb +18 -0
  231. data/lib/arel/nodes/extract.rb +24 -0
  232. data/lib/arel/nodes/false.rb +16 -0
  233. data/lib/arel/nodes/full_outer_join.rb +8 -0
  234. data/lib/arel/nodes/function.rb +44 -0
  235. data/lib/arel/nodes/grouping.rb +8 -0
  236. data/lib/arel/nodes/in.rb +8 -0
  237. data/lib/arel/nodes/infix_operation.rb +80 -0
  238. data/lib/arel/nodes/inner_join.rb +8 -0
  239. data/lib/arel/nodes/insert_statement.rb +37 -0
  240. data/lib/arel/nodes/join_source.rb +20 -0
  241. data/lib/arel/nodes/matches.rb +18 -0
  242. data/lib/arel/nodes/named_function.rb +23 -0
  243. data/lib/arel/nodes/node.rb +50 -0
  244. data/lib/arel/nodes/node_expression.rb +13 -0
  245. data/lib/arel/nodes/outer_join.rb +8 -0
  246. data/lib/arel/nodes/over.rb +15 -0
  247. data/lib/arel/nodes/regexp.rb +16 -0
  248. data/lib/arel/nodes/right_outer_join.rb +8 -0
  249. data/lib/arel/nodes/select_core.rb +67 -0
  250. data/lib/arel/nodes/select_statement.rb +41 -0
  251. data/lib/arel/nodes/sql_literal.rb +16 -0
  252. data/lib/arel/nodes/string_join.rb +11 -0
  253. data/lib/arel/nodes/table_alias.rb +27 -0
  254. data/lib/arel/nodes/terminal.rb +16 -0
  255. data/lib/arel/nodes/true.rb +16 -0
  256. data/lib/arel/nodes/unary.rb +45 -0
  257. data/lib/arel/nodes/unary_operation.rb +20 -0
  258. data/lib/arel/nodes/unqualified_column.rb +22 -0
  259. data/lib/arel/nodes/update_statement.rb +41 -0
  260. data/lib/arel/nodes/values_list.rb +9 -0
  261. data/lib/arel/nodes/window.rb +126 -0
  262. data/lib/arel/nodes/with.rb +11 -0
  263. data/lib/arel/nodes.rb +68 -0
  264. data/lib/arel/order_predications.rb +13 -0
  265. data/lib/arel/predications.rb +256 -0
  266. data/lib/arel/select_manager.rb +271 -0
  267. data/lib/arel/table.rb +110 -0
  268. data/lib/arel/tree_manager.rb +72 -0
  269. data/lib/arel/update_manager.rb +34 -0
  270. data/lib/arel/visitors/depth_first.rb +203 -0
  271. data/lib/arel/visitors/dot.rb +296 -0
  272. data/lib/arel/visitors/ibm_db.rb +34 -0
  273. data/lib/arel/visitors/informix.rb +62 -0
  274. data/lib/arel/visitors/mssql.rb +156 -0
  275. data/lib/arel/visitors/mysql.rb +83 -0
  276. data/lib/arel/visitors/oracle.rb +158 -0
  277. data/lib/arel/visitors/oracle12.rb +65 -0
  278. data/lib/arel/visitors/postgresql.rb +109 -0
  279. data/lib/arel/visitors/sqlite.rb +38 -0
  280. data/lib/arel/visitors/to_sql.rb +888 -0
  281. data/lib/arel/visitors/visitor.rb +45 -0
  282. data/lib/arel/visitors/where_sql.rb +22 -0
  283. data/lib/arel/visitors.rb +20 -0
  284. data/lib/arel/window_predications.rb +9 -0
  285. data/lib/arel.rb +62 -0
  286. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  287. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  288. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  289. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  290. data/lib/rails/generators/active_record/migration.rb +14 -2
  291. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  292. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  293. metadata +113 -26
  294. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/middleware/database_selector/resolver"
4
+
5
+ module ActiveRecord
6
+ module Middleware
7
+ # The DatabaseSelector Middleware provides a framework for automatically
8
+ # swapping from the primary to the replica database connection. Rails
9
+ # provides a basic framework to determine when to swap and allows for
10
+ # applications to write custom strategy classes to override the default
11
+ # behavior.
12
+ #
13
+ # The resolver class defines when the application should switch (i.e. read
14
+ # from the primary if a write occurred less than 2 seconds ago) and a
15
+ # resolver context class that sets a value that helps the resolver class
16
+ # decide when to switch.
17
+ #
18
+ # Rails default middleware uses the request's session to set a timestamp
19
+ # that informs the application when to read from a primary or read from a
20
+ # replica.
21
+ #
22
+ # To use the DatabaseSelector in your application with default settings add
23
+ # the following options to your environment config:
24
+ #
25
+ # config.active_record.database_selector = { delay: 2.seconds }
26
+ # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
27
+ # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
28
+ #
29
+ # New applications will include these lines commented out in the production.rb.
30
+ #
31
+ # The default behavior can be changed by setting the config options to a
32
+ # custom class:
33
+ #
34
+ # config.active_record.database_selector = { delay: 2.seconds }
35
+ # config.active_record.database_resolver = MyResolver
36
+ # config.active_record.database_resolver_context = MyResolver::MySession
37
+ class DatabaseSelector
38
+ def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
39
+ @app = app
40
+ @resolver_klass = resolver_klass || Resolver
41
+ @context_klass = context_klass || Resolver::Session
42
+ @options = options
43
+ end
44
+
45
+ attr_reader :resolver_klass, :context_klass, :options
46
+
47
+ # Middleware that determines which database connection to use in a multiple
48
+ # database application.
49
+ def call(env)
50
+ request = ActionDispatch::Request.new(env)
51
+
52
+ select_database(request) do
53
+ @app.call(env)
54
+ end
55
+ end
56
+
57
+ private
58
+ def select_database(request, &blk)
59
+ context = context_klass.call(request)
60
+ resolver = resolver_klass.call(context, options)
61
+
62
+ if reading_request?(request)
63
+ resolver.read(&blk)
64
+ else
65
+ resolver.write(&blk)
66
+ end
67
+ end
68
+
69
+ def reading_request?(request)
70
+ request.get? || request.head?
71
+ end
72
+ end
73
+ end
74
+ end
@@ -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
@@ -30,12 +32,14 @@ module ActiveRecord
30
32
  # * rename_index
31
33
  # * rename_table
32
34
  class CommandRecorder
33
- ReversibleAndIrreversibleMethods = [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
35
+ ReversibleAndIrreversibleMethods = [
36
+ :create_table, :create_join_table, :rename_table, :add_column, :remove_column,
34
37
  :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
35
38
  :change_column_default, :add_reference, :remove_reference, :transaction,
36
39
  :drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension,
37
40
  :change_column, :execute, :remove_columns, :change_column_null,
38
- :add_foreign_key, :remove_foreign_key
41
+ :add_foreign_key, :remove_foreign_key,
42
+ :change_column_comment, :change_table_comment
39
43
  ]
40
44
  include JoinTable
41
45
 
@@ -85,7 +89,7 @@ module ActiveRecord
85
89
  # invert the +command+.
86
90
  def inverse_of(command, args, &block)
87
91
  method = :"invert_#{command}"
88
- raise IrreversibleMigration, <<-MSG.strip_heredoc unless respond_to?(method, true)
92
+ raise IrreversibleMigration, <<~MSG unless respond_to?(method, true)
89
93
  This migration uses #{command}, which is not automatically reversible.
90
94
  To make the migration reversible you can either:
91
95
  1. Define #up and #down methods in place of the #change method.
@@ -100,25 +104,32 @@ module ActiveRecord
100
104
  record(:"#{method}", args, &block) # record(:create_table, args, &block)
101
105
  end # end
102
106
  EOV
107
+ ruby2_keywords(method) if respond_to?(:ruby2_keywords, true)
103
108
  end
104
109
  alias :add_belongs_to :add_reference
105
110
  alias :remove_belongs_to :remove_reference
106
111
 
107
- def change_table(table_name, options = {}) # :nodoc:
112
+ def change_table(table_name, **options) # :nodoc:
108
113
  yield delegate.update_table_definition(table_name, self)
109
114
  end
110
115
 
111
- private
116
+ def replay(migration)
117
+ commands.each do |cmd, args, block|
118
+ migration.send(cmd, *args, &block)
119
+ end
120
+ end
112
121
 
122
+ private
113
123
  module StraightReversions # :nodoc:
114
124
  private
115
- { transaction: :transaction,
125
+ {
116
126
  execute_block: :execute_block,
117
127
  create_table: :drop_table,
118
128
  create_join_table: :drop_join_table,
119
129
  add_column: :remove_column,
120
130
  add_timestamps: :remove_timestamps,
121
131
  add_reference: :remove_reference,
132
+ add_foreign_key: :remove_foreign_key,
122
133
  enable_extension: :disable_extension
123
134
  }.each do |cmd, inv|
124
135
  [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
@@ -133,6 +144,17 @@ module ActiveRecord
133
144
 
134
145
  include StraightReversions
135
146
 
147
+ def invert_transaction(args)
148
+ sub_recorder = CommandRecorder.new(delegate)
149
+ sub_recorder.revert { yield }
150
+
151
+ invertions_proc = proc {
152
+ sub_recorder.replay(self)
153
+ }
154
+
155
+ [:transaction, args, invertions_proc]
156
+ end
157
+
136
158
  def invert_drop_table(args, &block)
137
159
  if args.size == 1 && block == nil
138
160
  raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
@@ -198,29 +220,38 @@ module ActiveRecord
198
220
  [:change_column_null, args]
199
221
  end
200
222
 
201
- def invert_add_foreign_key(args)
202
- from_table, to_table, add_options = args
203
- add_options ||= {}
223
+ def invert_remove_foreign_key(args)
224
+ options = args.extract_options!
225
+ from_table, to_table = args
204
226
 
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
227
+ to_table ||= options.delete(:to_table)
228
+
229
+ raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil?
230
+
231
+ reversed_args = [from_table, to_table]
232
+ reversed_args << options unless options.empty?
233
+
234
+ [:add_foreign_key, reversed_args]
235
+ end
236
+
237
+ def invert_change_column_comment(args)
238
+ table, column, options = *args
239
+
240
+ unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
241
+ raise ActiveRecord::IrreversibleMigration, "change_column_comment is only reversible if given a :from and :to option."
211
242
  end
212
243
 
213
- [:remove_foreign_key, [from_table, options]]
244
+ [:change_column_comment, [table, column, from: options[:to], to: options[:from]]]
214
245
  end
215
246
 
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)
247
+ def invert_change_table_comment(args)
248
+ table, options = *args
219
249
 
220
- reversed_args = [from_table, to_table]
221
- reversed_args << remove_options if remove_options
250
+ unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
251
+ raise ActiveRecord::IrreversibleMigration, "change_table_comment is only reversible if given a :from and :to option."
252
+ end
222
253
 
223
- [:add_foreign_key, reversed_args]
254
+ [:change_table_comment, [table, from: options[:to], to: options[:from]]]
224
255
  end
225
256
 
226
257
  def respond_to_missing?(method, _)
@@ -235,6 +266,7 @@ module ActiveRecord
235
266
  super
236
267
  end
237
268
  end
269
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
238
270
  end
239
271
  end
240
272
  end
@@ -13,7 +13,77 @@ 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 = {})
@@ -27,7 +97,7 @@ module ActiveRecord
27
97
  end
28
98
  end
29
99
 
30
- def create_table(table_name, options = {})
100
+ def create_table(table_name, **options)
31
101
  if connection.adapter_name == "Mysql2"
32
102
  super(table_name, options: "ENGINE=InnoDB", **options)
33
103
  else
@@ -49,7 +119,7 @@ module ActiveRecord
49
119
  alias :belongs_to :references
50
120
  end
51
121
 
52
- def create_table(table_name, options = {})
122
+ def create_table(table_name, **options)
53
123
  if connection.adapter_name == "PostgreSQL"
54
124
  if options[:id] == :uuid && !options.key?(:default)
55
125
  options[:default] = "uuid_generate_v4()"
@@ -69,38 +139,15 @@ module ActiveRecord
69
139
  options[:id] = :integer
70
140
  end
71
141
 
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
142
+ super
89
143
  end
90
144
 
91
145
  def create_join_table(table_1, table_2, column_options: {}, **options)
92
146
  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
147
+ super
101
148
  end
102
149
 
103
- def add_column(table_name, column_name, type, options = {})
150
+ def add_column(table_name, column_name, type, **options)
104
151
  if type == :primary_key
105
152
  type = :integer
106
153
  options[:primary_key] = true
@@ -118,7 +165,7 @@ module ActiveRecord
118
165
  class << t
119
166
  prepend TableDefinition
120
167
  end
121
- t
168
+ super
122
169
  end
123
170
  end
124
171
 
@@ -136,33 +183,13 @@ module ActiveRecord
136
183
  end
137
184
  end
138
185
 
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)
186
+ def add_reference(table_name, ref_name, **options)
160
187
  options[:index] ||= false
161
188
  super
162
189
  end
163
190
  alias :add_belongs_to :add_reference
164
191
 
165
- def add_timestamps(_, **options)
192
+ def add_timestamps(table_name, **options)
166
193
  options[:null] = true if options[:null].nil?
167
194
  super
168
195
  end
@@ -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