activerecord 6.0.0 → 6.1.4

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 +1178 -600
  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 +30 -10
  7. data/lib/active_record/associations/alias_tracker.rb +19 -16
  8. data/lib/active_record/associations/association.rb +55 -29
  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 +25 -8
  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 +77 -42
  28. data/lib/active_record/associations/preloader/association.rb +51 -25
  29. data/lib/active_record/associations/preloader/through_association.rb +2 -2
  30. data/lib/active_record/associations/preloader.rb +13 -8
  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 +120 -13
  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 +63 -44
  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 +12 -3
  49. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
  50. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  51. data/lib/active_record/connection_adapters/abstract/database_statements.rb +87 -38
  52. data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -10
  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 +141 -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 +76 -79
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
  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 +17 -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 +83 -65
  104. data/lib/active_record/connection_adapters/schema_cache.rb +106 -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 +61 -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 +219 -81
  114. data/lib/active_record/core.rb +268 -71
  115. data/lib/active_record/counter_cache.rb +4 -1
  116. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -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 +124 -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 +43 -10
  137. data/lib/active_record/integration.rb +3 -5
  138. data/lib/active_record/internal_metadata.rb +16 -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 +14 -14
  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 +71 -20
  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 +120 -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 +55 -17
  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 +344 -181
  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 -82
  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 +3 -3
  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 +79 -16
  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 +26 -73
  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 +15 -12
  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 +27 -24
  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,14 @@ 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
+ index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
202
+ index_options
167
203
  end
168
204
 
169
205
  def foreign_key_options
@@ -199,7 +235,7 @@ module ActiveRecord
199
235
  # Appends a primary key definition to the table definition.
200
236
  # Can be called multiple times, but this is probably not a good idea.
201
237
  def primary_key(name, type = :primary_key, **options)
202
- column(name, type, options.merge(primary_key: true))
238
+ column(name, type, **options.merge(primary_key: true))
203
239
  end
204
240
 
205
241
  ##
@@ -221,16 +257,17 @@ module ActiveRecord
221
257
  end
222
258
 
223
259
  class_methods do
224
- private def define_column_methods(*column_types) # :nodoc:
260
+ def define_column_methods(*column_types) # :nodoc:
225
261
  column_types.each do |column_type|
226
262
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
227
263
  def #{column_type}(*names, **options)
228
264
  raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
229
- names.each { |name| column(name, :#{column_type}, options) }
265
+ names.each { |name| column(name, :#{column_type}, **options) }
230
266
  end
231
267
  RUBY
232
268
  end
233
269
  end
270
+ private :define_column_methods
234
271
  end
235
272
  end
236
273
 
@@ -240,7 +277,7 @@ module ActiveRecord
240
277
  # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
241
278
  # is actually of this type:
242
279
  #
243
- # class SomeMigration < ActiveRecord::Migration[5.0]
280
+ # class SomeMigration < ActiveRecord::Migration[6.0]
244
281
  # def up
245
282
  # create_table :foo do |t|
246
283
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -255,7 +292,7 @@ module ActiveRecord
255
292
  class TableDefinition
256
293
  include ColumnMethods
257
294
 
258
- attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
295
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
259
296
 
260
297
  def initialize(
261
298
  conn,
@@ -272,6 +309,7 @@ module ActiveRecord
272
309
  @indexes = []
273
310
  @foreign_keys = []
274
311
  @primary_keys = nil
312
+ @check_constraints = []
275
313
  @temporary = temporary
276
314
  @if_not_exists = if_not_exists
277
315
  @options = options
@@ -360,10 +398,9 @@ module ActiveRecord
360
398
  # t.references :tagger, polymorphic: true
361
399
  # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
362
400
  # end
363
- def column(name, type, **options)
401
+ def column(name, type, index: nil, **options)
364
402
  name = name.to_s
365
403
  type = type.to_sym if type
366
- options = options.dup
367
404
 
368
405
  if @columns_hash[name]
369
406
  if @columns_hash[name].primary_key?
@@ -373,9 +410,13 @@ module ActiveRecord
373
410
  end
374
411
  end
375
412
 
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)
413
+ @columns_hash[name] = new_column_definition(name, type, **options)
414
+
415
+ if index
416
+ index_options = index.is_a?(Hash) ? index : {}
417
+ index(name, **index_options)
418
+ end
419
+
379
420
  self
380
421
  end
381
422
 
@@ -389,14 +430,18 @@ module ActiveRecord
389
430
  # This is primarily used to track indexes that need to be created after the table
390
431
  #
391
432
  # index(:account_id, name: 'index_projects_on_account_id')
392
- def index(column_name, options = {})
433
+ def index(column_name, **options)
393
434
  indexes << [column_name, options]
394
435
  end
395
436
 
396
- def foreign_key(table_name, options = {}) # :nodoc:
437
+ def foreign_key(table_name, **options) # :nodoc:
397
438
  foreign_keys << [table_name, options]
398
439
  end
399
440
 
441
+ def check_constraint(expression, **options)
442
+ check_constraints << [expression, options]
443
+ end
444
+
400
445
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
401
446
  # <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
402
447
  #
@@ -408,8 +453,8 @@ module ActiveRecord
408
453
  options[:precision] = 6
409
454
  end
410
455
 
411
- column(:created_at, :datetime, options)
412
- column(:updated_at, :datetime, options)
456
+ column(:created_at, :datetime, **options)
457
+ column(:updated_at, :datetime, **options)
413
458
  end
414
459
 
415
460
  # Adds a reference.
@@ -421,7 +466,7 @@ module ActiveRecord
421
466
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
422
467
  def references(*args, **options)
423
468
  args.each do |ref_name|
424
- ReferenceDefinition.new(ref_name, options).add_to(self)
469
+ ReferenceDefinition.new(ref_name, **options).add_to(self)
425
470
  end
426
471
  end
427
472
  alias :belongs_to :references
@@ -456,14 +501,16 @@ module ActiveRecord
456
501
 
457
502
  class AlterTable # :nodoc:
458
503
  attr_reader :adds
459
- attr_reader :foreign_key_adds
460
- attr_reader :foreign_key_drops
504
+ attr_reader :foreign_key_adds, :foreign_key_drops
505
+ attr_reader :check_constraint_adds, :check_constraint_drops
461
506
 
462
507
  def initialize(td)
463
508
  @td = td
464
509
  @adds = []
465
510
  @foreign_key_adds = []
466
511
  @foreign_key_drops = []
512
+ @check_constraint_adds = []
513
+ @check_constraint_drops = []
467
514
  end
468
515
 
469
516
  def name; @td.name; end
@@ -476,10 +523,18 @@ module ActiveRecord
476
523
  @foreign_key_drops << name
477
524
  end
478
525
 
479
- def add_column(name, type, options)
526
+ def add_check_constraint(expression, options)
527
+ @check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
528
+ end
529
+
530
+ def drop_check_constraint(constraint_name)
531
+ @check_constraint_drops << constraint_name
532
+ end
533
+
534
+ def add_column(name, type, **options)
480
535
  name = name.to_s
481
536
  type = type.to_sym
482
- @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
537
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
483
538
  end
484
539
  end
485
540
 
@@ -496,9 +551,11 @@ module ActiveRecord
496
551
  # t.timestamps
497
552
  # t.change
498
553
  # t.change_default
554
+ # t.change_null
499
555
  # t.rename
500
556
  # t.references
501
557
  # t.belongs_to
558
+ # t.check_constraint
502
559
  # t.string
503
560
  # t.text
504
561
  # t.integer
@@ -520,6 +577,7 @@ module ActiveRecord
520
577
  # t.remove_references
521
578
  # t.remove_belongs_to
522
579
  # t.remove_index
580
+ # t.remove_check_constraint
523
581
  # t.remove_timestamps
524
582
  # end
525
583
  #
@@ -538,10 +596,12 @@ module ActiveRecord
538
596
  # t.column(:name, :string)
539
597
  #
540
598
  # 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
599
+ def column(column_name, type, index: nil, **options)
600
+ @base.add_column(name, column_name, type, **options)
601
+ if index
602
+ index_options = index.is_a?(Hash) ? index : {}
603
+ index(column_name, **index_options)
604
+ end
545
605
  end
546
606
 
547
607
  # Checks to see if a column exists.
@@ -549,8 +609,8 @@ module ActiveRecord
549
609
  # t.string(:name) unless t.column_exists?(:name, :string)
550
610
  #
551
611
  # 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)
612
+ def column_exists?(column_name, type = nil, **options)
613
+ @base.column_exists?(name, column_name, type, **options)
554
614
  end
555
615
 
556
616
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
@@ -561,8 +621,8 @@ module ActiveRecord
561
621
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
562
622
  #
563
623
  # 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)
624
+ def index(column_name, **options)
625
+ @base.add_index(name, column_name, **options)
566
626
  end
567
627
 
568
628
  # Checks to see if an index exists.
@@ -590,8 +650,8 @@ module ActiveRecord
590
650
  # t.timestamps(null: false)
591
651
  #
592
652
  # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
593
- def timestamps(options = {})
594
- @base.add_timestamps(name, options)
653
+ def timestamps(**options)
654
+ @base.add_timestamps(name, **options)
595
655
  end
596
656
 
597
657
  # Changes the column's definition according to the new options.
@@ -600,8 +660,8 @@ module ActiveRecord
600
660
  # t.change(:description, :text)
601
661
  #
602
662
  # 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)
663
+ def change(column_name, type, **options)
664
+ @base.change_column(name, column_name, type, **options)
605
665
  end
606
666
 
607
667
  # Sets a new default value for a column.
@@ -615,14 +675,24 @@ module ActiveRecord
615
675
  @base.change_column_default(name, column_name, default_or_changes)
616
676
  end
617
677
 
678
+ # Sets or removes a NOT NULL constraint on a column.
679
+ #
680
+ # t.change_null(:qualification, true)
681
+ # t.change_null(:qualification, false, 0)
682
+ #
683
+ # See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
684
+ def change_null(column_name, null, default = nil)
685
+ @base.change_column_null(name, column_name, null, default)
686
+ end
687
+
618
688
  # Removes the column(s) from the table definition.
619
689
  #
620
690
  # t.remove(:qualification)
621
691
  # t.remove(:qualification, :experience)
622
692
  #
623
693
  # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
624
- def remove(*column_names)
625
- @base.remove_columns(name, *column_names)
694
+ def remove(*column_names, **options)
695
+ @base.remove_columns(name, *column_names, **options)
626
696
  end
627
697
 
628
698
  # Removes the given index from the table.
@@ -630,10 +700,11 @@ module ActiveRecord
630
700
  # t.remove_index(:branch_id)
631
701
  # t.remove_index(column: [:branch_id, :party_id])
632
702
  # t.remove_index(name: :by_branch_party)
703
+ # t.remove_index(:branch_id, name: :by_branch_party)
633
704
  #
634
705
  # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
635
- def remove_index(options = {})
636
- @base.remove_index(name, options)
706
+ def remove_index(column_name = nil, **options)
707
+ @base.remove_index(name, column_name, **options)
637
708
  end
638
709
 
639
710
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
@@ -641,8 +712,8 @@ module ActiveRecord
641
712
  # t.remove_timestamps
642
713
  #
643
714
  # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
644
- def remove_timestamps(options = {})
645
- @base.remove_timestamps(name, options)
715
+ def remove_timestamps(**options)
716
+ @base.remove_timestamps(name, **options)
646
717
  end
647
718
 
648
719
  # Renames a column.
@@ -662,7 +733,7 @@ module ActiveRecord
662
733
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
663
734
  def references(*args, **options)
664
735
  args.each do |ref_name|
665
- @base.add_reference(name, ref_name, options)
736
+ @base.add_reference(name, ref_name, **options)
666
737
  end
667
738
  end
668
739
  alias :belongs_to :references
@@ -675,7 +746,7 @@ module ActiveRecord
675
746
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
676
747
  def remove_references(*args, **options)
677
748
  args.each do |ref_name|
678
- @base.remove_reference(name, ref_name, options)
749
+ @base.remove_reference(name, ref_name, **options)
679
750
  end
680
751
  end
681
752
  alias :remove_belongs_to :remove_references
@@ -686,8 +757,8 @@ module ActiveRecord
686
757
  # t.foreign_key(:authors, column: :author_id, primary_key: "id")
687
758
  #
688
759
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
689
- def foreign_key(*args)
690
- @base.add_foreign_key(name, *args)
760
+ def foreign_key(*args, **options)
761
+ @base.add_foreign_key(name, *args, **options)
691
762
  end
692
763
 
693
764
  # Removes the given foreign key from the table.
@@ -696,8 +767,8 @@ module ActiveRecord
696
767
  # t.remove_foreign_key(column: :author_id)
697
768
  #
698
769
  # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
699
- def remove_foreign_key(*args)
700
- @base.remove_foreign_key(name, *args)
770
+ def remove_foreign_key(*args, **options)
771
+ @base.remove_foreign_key(name, *args, **options)
701
772
  end
702
773
 
703
774
  # Checks to see if a foreign key exists.
@@ -705,8 +776,26 @@ module ActiveRecord
705
776
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
706
777
  #
707
778
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
708
- def foreign_key_exists?(*args)
709
- @base.foreign_key_exists?(name, *args)
779
+ def foreign_key_exists?(*args, **options)
780
+ @base.foreign_key_exists?(name, *args, **options)
781
+ end
782
+
783
+ # Adds a check constraint.
784
+ #
785
+ # t.check_constraint("price > 0", name: "price_check")
786
+ #
787
+ # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
788
+ def check_constraint(*args)
789
+ @base.add_check_constraint(name, *args)
790
+ end
791
+
792
+ # Removes the given check constraint from the table.
793
+ #
794
+ # t.remove_check_constraint(name: "price_check")
795
+ #
796
+ # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
797
+ def remove_check_constraint(*args)
798
+ @base.remove_check_constraint(name, *args)
710
799
  end
711
800
  end
712
801
  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