activerecord 6.0.0 → 6.1.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1413 -614
  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 +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 +77 -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 +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 +24 -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 +44 -35
  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 +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 +32 -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 +23 -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 +30 -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 +84 -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 +40 -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 +283 -71
  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 +3 -3
  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 +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 +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 +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 +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 +346 -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 +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 +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 +31 -27
  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