activerecord 4.2.0 → 5.2.8.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 (274) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +640 -928
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +10 -11
  5. data/examples/performance.rb +32 -31
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +264 -247
  8. data/lib/active_record/association_relation.rb +24 -6
  9. data/lib/active_record/associations/alias_tracker.rb +29 -35
  10. data/lib/active_record/associations/association.rb +87 -41
  11. data/lib/active_record/associations/association_scope.rb +106 -132
  12. data/lib/active_record/associations/belongs_to_association.rb +55 -36
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  14. data/lib/active_record/associations/builder/association.rb +29 -38
  15. data/lib/active_record/associations/builder/belongs_to.rb +77 -30
  16. data/lib/active_record/associations/builder/collection_association.rb +14 -23
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -39
  18. data/lib/active_record/associations/builder/has_many.rb +6 -4
  19. data/lib/active_record/associations/builder/has_one.rb +13 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +15 -11
  21. data/lib/active_record/associations/collection_association.rb +145 -266
  22. data/lib/active_record/associations/collection_proxy.rb +242 -138
  23. data/lib/active_record/associations/foreign_association.rb +13 -0
  24. data/lib/active_record/associations/has_many_association.rb +35 -75
  25. data/lib/active_record/associations/has_many_through_association.rb +51 -69
  26. data/lib/active_record/associations/has_one_association.rb +39 -24
  27. data/lib/active_record/associations/has_one_through_association.rb +18 -9
  28. data/lib/active_record/associations/join_dependency/join_association.rb +40 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -154
  32. data/lib/active_record/associations/preloader/association.rb +85 -116
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -74
  34. data/lib/active_record/associations/preloader.rb +83 -93
  35. data/lib/active_record/associations/singular_association.rb +27 -40
  36. data/lib/active_record/associations/through_association.rb +48 -23
  37. data/lib/active_record/associations.rb +1732 -1596
  38. data/lib/active_record/attribute_assignment.rb +58 -182
  39. data/lib/active_record/attribute_decorators.rb +39 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -5
  41. data/lib/active_record/attribute_methods/dirty.rb +94 -125
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -71
  43. data/lib/active_record/attribute_methods/query.rb +4 -2
  44. data/lib/active_record/attribute_methods/read.rb +45 -63
  45. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
  47. data/lib/active_record/attribute_methods/write.rb +31 -46
  48. data/lib/active_record/attribute_methods.rb +170 -117
  49. data/lib/active_record/attributes.rb +201 -74
  50. data/lib/active_record/autosave_association.rb +118 -45
  51. data/lib/active_record/base.rb +60 -48
  52. data/lib/active_record/callbacks.rb +97 -57
  53. data/lib/active_record/coders/json.rb +3 -1
  54. data/lib/active_record/coders/yaml_column.rb +37 -13
  55. data/lib/active_record/collection_cache_key.rb +53 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -284
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +254 -87
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +72 -22
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -52
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -217
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +617 -212
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +139 -75
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +332 -191
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +567 -563
  69. data/lib/active_record/connection_adapters/column.rb +50 -41
  70. data/lib/active_record/connection_adapters/connection_specification.rb +147 -135
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +42 -195
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -115
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +10 -6
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +65 -51
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +107 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +144 -90
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +466 -280
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +439 -330
  117. data/lib/active_record/connection_adapters/schema_cache.rb +48 -24
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +269 -324
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +40 -27
  128. data/lib/active_record/core.rb +205 -202
  129. data/lib/active_record/counter_cache.rb +80 -37
  130. data/lib/active_record/define_callbacks.rb +22 -0
  131. data/lib/active_record/dynamic_matchers.rb +87 -105
  132. data/lib/active_record/enum.rb +136 -90
  133. data/lib/active_record/errors.rb +180 -52
  134. data/lib/active_record/explain.rb +23 -11
  135. data/lib/active_record/explain_registry.rb +4 -2
  136. data/lib/active_record/explain_subscriber.rb +11 -6
  137. data/lib/active_record/fixture_set/file.rb +35 -9
  138. data/lib/active_record/fixtures.rb +193 -135
  139. data/lib/active_record/gem_version.rb +5 -3
  140. data/lib/active_record/inheritance.rb +148 -112
  141. data/lib/active_record/integration.rb +70 -28
  142. data/lib/active_record/internal_metadata.rb +45 -0
  143. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  144. data/lib/active_record/locale/en.yml +3 -2
  145. data/lib/active_record/locking/optimistic.rb +92 -98
  146. data/lib/active_record/locking/pessimistic.rb +15 -3
  147. data/lib/active_record/log_subscriber.rb +95 -33
  148. data/lib/active_record/migration/command_recorder.rb +133 -90
  149. data/lib/active_record/migration/compatibility.rb +217 -0
  150. data/lib/active_record/migration/join_table.rb +8 -6
  151. data/lib/active_record/migration.rb +594 -267
  152. data/lib/active_record/model_schema.rb +292 -111
  153. data/lib/active_record/nested_attributes.rb +266 -214
  154. data/lib/active_record/no_touching.rb +8 -2
  155. data/lib/active_record/null_relation.rb +24 -37
  156. data/lib/active_record/persistence.rb +350 -119
  157. data/lib/active_record/query_cache.rb +13 -24
  158. data/lib/active_record/querying.rb +19 -17
  159. data/lib/active_record/railtie.rb +117 -35
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +9 -3
  162. data/lib/active_record/railties/databases.rake +160 -174
  163. data/lib/active_record/readonly_attributes.rb +5 -4
  164. data/lib/active_record/reflection.rb +447 -288
  165. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  166. data/lib/active_record/relation/batches.rb +204 -55
  167. data/lib/active_record/relation/calculations.rb +259 -244
  168. data/lib/active_record/relation/delegation.rb +67 -60
  169. data/lib/active_record/relation/finder_methods.rb +290 -253
  170. data/lib/active_record/relation/from_clause.rb +26 -0
  171. data/lib/active_record/relation/merger.rb +91 -68
  172. data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -23
  173. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  174. data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  179. data/lib/active_record/relation/predicate_builder.rb +118 -92
  180. data/lib/active_record/relation/query_attribute.rb +45 -0
  181. data/lib/active_record/relation/query_methods.rb +446 -389
  182. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  183. data/lib/active_record/relation/spawn_methods.rb +18 -16
  184. data/lib/active_record/relation/where_clause.rb +186 -0
  185. data/lib/active_record/relation/where_clause_factory.rb +34 -0
  186. data/lib/active_record/relation.rb +287 -339
  187. data/lib/active_record/result.rb +54 -36
  188. data/lib/active_record/runtime_registry.rb +6 -4
  189. data/lib/active_record/sanitization.rb +155 -124
  190. data/lib/active_record/schema.rb +30 -24
  191. data/lib/active_record/schema_dumper.rb +91 -87
  192. data/lib/active_record/schema_migration.rb +19 -19
  193. data/lib/active_record/scoping/default.rb +102 -84
  194. data/lib/active_record/scoping/named.rb +81 -32
  195. data/lib/active_record/scoping.rb +45 -26
  196. data/lib/active_record/secure_token.rb +40 -0
  197. data/lib/active_record/serialization.rb +5 -5
  198. data/lib/active_record/statement_cache.rb +45 -35
  199. data/lib/active_record/store.rb +42 -36
  200. data/lib/active_record/suppressor.rb +61 -0
  201. data/lib/active_record/table_metadata.rb +82 -0
  202. data/lib/active_record/tasks/database_tasks.rb +136 -95
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +59 -89
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -31
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -16
  206. data/lib/active_record/timestamp.rb +70 -38
  207. data/lib/active_record/touch_later.rb +64 -0
  208. data/lib/active_record/transactions.rb +208 -123
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type/adapter_specific_registry.rb +136 -0
  211. data/lib/active_record/type/date.rb +4 -41
  212. data/lib/active_record/type/date_time.rb +4 -38
  213. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  214. data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
  215. data/lib/active_record/type/internal/timezone.rb +17 -0
  216. data/lib/active_record/type/json.rb +30 -0
  217. data/lib/active_record/type/serialized.rb +30 -15
  218. data/lib/active_record/type/text.rb +2 -2
  219. data/lib/active_record/type/time.rb +11 -16
  220. data/lib/active_record/type/type_map.rb +15 -17
  221. data/lib/active_record/type/unsigned_integer.rb +9 -7
  222. data/lib/active_record/type.rb +79 -23
  223. data/lib/active_record/type_caster/connection.rb +33 -0
  224. data/lib/active_record/type_caster/map.rb +23 -0
  225. data/lib/active_record/type_caster.rb +9 -0
  226. data/lib/active_record/validations/absence.rb +25 -0
  227. data/lib/active_record/validations/associated.rb +13 -4
  228. data/lib/active_record/validations/length.rb +26 -0
  229. data/lib/active_record/validations/presence.rb +14 -13
  230. data/lib/active_record/validations/uniqueness.rb +41 -32
  231. data/lib/active_record/validations.rb +38 -35
  232. data/lib/active_record/version.rb +3 -1
  233. data/lib/active_record.rb +36 -21
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  236. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -35
  237. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +8 -6
  238. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -7
  239. data/lib/rails/generators/active_record/migration.rb +18 -1
  240. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +3 -0
  242. data/lib/rails/generators/active_record.rb +7 -5
  243. metadata +77 -53
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  251. data/lib/active_record/attribute.rb +0 -149
  252. data/lib/active_record/attribute_set/builder.rb +0 -86
  253. data/lib/active_record/attribute_set.rb +0 -77
  254. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  255. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  256. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  257. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  258. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  259. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  260. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  261. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  262. data/lib/active_record/type/big_integer.rb +0 -13
  263. data/lib/active_record/type/binary.rb +0 -50
  264. data/lib/active_record/type/boolean.rb +0 -30
  265. data/lib/active_record/type/decimal.rb +0 -40
  266. data/lib/active_record/type/decorator.rb +0 -14
  267. data/lib/active_record/type/float.rb +0 -19
  268. data/lib/active_record/type/integer.rb +0 -55
  269. data/lib/active_record/type/mutable.rb +0 -16
  270. data/lib/active_record/type/numeric.rb +0 -36
  271. data/lib/active_record/type/string.rb +0 -36
  272. data/lib/active_record/type/time_value.rb +0 -38
  273. data/lib/active_record/type/value.rb +0 -101
  274. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class Migration
3
5
  # <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
@@ -5,15 +7,36 @@ module ActiveRecord
5
7
  # knows how to invert the following commands:
6
8
  #
7
9
  # * add_column
10
+ # * add_foreign_key
8
11
  # * add_index
12
+ # * add_reference
9
13
  # * add_timestamps
10
- # * create_table
14
+ # * change_column
15
+ # * change_column_default (must supply a :from and :to option)
16
+ # * change_column_null
11
17
  # * create_join_table
18
+ # * create_table
19
+ # * disable_extension
20
+ # * drop_join_table
21
+ # * drop_table (must supply a block)
22
+ # * enable_extension
23
+ # * remove_column (must supply a type)
24
+ # * remove_columns (must specify at least one column name or more)
25
+ # * remove_foreign_key (must supply a second table)
26
+ # * remove_index
27
+ # * remove_reference
12
28
  # * remove_timestamps
13
29
  # * rename_column
14
30
  # * rename_index
15
31
  # * rename_table
16
32
  class CommandRecorder
33
+ ReversibleAndIrreversibleMethods = [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
34
+ :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
35
+ :change_column_default, :add_reference, :remove_reference, :transaction,
36
+ :drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension,
37
+ :change_column, :execute, :remove_columns, :change_column_null,
38
+ :add_foreign_key, :remove_foreign_key
39
+ ]
17
40
  include JoinTable
18
41
 
19
42
  attr_accessor :commands, :delegate, :reverting
@@ -41,7 +64,7 @@ module ActiveRecord
41
64
  @reverting = !@reverting
42
65
  end
43
66
 
44
- # record +command+. +command+ should be a method name and arguments.
67
+ # Record +command+. +command+ should be a method name and arguments.
45
68
  # For example:
46
69
  #
47
70
  # recorder.record(:method_name, [:arg1, :arg2])
@@ -62,22 +85,16 @@ module ActiveRecord
62
85
  # invert the +command+.
63
86
  def inverse_of(command, args, &block)
64
87
  method = :"invert_#{command}"
65
- raise IrreversibleMigration unless respond_to?(method, true)
88
+ raise IrreversibleMigration, <<-MSG.strip_heredoc unless respond_to?(method, true)
89
+ This migration uses #{command}, which is not automatically reversible.
90
+ To make the migration reversible you can either:
91
+ 1. Define #up and #down methods in place of the #change method.
92
+ 2. Use the #reversible method to define reversible behavior.
93
+ MSG
66
94
  send(method, args, &block)
67
95
  end
68
96
 
69
- def respond_to?(*args) # :nodoc:
70
- super || delegate.respond_to?(*args)
71
- end
72
-
73
- [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
74
- :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
75
- :change_column_default, :add_reference, :remove_reference, :transaction,
76
- :drop_join_table, :drop_table, :execute_block, :enable_extension,
77
- :change_column, :execute, :remove_columns, :change_column_null,
78
- :add_foreign_key, :remove_foreign_key
79
- # irreversible methods need to be here too
80
- ].each do |method|
97
+ ReversibleAndIrreversibleMethods.each do |method|
81
98
  class_eval <<-EOV, __FILE__, __LINE__ + 1
82
99
  def #{method}(*args, &block) # def create_table(*args, &block)
83
100
  record(:"#{method}", args, &block) # record(:create_table, args, &block)
@@ -93,105 +110,131 @@ module ActiveRecord
93
110
 
94
111
  private
95
112
 
96
- module StraightReversions
97
- private
98
- { transaction: :transaction,
99
- execute_block: :execute_block,
100
- create_table: :drop_table,
101
- create_join_table: :drop_join_table,
102
- add_column: :remove_column,
103
- add_timestamps: :remove_timestamps,
104
- add_reference: :remove_reference,
105
- enable_extension: :disable_extension
106
- }.each do |cmd, inv|
107
- [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
108
- class_eval <<-EOV, __FILE__, __LINE__ + 1
109
- def invert_#{method}(args, &block) # def invert_create_table(args, &block)
110
- [:#{inverse}, args, block] # [:drop_table, args, block]
111
- end # end
112
- EOV
113
+ module StraightReversions # :nodoc:
114
+ private
115
+ { transaction: :transaction,
116
+ execute_block: :execute_block,
117
+ create_table: :drop_table,
118
+ create_join_table: :drop_join_table,
119
+ add_column: :remove_column,
120
+ add_timestamps: :remove_timestamps,
121
+ add_reference: :remove_reference,
122
+ enable_extension: :disable_extension
123
+ }.each do |cmd, inv|
124
+ [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
125
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
126
+ def invert_#{method}(args, &block) # def invert_create_table(args, &block)
127
+ [:#{inverse}, args, block] # [:drop_table, args, block]
128
+ end # end
129
+ EOV
130
+ end
131
+ end
132
+ end
133
+
134
+ include StraightReversions
135
+
136
+ def invert_drop_table(args, &block)
137
+ if args.size == 1 && block == nil
138
+ raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
113
139
  end
140
+ super
114
141
  end
115
- end
116
142
 
117
- include StraightReversions
143
+ def invert_rename_table(args)
144
+ [:rename_table, args.reverse]
145
+ end
118
146
 
119
- def invert_drop_table(args, &block)
120
- if args.size == 1 && block == nil
121
- raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
147
+ def invert_remove_column(args)
148
+ raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
149
+ super
122
150
  end
123
- super
124
- end
125
151
 
126
- def invert_rename_table(args)
127
- [:rename_table, args.reverse]
128
- end
152
+ def invert_rename_index(args)
153
+ [:rename_index, [args.first] + args.last(2).reverse]
154
+ end
129
155
 
130
- def invert_remove_column(args)
131
- raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
132
- super
133
- end
156
+ def invert_rename_column(args)
157
+ [:rename_column, [args.first] + args.last(2).reverse]
158
+ end
134
159
 
135
- def invert_rename_index(args)
136
- [:rename_index, [args.first] + args.last(2).reverse]
137
- end
160
+ def invert_add_index(args)
161
+ table, columns, options = *args
162
+ options ||= {}
138
163
 
139
- def invert_rename_column(args)
140
- [:rename_column, [args.first] + args.last(2).reverse]
141
- end
164
+ options_hash = options.slice(:name, :algorithm)
165
+ options_hash[:column] = columns if !options_hash[:name]
142
166
 
143
- def invert_add_index(args)
144
- table, columns, options = *args
145
- options ||= {}
167
+ [:remove_index, [table, options_hash]]
168
+ end
169
+
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]]
180
+ end
181
+ end
146
182
 
147
- index_name = options[:name]
148
- options_hash = index_name ? { name: index_name } : { column: columns }
183
+ alias :invert_add_belongs_to :invert_add_reference
184
+ alias :invert_remove_belongs_to :invert_remove_reference
149
185
 
150
- [:remove_index, [table, options_hash]]
151
- end
186
+ def invert_change_column_default(args)
187
+ table, column, options = *args
152
188
 
153
- def invert_remove_index(args)
154
- table, options = *args
189
+ unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
190
+ raise ActiveRecord::IrreversibleMigration, "change_column_default is only reversible if given a :from and :to option."
191
+ end
155
192
 
156
- unless options && options.is_a?(Hash) && options[:column]
157
- raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option."
193
+ [:change_column_default, [table, column, from: options[:to], to: options[:from]]]
158
194
  end
159
195
 
160
- options = options.dup
161
- [:add_index, [table, options.delete(:column), options]]
162
- end
196
+ def invert_change_column_null(args)
197
+ args[2] = !args[2]
198
+ [:change_column_null, args]
199
+ end
163
200
 
164
- alias :invert_add_belongs_to :invert_add_reference
165
- alias :invert_remove_belongs_to :invert_remove_reference
201
+ def invert_add_foreign_key(args)
202
+ from_table, to_table, add_options = args
203
+ add_options ||= {}
166
204
 
167
- def invert_change_column_null(args)
168
- args[2] = !args[2]
169
- [:change_column_null, args]
170
- end
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
211
+ end
171
212
 
172
- def invert_add_foreign_key(args)
173
- from_table, to_table, add_options = args
174
- add_options ||= {}
213
+ [:remove_foreign_key, [from_table, options]]
214
+ end
175
215
 
176
- if add_options[:name]
177
- options = { name: add_options[:name] }
178
- elsif add_options[:column]
179
- options = { column: add_options[:column] }
180
- else
181
- options = to_table
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)
219
+
220
+ reversed_args = [from_table, to_table]
221
+ reversed_args << remove_options if remove_options
222
+
223
+ [:add_foreign_key, reversed_args]
182
224
  end
183
225
 
184
- [:remove_foreign_key, [from_table, options]]
185
- end
226
+ def respond_to_missing?(method, _)
227
+ super || delegate.respond_to?(method)
228
+ end
186
229
 
187
- # Forwards any missing method call to the \target.
188
- def method_missing(method, *args, &block)
189
- if @delegate.respond_to?(method)
190
- @delegate.send(method, *args, &block)
191
- else
192
- super
230
+ # Forwards any missing method call to the \target.
231
+ def method_missing(method, *args, &block)
232
+ if delegate.respond_to?(method)
233
+ delegate.public_send(method, *args, &block)
234
+ else
235
+ super
236
+ end
193
237
  end
194
- end
195
238
  end
196
239
  end
197
240
  end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Migration
5
+ module Compatibility # :nodoc: all
6
+ def self.find(version)
7
+ version = version.to_s
8
+ name = "V#{version.tr('.', '_')}"
9
+ unless const_defined?(name)
10
+ versions = constants.grep(/\AV[0-9_]+\z/).map { |s| s.to_s.delete("V").tr("_", ".").inspect }
11
+ raise ArgumentError, "Unknown migration version #{version.inspect}; expected one of #{versions.sort.join(', ')}"
12
+ end
13
+ const_get(name)
14
+ end
15
+
16
+ V5_2 = Current
17
+
18
+ class V5_1 < V5_2
19
+ def change_column(table_name, column_name, type, options = {})
20
+ if connection.adapter_name == "PostgreSQL"
21
+ super(table_name, column_name, type, options.except(:default, :null, :comment))
22
+ connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
23
+ connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
24
+ connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def create_table(table_name, options = {})
31
+ if connection.adapter_name == "Mysql2"
32
+ super(table_name, options: "ENGINE=InnoDB", **options)
33
+ else
34
+ super
35
+ end
36
+ end
37
+ end
38
+
39
+ class V5_0 < V5_1
40
+ module TableDefinition
41
+ def primary_key(name, type = :primary_key, **options)
42
+ type = :integer if type == :primary_key
43
+ super
44
+ end
45
+
46
+ def references(*args, **options)
47
+ super(*args, type: :integer, **options)
48
+ end
49
+ alias :belongs_to :references
50
+ end
51
+
52
+ def create_table(table_name, options = {})
53
+ if connection.adapter_name == "PostgreSQL"
54
+ if options[:id] == :uuid && !options.key?(:default)
55
+ options[:default] = "uuid_generate_v4()"
56
+ end
57
+ end
58
+
59
+ unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
60
+ if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
61
+ options[:default] = nil
62
+ end
63
+ end
64
+
65
+ # Since 5.1 PostgreSQL adapter uses bigserial type for primary
66
+ # keys by default and MySQL uses bigint. This compat layer makes old migrations utilize
67
+ # serial/int type instead -- the way it used to work before 5.1.
68
+ unless options.key?(:id)
69
+ options[:id] = :integer
70
+ end
71
+
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
89
+ end
90
+
91
+ def create_join_table(table_1, table_2, column_options: {}, **options)
92
+ 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
101
+ end
102
+
103
+ def add_column(table_name, column_name, type, options = {})
104
+ if type == :primary_key
105
+ type = :integer
106
+ options[:primary_key] = true
107
+ end
108
+ super
109
+ end
110
+
111
+ def add_reference(table_name, ref_name, **options)
112
+ super(table_name, ref_name, type: :integer, **options)
113
+ end
114
+ alias :add_belongs_to :add_reference
115
+
116
+ private
117
+ def compatible_table_definition(t)
118
+ class << t
119
+ prepend TableDefinition
120
+ end
121
+ t
122
+ end
123
+ end
124
+
125
+ class V4_2 < V5_0
126
+ module TableDefinition
127
+ def references(*, **options)
128
+ options[:index] ||= false
129
+ super
130
+ end
131
+ alias :belongs_to :references
132
+
133
+ def timestamps(**options)
134
+ options[:null] = true if options[:null].nil?
135
+ super
136
+ end
137
+ end
138
+
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)
160
+ options[:index] ||= false
161
+ super
162
+ end
163
+ alias :add_belongs_to :add_reference
164
+
165
+ def add_timestamps(_, **options)
166
+ options[:null] = true if options[:null].nil?
167
+ super
168
+ end
169
+
170
+ def index_exists?(table_name, column_name, options = {})
171
+ column_names = Array(column_name).map(&:to_s)
172
+ options[:name] =
173
+ if options[:name].present?
174
+ options[:name].to_s
175
+ else
176
+ connection.index_name(table_name, column: column_names)
177
+ end
178
+ super
179
+ end
180
+
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)
185
+ end
186
+
187
+ private
188
+ def compatible_table_definition(t)
189
+ class << t
190
+ prepend TableDefinition
191
+ end
192
+ super
193
+ end
194
+
195
+ def index_name_for_remove(table_name, options = {})
196
+ index_name = connection.index_name(table_name, options)
197
+
198
+ 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
202
+ index_name_without_column = connection.index_name(table_name, options_without_column)
203
+
204
+ if connection.index_name_exists?(table_name, index_name_without_column)
205
+ return index_name_without_column
206
+ end
207
+ end
208
+
209
+ raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
210
+ end
211
+
212
+ index_name
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class Migration
3
5
  module JoinTable #:nodoc:
4
6
  private
5
7
 
6
- def find_join_table_name(table_1, table_2, options = {})
7
- options.delete(:table_name) || join_table_name(table_1, table_2)
8
- end
8
+ def find_join_table_name(table_1, table_2, options = {})
9
+ options.delete(:table_name) || join_table_name(table_1, table_2)
10
+ end
9
11
 
10
- def join_table_name(table_1, table_2)
11
- ModelSchema.derive_join_table_name(table_1, table_2).to_sym
12
- end
12
+ def join_table_name(table_1, table_2)
13
+ ModelSchema.derive_join_table_name(table_1, table_2).to_sym
14
+ end
13
15
  end
14
16
  end
15
17
  end