activerecord 6.0.1 → 6.1.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1314 -633
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_record/aggregations.rb +5 -6
  6. data/lib/active_record/association_relation.rb +26 -15
  7. data/lib/active_record/associations/alias_tracker.rb +19 -16
  8. data/lib/active_record/associations/association.rb +55 -37
  9. data/lib/active_record/associations/association_scope.rb +19 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +23 -10
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
  12. data/lib/active_record/associations/builder/association.rb +32 -5
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +38 -13
  20. data/lib/active_record/associations/collection_proxy.rb +14 -7
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -3
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +39 -16
  26. data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
  27. data/lib/active_record/associations/join_dependency.rb +73 -42
  28. data/lib/active_record/associations/preloader/association.rb +49 -25
  29. data/lib/active_record/associations/preloader/through_association.rb +2 -2
  30. data/lib/active_record/associations/preloader.rb +12 -7
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations/through_association.rb +1 -1
  33. data/lib/active_record/associations.rb +119 -12
  34. data/lib/active_record/attribute_assignment.rb +10 -9
  35. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
  36. data/lib/active_record/attribute_methods/dirty.rb +3 -13
  37. data/lib/active_record/attribute_methods/primary_key.rb +6 -4
  38. data/lib/active_record/attribute_methods/query.rb +3 -6
  39. data/lib/active_record/attribute_methods/read.rb +8 -12
  40. data/lib/active_record/attribute_methods/serialization.rb +11 -6
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  42. data/lib/active_record/attribute_methods/write.rb +12 -21
  43. data/lib/active_record/attribute_methods.rb +64 -54
  44. data/lib/active_record/attributes.rb +33 -9
  45. data/lib/active_record/autosave_association.rb +56 -41
  46. data/lib/active_record/base.rb +2 -14
  47. data/lib/active_record/callbacks.rb +153 -24
  48. data/lib/active_record/coders/yaml_column.rb +24 -3
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +190 -136
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +83 -38
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -9
  53. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  54. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +145 -52
  57. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  58. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +267 -105
  59. data/lib/active_record/connection_adapters/abstract/transaction.rb +94 -36
  60. data/lib/active_record/connection_adapters/abstract_adapter.rb +63 -77
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +136 -111
  62. data/lib/active_record/connection_adapters/column.rb +15 -1
  63. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  64. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  65. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
  67. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  68. data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
  69. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
  70. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  71. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
  72. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -13
  73. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  74. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
  75. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  76. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
  79. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  81. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  96. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  97. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  102. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql_adapter.rb +80 -66
  104. data/lib/active_record/connection_adapters/schema_cache.rb +130 -15
  105. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  106. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
  107. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
  108. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  109. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
  110. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +57 -57
  111. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  112. data/lib/active_record/connection_adapters.rb +52 -0
  113. data/lib/active_record/connection_handling.rb +218 -87
  114. data/lib/active_record/core.rb +269 -68
  115. data/lib/active_record/counter_cache.rb +4 -1
  116. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  117. data/lib/active_record/database_configurations/database_config.rb +52 -9
  118. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  119. data/lib/active_record/database_configurations/url_config.rb +15 -41
  120. data/lib/active_record/database_configurations.rb +125 -85
  121. data/lib/active_record/delegated_type.rb +209 -0
  122. data/lib/active_record/destroy_association_async_job.rb +36 -0
  123. data/lib/active_record/dynamic_matchers.rb +2 -3
  124. data/lib/active_record/enum.rb +80 -38
  125. data/lib/active_record/errors.rb +47 -12
  126. data/lib/active_record/explain.rb +9 -5
  127. data/lib/active_record/explain_subscriber.rb +1 -1
  128. data/lib/active_record/fixture_set/file.rb +10 -17
  129. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  130. data/lib/active_record/fixture_set/render_context.rb +1 -1
  131. data/lib/active_record/fixture_set/table_row.rb +2 -3
  132. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  133. data/lib/active_record/fixtures.rb +58 -12
  134. data/lib/active_record/gem_version.rb +2 -2
  135. data/lib/active_record/inheritance.rb +40 -21
  136. data/lib/active_record/insert_all.rb +42 -9
  137. data/lib/active_record/integration.rb +3 -5
  138. data/lib/active_record/internal_metadata.rb +18 -7
  139. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  140. data/lib/active_record/locking/optimistic.rb +33 -18
  141. data/lib/active_record/locking/pessimistic.rb +6 -2
  142. data/lib/active_record/log_subscriber.rb +28 -9
  143. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  144. data/lib/active_record/middleware/database_selector/resolver.rb +6 -2
  145. data/lib/active_record/middleware/database_selector.rb +4 -2
  146. data/lib/active_record/migration/command_recorder.rb +53 -45
  147. data/lib/active_record/migration/compatibility.rb +75 -21
  148. data/lib/active_record/migration/join_table.rb +0 -1
  149. data/lib/active_record/migration.rb +115 -85
  150. data/lib/active_record/model_schema.rb +117 -15
  151. data/lib/active_record/nested_attributes.rb +2 -5
  152. data/lib/active_record/no_touching.rb +1 -1
  153. data/lib/active_record/null_relation.rb +0 -1
  154. data/lib/active_record/persistence.rb +50 -46
  155. data/lib/active_record/query_cache.rb +15 -5
  156. data/lib/active_record/querying.rb +12 -7
  157. data/lib/active_record/railtie.rb +65 -45
  158. data/lib/active_record/railties/console_sandbox.rb +2 -4
  159. data/lib/active_record/railties/databases.rake +280 -99
  160. data/lib/active_record/readonly_attributes.rb +4 -0
  161. data/lib/active_record/reflection.rb +77 -63
  162. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  163. data/lib/active_record/relation/batches.rb +38 -32
  164. data/lib/active_record/relation/calculations.rb +106 -45
  165. data/lib/active_record/relation/delegation.rb +9 -7
  166. data/lib/active_record/relation/finder_methods.rb +45 -16
  167. data/lib/active_record/relation/from_clause.rb +5 -1
  168. data/lib/active_record/relation/merger.rb +27 -26
  169. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  170. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  171. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
  172. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  173. data/lib/active_record/relation/predicate_builder.rb +59 -40
  174. data/lib/active_record/relation/query_methods.rb +339 -188
  175. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  176. data/lib/active_record/relation/spawn_methods.rb +8 -8
  177. data/lib/active_record/relation/where_clause.rb +111 -62
  178. data/lib/active_record/relation.rb +116 -83
  179. data/lib/active_record/result.rb +41 -34
  180. data/lib/active_record/runtime_registry.rb +2 -2
  181. data/lib/active_record/sanitization.rb +6 -17
  182. data/lib/active_record/schema_dumper.rb +34 -4
  183. data/lib/active_record/schema_migration.rb +2 -8
  184. data/lib/active_record/scoping/default.rb +1 -4
  185. data/lib/active_record/scoping/named.rb +7 -18
  186. data/lib/active_record/scoping.rb +0 -1
  187. data/lib/active_record/secure_token.rb +16 -8
  188. data/lib/active_record/serialization.rb +5 -3
  189. data/lib/active_record/signed_id.rb +116 -0
  190. data/lib/active_record/statement_cache.rb +20 -4
  191. data/lib/active_record/store.rb +9 -4
  192. data/lib/active_record/suppressor.rb +2 -2
  193. data/lib/active_record/table_metadata.rb +42 -36
  194. data/lib/active_record/tasks/database_tasks.rb +140 -113
  195. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
  196. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
  197. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
  198. data/lib/active_record/test_databases.rb +5 -4
  199. data/lib/active_record/test_fixtures.rb +87 -20
  200. data/lib/active_record/timestamp.rb +4 -7
  201. data/lib/active_record/touch_later.rb +20 -21
  202. data/lib/active_record/transactions.rb +25 -72
  203. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  204. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  205. data/lib/active_record/type/serialized.rb +6 -3
  206. data/lib/active_record/type/time.rb +10 -0
  207. data/lib/active_record/type/type_map.rb +0 -1
  208. data/lib/active_record/type/unsigned_integer.rb +0 -1
  209. data/lib/active_record/type.rb +8 -2
  210. data/lib/active_record/type_caster/connection.rb +0 -1
  211. data/lib/active_record/type_caster/map.rb +8 -5
  212. data/lib/active_record/validations/associated.rb +1 -2
  213. data/lib/active_record/validations/numericality.rb +35 -0
  214. data/lib/active_record/validations/uniqueness.rb +24 -4
  215. data/lib/active_record/validations.rb +3 -3
  216. data/lib/active_record.rb +7 -13
  217. data/lib/arel/attributes/attribute.rb +4 -0
  218. data/lib/arel/collectors/bind.rb +5 -0
  219. data/lib/arel/collectors/composite.rb +8 -0
  220. data/lib/arel/collectors/sql_string.rb +7 -0
  221. data/lib/arel/collectors/substitute_binds.rb +7 -0
  222. data/lib/arel/nodes/binary.rb +82 -8
  223. data/lib/arel/nodes/bind_param.rb +8 -0
  224. data/lib/arel/nodes/casted.rb +21 -9
  225. data/lib/arel/nodes/equality.rb +6 -9
  226. data/lib/arel/nodes/grouping.rb +3 -0
  227. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  228. data/lib/arel/nodes/in.rb +8 -1
  229. data/lib/arel/nodes/infix_operation.rb +13 -1
  230. data/lib/arel/nodes/join_source.rb +1 -1
  231. data/lib/arel/nodes/node.rb +7 -6
  232. data/lib/arel/nodes/ordering.rb +27 -0
  233. data/lib/arel/nodes/sql_literal.rb +3 -0
  234. data/lib/arel/nodes/table_alias.rb +7 -3
  235. data/lib/arel/nodes/unary.rb +0 -1
  236. data/lib/arel/nodes.rb +3 -1
  237. data/lib/arel/predications.rb +17 -24
  238. data/lib/arel/select_manager.rb +1 -2
  239. data/lib/arel/table.rb +13 -5
  240. data/lib/arel/visitors/dot.rb +14 -3
  241. data/lib/arel/visitors/mysql.rb +11 -1
  242. data/lib/arel/visitors/postgresql.rb +15 -5
  243. data/lib/arel/visitors/sqlite.rb +0 -1
  244. data/lib/arel/visitors/to_sql.rb +89 -79
  245. data/lib/arel/visitors/visitor.rb +0 -1
  246. data/lib/arel/visitors.rb +0 -7
  247. data/lib/arel.rb +5 -9
  248. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  249. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  250. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  251. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
  252. data/lib/rails/generators/active_record/migration.rb +6 -2
  253. data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
  254. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  255. metadata +30 -29
  256. data/lib/active_record/attribute_decorators.rb +0 -90
  257. data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
  258. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  259. data/lib/active_record/define_callbacks.rb +0 -22
  260. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  261. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  262. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  263. data/lib/arel/attributes.rb +0 -22
  264. data/lib/arel/visitors/depth_first.rb +0 -204
  265. data/lib/arel/visitors/ibm_db.rb +0 -34
  266. data/lib/arel/visitors/informix.rb +0 -62
  267. data/lib/arel/visitors/mssql.rb +0 -157
  268. data/lib/arel/visitors/oracle.rb +0 -159
  269. data/lib/arel/visitors/oracle12.rb +0 -66
  270. data/lib/arel/visitors/where_sql.rb +0 -23
@@ -33,6 +33,14 @@ module ActiveRecord
33
33
  @comment = comment
34
34
  end
35
35
 
36
+ def column_options
37
+ {
38
+ length: lengths,
39
+ order: orders,
40
+ opclass: opclasses,
41
+ }
42
+ end
43
+
36
44
  private
37
45
  def concise_options(options)
38
46
  if columns.size == options.size && options.values.uniq.size == 1
@@ -63,12 +71,18 @@ module ActiveRecord
63
71
  end
64
72
  CODE
65
73
  end
74
+
75
+ def aliased_types(name, fallback)
76
+ "timestamp" == name ? :datetime : fallback
77
+ end
66
78
  end
67
79
 
68
80
  AddColumnDefinition = Struct.new(:column) # :nodoc:
69
81
 
70
82
  ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
71
83
 
84
+ CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
85
+
72
86
  PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
73
87
 
74
88
  ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
@@ -105,8 +119,9 @@ module ActiveRecord
105
119
  !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
106
120
  end
107
121
 
108
- def defined_for?(to_table: nil, **options)
122
+ def defined_for?(to_table: nil, validate: nil, **options)
109
123
  (to_table.nil? || to_table.to_s == self.to_table) &&
124
+ (validate.nil? || validate == options.fetch(:validate, validate)) &&
110
125
  options.all? { |k, v| self.options[k].to_s == v.to_s }
111
126
  end
112
127
 
@@ -116,6 +131,21 @@ module ActiveRecord
116
131
  end
117
132
  end
118
133
 
134
+ CheckConstraintDefinition = Struct.new(:table_name, :expression, :options) do
135
+ def name
136
+ options[:name]
137
+ end
138
+
139
+ def validate?
140
+ options.fetch(:validate, true)
141
+ end
142
+ alias validated? validate?
143
+
144
+ def export_name_on_schema_dump?
145
+ !ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
146
+ end
147
+ end
148
+
119
149
  class ReferenceDefinition # :nodoc:
120
150
  def initialize(
121
151
  name,
@@ -138,16 +168,16 @@ module ActiveRecord
138
168
  end
139
169
 
140
170
  def add_to(table)
141
- columns.each do |column_options|
142
- table.column(*column_options)
171
+ columns.each do |name, type, options|
172
+ table.column(name, type, **options)
143
173
  end
144
174
 
145
175
  if index
146
- table.index(column_names, index_options)
176
+ table.index(column_names, **index_options(table.name))
147
177
  end
148
178
 
149
179
  if foreign_key
150
- table.foreign_key(foreign_table_name, foreign_key_options)
180
+ table.foreign_key(foreign_table_name, **foreign_key_options)
151
181
  end
152
182
  end
153
183
 
@@ -162,8 +192,18 @@ module ActiveRecord
162
192
  as_options(polymorphic).merge(options.slice(:null, :first, :after))
163
193
  end
164
194
 
165
- def index_options
166
- as_options(index)
195
+ def polymorphic_index_name(table_name)
196
+ "index_#{table_name}_on_#{name}"
197
+ end
198
+
199
+ def index_options(table_name)
200
+ index_options = as_options(index)
201
+
202
+ # legacy reference index names are used on versions 6.0 and earlier
203
+ return index_options if options[:_uses_legacy_reference_index_name]
204
+
205
+ index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
206
+ index_options
167
207
  end
168
208
 
169
209
  def foreign_key_options
@@ -199,7 +239,7 @@ module ActiveRecord
199
239
  # Appends a primary key definition to the table definition.
200
240
  # Can be called multiple times, but this is probably not a good idea.
201
241
  def primary_key(name, type = :primary_key, **options)
202
- column(name, type, options.merge(primary_key: true))
242
+ column(name, type, **options.merge(primary_key: true))
203
243
  end
204
244
 
205
245
  ##
@@ -221,16 +261,17 @@ module ActiveRecord
221
261
  end
222
262
 
223
263
  class_methods do
224
- private def define_column_methods(*column_types) # :nodoc:
264
+ def define_column_methods(*column_types) # :nodoc:
225
265
  column_types.each do |column_type|
226
266
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
227
267
  def #{column_type}(*names, **options)
228
268
  raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
229
- names.each { |name| column(name, :#{column_type}, options) }
269
+ names.each { |name| column(name, :#{column_type}, **options) }
230
270
  end
231
271
  RUBY
232
272
  end
233
273
  end
274
+ private :define_column_methods
234
275
  end
235
276
  end
236
277
 
@@ -240,7 +281,7 @@ module ActiveRecord
240
281
  # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
241
282
  # is actually of this type:
242
283
  #
243
- # class SomeMigration < ActiveRecord::Migration[5.0]
284
+ # class SomeMigration < ActiveRecord::Migration[6.0]
244
285
  # def up
245
286
  # create_table :foo do |t|
246
287
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -255,7 +296,7 @@ module ActiveRecord
255
296
  class TableDefinition
256
297
  include ColumnMethods
257
298
 
258
- attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
299
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
259
300
 
260
301
  def initialize(
261
302
  conn,
@@ -272,6 +313,7 @@ module ActiveRecord
272
313
  @indexes = []
273
314
  @foreign_keys = []
274
315
  @primary_keys = nil
316
+ @check_constraints = []
275
317
  @temporary = temporary
276
318
  @if_not_exists = if_not_exists
277
319
  @options = options
@@ -360,10 +402,9 @@ module ActiveRecord
360
402
  # t.references :tagger, polymorphic: true
361
403
  # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
362
404
  # end
363
- def column(name, type, **options)
405
+ def column(name, type, index: nil, **options)
364
406
  name = name.to_s
365
407
  type = type.to_sym if type
366
- options = options.dup
367
408
 
368
409
  if @columns_hash[name]
369
410
  if @columns_hash[name].primary_key?
@@ -373,9 +414,13 @@ module ActiveRecord
373
414
  end
374
415
  end
375
416
 
376
- index_options = options.delete(:index)
377
- index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
378
- @columns_hash[name] = new_column_definition(name, type, options)
417
+ @columns_hash[name] = new_column_definition(name, type, **options)
418
+
419
+ if index
420
+ index_options = index.is_a?(Hash) ? index : {}
421
+ index(name, **index_options)
422
+ end
423
+
379
424
  self
380
425
  end
381
426
 
@@ -389,14 +434,18 @@ module ActiveRecord
389
434
  # This is primarily used to track indexes that need to be created after the table
390
435
  #
391
436
  # index(:account_id, name: 'index_projects_on_account_id')
392
- def index(column_name, options = {})
437
+ def index(column_name, **options)
393
438
  indexes << [column_name, options]
394
439
  end
395
440
 
396
- def foreign_key(table_name, options = {}) # :nodoc:
441
+ def foreign_key(table_name, **options) # :nodoc:
397
442
  foreign_keys << [table_name, options]
398
443
  end
399
444
 
445
+ def check_constraint(expression, **options)
446
+ check_constraints << [expression, options]
447
+ end
448
+
400
449
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
401
450
  # <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
402
451
  #
@@ -408,8 +457,8 @@ module ActiveRecord
408
457
  options[:precision] = 6
409
458
  end
410
459
 
411
- column(:created_at, :datetime, options)
412
- column(:updated_at, :datetime, options)
460
+ column(:created_at, :datetime, **options)
461
+ column(:updated_at, :datetime, **options)
413
462
  end
414
463
 
415
464
  # Adds a reference.
@@ -421,7 +470,7 @@ module ActiveRecord
421
470
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
422
471
  def references(*args, **options)
423
472
  args.each do |ref_name|
424
- ReferenceDefinition.new(ref_name, options).add_to(self)
473
+ ReferenceDefinition.new(ref_name, **options).add_to(self)
425
474
  end
426
475
  end
427
476
  alias :belongs_to :references
@@ -456,14 +505,16 @@ module ActiveRecord
456
505
 
457
506
  class AlterTable # :nodoc:
458
507
  attr_reader :adds
459
- attr_reader :foreign_key_adds
460
- attr_reader :foreign_key_drops
508
+ attr_reader :foreign_key_adds, :foreign_key_drops
509
+ attr_reader :check_constraint_adds, :check_constraint_drops
461
510
 
462
511
  def initialize(td)
463
512
  @td = td
464
513
  @adds = []
465
514
  @foreign_key_adds = []
466
515
  @foreign_key_drops = []
516
+ @check_constraint_adds = []
517
+ @check_constraint_drops = []
467
518
  end
468
519
 
469
520
  def name; @td.name; end
@@ -476,10 +527,18 @@ module ActiveRecord
476
527
  @foreign_key_drops << name
477
528
  end
478
529
 
479
- def add_column(name, type, options)
530
+ def add_check_constraint(expression, options)
531
+ @check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
532
+ end
533
+
534
+ def drop_check_constraint(constraint_name)
535
+ @check_constraint_drops << constraint_name
536
+ end
537
+
538
+ def add_column(name, type, **options)
480
539
  name = name.to_s
481
540
  type = type.to_sym
482
- @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
541
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
483
542
  end
484
543
  end
485
544
 
@@ -496,9 +555,11 @@ module ActiveRecord
496
555
  # t.timestamps
497
556
  # t.change
498
557
  # t.change_default
558
+ # t.change_null
499
559
  # t.rename
500
560
  # t.references
501
561
  # t.belongs_to
562
+ # t.check_constraint
502
563
  # t.string
503
564
  # t.text
504
565
  # t.integer
@@ -520,6 +581,7 @@ module ActiveRecord
520
581
  # t.remove_references
521
582
  # t.remove_belongs_to
522
583
  # t.remove_index
584
+ # t.remove_check_constraint
523
585
  # t.remove_timestamps
524
586
  # end
525
587
  #
@@ -538,10 +600,12 @@ module ActiveRecord
538
600
  # t.column(:name, :string)
539
601
  #
540
602
  # See TableDefinition#column for details of the options you can use.
541
- def column(column_name, type, **options)
542
- index_options = options.delete(:index)
543
- @base.add_column(name, column_name, type, options)
544
- index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
603
+ def column(column_name, type, index: nil, **options)
604
+ @base.add_column(name, column_name, type, **options)
605
+ if index
606
+ index_options = index.is_a?(Hash) ? index : {}
607
+ index(column_name, **index_options)
608
+ end
545
609
  end
546
610
 
547
611
  # Checks to see if a column exists.
@@ -549,8 +613,8 @@ module ActiveRecord
549
613
  # t.string(:name) unless t.column_exists?(:name, :string)
550
614
  #
551
615
  # See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
552
- def column_exists?(column_name, type = nil, options = {})
553
- @base.column_exists?(name, column_name, type, options)
616
+ def column_exists?(column_name, type = nil, **options)
617
+ @base.column_exists?(name, column_name, type, **options)
554
618
  end
555
619
 
556
620
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
@@ -561,8 +625,8 @@ module ActiveRecord
561
625
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
562
626
  #
563
627
  # See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
564
- def index(column_name, options = {})
565
- @base.add_index(name, column_name, options)
628
+ def index(column_name, **options)
629
+ @base.add_index(name, column_name, **options)
566
630
  end
567
631
 
568
632
  # Checks to see if an index exists.
@@ -590,8 +654,8 @@ module ActiveRecord
590
654
  # t.timestamps(null: false)
591
655
  #
592
656
  # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
593
- def timestamps(options = {})
594
- @base.add_timestamps(name, options)
657
+ def timestamps(**options)
658
+ @base.add_timestamps(name, **options)
595
659
  end
596
660
 
597
661
  # Changes the column's definition according to the new options.
@@ -600,8 +664,8 @@ module ActiveRecord
600
664
  # t.change(:description, :text)
601
665
  #
602
666
  # See TableDefinition#column for details of the options you can use.
603
- def change(column_name, type, options = {})
604
- @base.change_column(name, column_name, type, options)
667
+ def change(column_name, type, **options)
668
+ @base.change_column(name, column_name, type, **options)
605
669
  end
606
670
 
607
671
  # Sets a new default value for a column.
@@ -615,14 +679,24 @@ module ActiveRecord
615
679
  @base.change_column_default(name, column_name, default_or_changes)
616
680
  end
617
681
 
682
+ # Sets or removes a NOT NULL constraint on a column.
683
+ #
684
+ # t.change_null(:qualification, true)
685
+ # t.change_null(:qualification, false, 0)
686
+ #
687
+ # See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
688
+ def change_null(column_name, null, default = nil)
689
+ @base.change_column_null(name, column_name, null, default)
690
+ end
691
+
618
692
  # Removes the column(s) from the table definition.
619
693
  #
620
694
  # t.remove(:qualification)
621
695
  # t.remove(:qualification, :experience)
622
696
  #
623
697
  # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
624
- def remove(*column_names)
625
- @base.remove_columns(name, *column_names)
698
+ def remove(*column_names, **options)
699
+ @base.remove_columns(name, *column_names, **options)
626
700
  end
627
701
 
628
702
  # Removes the given index from the table.
@@ -630,10 +704,11 @@ module ActiveRecord
630
704
  # t.remove_index(:branch_id)
631
705
  # t.remove_index(column: [:branch_id, :party_id])
632
706
  # t.remove_index(name: :by_branch_party)
707
+ # t.remove_index(:branch_id, name: :by_branch_party)
633
708
  #
634
709
  # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
635
- def remove_index(options = {})
636
- @base.remove_index(name, options)
710
+ def remove_index(column_name = nil, **options)
711
+ @base.remove_index(name, column_name, **options)
637
712
  end
638
713
 
639
714
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
@@ -641,8 +716,8 @@ module ActiveRecord
641
716
  # t.remove_timestamps
642
717
  #
643
718
  # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
644
- def remove_timestamps(options = {})
645
- @base.remove_timestamps(name, options)
719
+ def remove_timestamps(**options)
720
+ @base.remove_timestamps(name, **options)
646
721
  end
647
722
 
648
723
  # Renames a column.
@@ -662,7 +737,7 @@ module ActiveRecord
662
737
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
663
738
  def references(*args, **options)
664
739
  args.each do |ref_name|
665
- @base.add_reference(name, ref_name, options)
740
+ @base.add_reference(name, ref_name, **options)
666
741
  end
667
742
  end
668
743
  alias :belongs_to :references
@@ -675,7 +750,7 @@ module ActiveRecord
675
750
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
676
751
  def remove_references(*args, **options)
677
752
  args.each do |ref_name|
678
- @base.remove_reference(name, ref_name, options)
753
+ @base.remove_reference(name, ref_name, **options)
679
754
  end
680
755
  end
681
756
  alias :remove_belongs_to :remove_references
@@ -686,8 +761,8 @@ module ActiveRecord
686
761
  # t.foreign_key(:authors, column: :author_id, primary_key: "id")
687
762
  #
688
763
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
689
- def foreign_key(*args)
690
- @base.add_foreign_key(name, *args)
764
+ def foreign_key(*args, **options)
765
+ @base.add_foreign_key(name, *args, **options)
691
766
  end
692
767
 
693
768
  # Removes the given foreign key from the table.
@@ -696,8 +771,8 @@ module ActiveRecord
696
771
  # t.remove_foreign_key(column: :author_id)
697
772
  #
698
773
  # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
699
- def remove_foreign_key(*args)
700
- @base.remove_foreign_key(name, *args)
774
+ def remove_foreign_key(*args, **options)
775
+ @base.remove_foreign_key(name, *args, **options)
701
776
  end
702
777
 
703
778
  # Checks to see if a foreign key exists.
@@ -705,8 +780,26 @@ module ActiveRecord
705
780
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
706
781
  #
707
782
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
708
- def foreign_key_exists?(*args)
709
- @base.foreign_key_exists?(name, *args)
783
+ def foreign_key_exists?(*args, **options)
784
+ @base.foreign_key_exists?(name, *args, **options)
785
+ end
786
+
787
+ # Adds a check constraint.
788
+ #
789
+ # t.check_constraint("price > 0", name: "price_check")
790
+ #
791
+ # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
792
+ def check_constraint(*args)
793
+ @base.add_check_constraint(name, *args)
794
+ end
795
+
796
+ # Removes the given check constraint from the table.
797
+ #
798
+ # t.remove_check_constraint(name: "price_check")
799
+ #
800
+ # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
801
+ def remove_check_constraint(*args)
802
+ @base.remove_check_constraint(name, *args)
710
803
  end
711
804
  end
712
805
  end
@@ -13,9 +13,9 @@ module ActiveRecord
13
13
  end
14
14
 
15
15
  def column_spec_for_primary_key(column)
16
- return {} if default_primary_key?(column)
17
- spec = { id: schema_type(column).inspect }
18
- spec.merge!(prepare_column_options(column).except!(:null, :comment))
16
+ spec = {}
17
+ spec[:id] = schema_type(column).inspect unless default_primary_key?(column)
18
+ spec.merge!(prepare_column_options(column).except!(:null))
19
19
  spec[:default] ||= "nil" if explicit_primary_key_default?(column)
20
20
  spec
21
21
  end