activerecord 5.0.7.2 → 5.1.0.beta1

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 (216) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +389 -2252
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record.rb +20 -20
  8. data/lib/active_record/aggregations.rb +244 -244
  9. data/lib/active_record/association_relation.rb +5 -5
  10. data/lib/active_record/associations.rb +1579 -1569
  11. data/lib/active_record/associations/alias_tracker.rb +1 -1
  12. data/lib/active_record/associations/association.rb +23 -15
  13. data/lib/active_record/associations/association_scope.rb +83 -81
  14. data/lib/active_record/associations/belongs_to_association.rb +0 -1
  15. data/lib/active_record/associations/builder/belongs_to.rb +16 -14
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  18. data/lib/active_record/associations/collection_association.rb +74 -241
  19. data/lib/active_record/associations/collection_proxy.rb +144 -70
  20. data/lib/active_record/associations/has_many_association.rb +15 -19
  21. data/lib/active_record/associations/has_many_through_association.rb +12 -5
  22. data/lib/active_record/associations/has_one_association.rb +22 -28
  23. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  24. data/lib/active_record/associations/join_dependency.rb +117 -115
  25. data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
  26. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  28. data/lib/active_record/associations/preloader.rb +94 -94
  29. data/lib/active_record/associations/preloader/association.rb +87 -64
  30. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  31. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  32. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  33. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +34 -41
  35. data/lib/active_record/associations/singular_association.rb +8 -25
  36. data/lib/active_record/associations/through_association.rb +3 -6
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  39. data/lib/active_record/attribute_assignment.rb +61 -61
  40. data/lib/active_record/attribute_decorators.rb +35 -13
  41. data/lib/active_record/attribute_methods.rb +56 -65
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  43. data/lib/active_record/attribute_methods/dirty.rb +216 -34
  44. data/lib/active_record/attribute_methods/primary_key.rb +78 -73
  45. data/lib/active_record/attribute_methods/read.rb +39 -35
  46. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  48. data/lib/active_record/attribute_methods/write.rb +36 -30
  49. data/lib/active_record/attribute_mutation_tracker.rb +53 -10
  50. data/lib/active_record/attribute_set.rb +9 -6
  51. data/lib/active_record/attribute_set/builder.rb +41 -49
  52. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  53. data/lib/active_record/attributes.rb +21 -21
  54. data/lib/active_record/autosave_association.rb +13 -13
  55. data/lib/active_record/base.rb +24 -22
  56. data/lib/active_record/callbacks.rb +52 -14
  57. data/lib/active_record/coders/yaml_column.rb +9 -11
  58. data/lib/active_record/collection_cache_key.rb +6 -17
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
  71. data/lib/active_record/connection_adapters/column.rb +27 -5
  72. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  73. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  94. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  97. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
  98. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
  116. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  117. data/lib/active_record/connection_handling.rb +14 -26
  118. data/lib/active_record/core.rb +110 -93
  119. data/lib/active_record/counter_cache.rb +62 -13
  120. data/lib/active_record/define_callbacks.rb +20 -0
  121. data/lib/active_record/dynamic_matchers.rb +80 -79
  122. data/lib/active_record/enum.rb +8 -6
  123. data/lib/active_record/errors.rb +58 -15
  124. data/lib/active_record/explain.rb +1 -2
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +7 -4
  127. data/lib/active_record/fixture_set/file.rb +11 -8
  128. data/lib/active_record/fixtures.rb +66 -53
  129. data/lib/active_record/gem_version.rb +3 -3
  130. data/lib/active_record/inheritance.rb +93 -79
  131. data/lib/active_record/integration.rb +7 -7
  132. data/lib/active_record/internal_metadata.rb +3 -16
  133. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  134. data/lib/active_record/locking/optimistic.rb +64 -56
  135. data/lib/active_record/locking/pessimistic.rb +10 -1
  136. data/lib/active_record/log_subscriber.rb +29 -29
  137. data/lib/active_record/migration.rb +155 -172
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +76 -37
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/model_schema.rb +85 -119
  142. data/lib/active_record/nested_attributes.rb +200 -199
  143. data/lib/active_record/null_relation.rb +10 -33
  144. data/lib/active_record/persistence.rb +45 -38
  145. data/lib/active_record/query_cache.rb +4 -8
  146. data/lib/active_record/querying.rb +2 -3
  147. data/lib/active_record/railtie.rb +16 -17
  148. data/lib/active_record/railties/controller_runtime.rb +6 -2
  149. data/lib/active_record/railties/databases.rake +125 -140
  150. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  151. data/lib/active_record/readonly_attributes.rb +2 -2
  152. data/lib/active_record/reflection.rb +79 -96
  153. data/lib/active_record/relation.rb +72 -115
  154. data/lib/active_record/relation/batches.rb +87 -58
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  156. data/lib/active_record/relation/calculations.rb +154 -160
  157. data/lib/active_record/relation/delegation.rb +30 -29
  158. data/lib/active_record/relation/finder_methods.rb +195 -226
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder.rb +92 -89
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  165. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  166. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +247 -295
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +79 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/result.rb +29 -31
  174. data/lib/active_record/runtime_registry.rb +3 -3
  175. data/lib/active_record/sanitization.rb +182 -197
  176. data/lib/active_record/schema.rb +3 -3
  177. data/lib/active_record/schema_dumper.rb +14 -37
  178. data/lib/active_record/schema_migration.rb +3 -3
  179. data/lib/active_record/scoping.rb +9 -10
  180. data/lib/active_record/scoping/default.rb +87 -91
  181. data/lib/active_record/scoping/named.rb +16 -28
  182. data/lib/active_record/secure_token.rb +2 -2
  183. data/lib/active_record/statement_cache.rb +13 -15
  184. data/lib/active_record/store.rb +31 -32
  185. data/lib/active_record/suppressor.rb +2 -1
  186. data/lib/active_record/table_metadata.rb +9 -5
  187. data/lib/active_record/tasks/database_tasks.rb +72 -65
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  191. data/lib/active_record/timestamp.rb +39 -25
  192. data/lib/active_record/touch_later.rb +1 -2
  193. data/lib/active_record/transactions.rb +98 -110
  194. data/lib/active_record/type.rb +17 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +9 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/serialized.rb +8 -8
  199. data/lib/active_record/type/text.rb +9 -0
  200. data/lib/active_record/type/time.rb +0 -1
  201. data/lib/active_record/type/type_map.rb +11 -15
  202. data/lib/active_record/type/unsigned_integer.rb +15 -0
  203. data/lib/active_record/type_caster.rb +2 -2
  204. data/lib/active_record/type_caster/connection.rb +8 -6
  205. data/lib/active_record/type_caster/map.rb +3 -1
  206. data/lib/active_record/validations.rb +4 -4
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/presence.rb +2 -2
  209. data/lib/active_record/validations/uniqueness.rb +8 -39
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/rails/generators/active_record.rb +4 -4
  212. data/lib/rails/generators/active_record/migration.rb +2 -2
  213. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  215. metadata +22 -13
  216. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -3,30 +3,37 @@ module ActiveRecord
3
3
  # Abstract representation of an index definition on a table. Instances of
4
4
  # this type are typically created and returned by methods in database
5
5
  # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
6
- class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment) #:nodoc:
7
- end
6
+ IndexDefinition = Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment) #:nodoc:
8
7
 
9
8
  # Abstract representation of a column definition. Instances of this type
10
9
  # are typically created by methods in TableDefinition, and added to the
11
10
  # +columns+ attribute of said TableDefinition object, in order to be used
12
11
  # for generating a number of table creation or table changing SQL statements.
13
- class ColumnDefinition < Struct.new(:name, :type, :limit, :precision, :scale, :default, :null, :first, :after, :auto_increment, :primary_key, :collation, :sql_type, :comment) #:nodoc:
14
-
12
+ ColumnDefinition = Struct.new(:name, :type, :options, :sql_type) do # :nodoc:
15
13
  def primary_key?
16
- primary_key || type.to_sym == :primary_key
14
+ options[:primary_key]
17
15
  end
18
- end
19
16
 
20
- class AddColumnDefinition < Struct.new(:column) # :nodoc:
21
- end
17
+ [:limit, :precision, :scale, :default, :null, :collation, :comment].each do |option_name|
18
+ module_eval <<-CODE, __FILE__, __LINE__ + 1
19
+ def #{option_name}
20
+ options[:#{option_name}]
21
+ end
22
22
 
23
- class ChangeColumnDefinition < Struct.new(:column, :name) #:nodoc:
23
+ def #{option_name}=(value)
24
+ options[:#{option_name}] = value
25
+ end
26
+ CODE
27
+ end
24
28
  end
25
29
 
26
- class PrimaryKeyDefinition < Struct.new(:name) # :nodoc:
27
- end
30
+ AddColumnDefinition = Struct.new(:column) # :nodoc:
28
31
 
29
- class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
32
+ ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
33
+
34
+ PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
35
+
36
+ ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
30
37
  def name
31
38
  options[:name]
32
39
  end
@@ -61,9 +68,9 @@ module ActiveRecord
61
68
  end
62
69
 
63
70
  private
64
- def default_primary_key
65
- "id"
66
- end
71
+ def default_primary_key
72
+ "id"
73
+ end
67
74
  end
68
75
 
69
76
  class ReferenceDefinition # :nodoc:
@@ -72,7 +79,7 @@ module ActiveRecord
72
79
  polymorphic: false,
73
80
  index: true,
74
81
  foreign_key: false,
75
- type: :integer,
82
+ type: :bigint,
76
83
  **options
77
84
  )
78
85
  @name = name
@@ -101,49 +108,55 @@ module ActiveRecord
101
108
  end
102
109
  end
103
110
 
111
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
112
+ # Workaround for Ruby 2.2 "private attribute?" warning.
104
113
  protected
105
114
 
106
- attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
115
+ attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
107
116
 
108
117
  private
109
118
 
110
- def as_options(value)
111
- value.is_a?(Hash) ? value : {}
112
- end
119
+ def as_options(value, default = {})
120
+ if value.is_a?(Hash)
121
+ value
122
+ else
123
+ default
124
+ end
125
+ end
113
126
 
114
- def polymorphic_options
115
- as_options(polymorphic).merge(null: options[:null])
116
- end
127
+ def polymorphic_options
128
+ as_options(polymorphic, options)
129
+ end
117
130
 
118
- def index_options
119
- as_options(index)
120
- end
131
+ def index_options
132
+ as_options(index)
133
+ end
121
134
 
122
- def foreign_key_options
123
- as_options(foreign_key).merge(column: column_name)
124
- end
135
+ def foreign_key_options
136
+ as_options(foreign_key).merge(column: column_name)
137
+ end
125
138
 
126
- def columns
127
- result = [[column_name, type, options]]
128
- if polymorphic
129
- result.unshift(["#{name}_type", :string, polymorphic_options])
139
+ def columns
140
+ result = [[column_name, type, options]]
141
+ if polymorphic
142
+ result.unshift(["#{name}_type", :string, polymorphic_options])
143
+ end
144
+ result
130
145
  end
131
- result
132
- end
133
146
 
134
- def column_name
135
- "#{name}_id"
136
- end
147
+ def column_name
148
+ "#{name}_id"
149
+ end
137
150
 
138
- def column_names
139
- columns.map(&:first)
140
- end
151
+ def column_names
152
+ columns.map(&:first)
153
+ end
141
154
 
142
- def foreign_table_name
143
- foreign_key_options.fetch(:to_table) do
144
- Base.pluralize_table_names ? name.to_s.pluralize : name
155
+ def foreign_table_name
156
+ foreign_key_options.fetch(:to_table) do
157
+ Base.pluralize_table_names ? name.to_s.pluralize : name
158
+ end
145
159
  end
146
- end
147
160
  end
148
161
 
149
162
  module ColumnMethods
@@ -172,6 +185,7 @@ module ActiveRecord
172
185
  :text,
173
186
  :time,
174
187
  :timestamp,
188
+ :virtual,
175
189
  ].each do |column_type|
176
190
  module_eval <<-CODE, __FILE__, __LINE__ + 1
177
191
  def #{column_type}(*args, **options)
@@ -338,9 +352,7 @@ module ActiveRecord
338
352
  # <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
339
353
  #
340
354
  # t.timestamps null: false
341
- def timestamps(*args)
342
- options = args.extract_options!
343
-
355
+ def timestamps(**options)
344
356
  options[:null] = false if options[:null].nil?
345
357
 
346
358
  column(:created_at, :datetime, options)
@@ -354,38 +366,27 @@ module ActiveRecord
354
366
  #
355
367
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
356
368
  def references(*args, **options)
357
- args.each do |col|
358
- ReferenceDefinition.new(col, **options).add_to(self)
369
+ args.each do |ref_name|
370
+ ReferenceDefinition.new(ref_name, options).add_to(self)
359
371
  end
360
372
  end
361
373
  alias :belongs_to :references
362
374
 
363
- def new_column_definition(name, type, options) # :nodoc:
375
+ def new_column_definition(name, type, **options) # :nodoc:
364
376
  type = aliased_types(type.to_s, type)
365
- column = create_column_definition name, type
366
-
367
- column.limit = options[:limit]
368
- column.precision = options[:precision]
369
- column.scale = options[:scale]
370
- column.default = options[:default]
371
- column.null = options[:null]
372
- column.first = options[:first]
373
- column.after = options[:after]
374
- column.auto_increment = options[:auto_increment]
375
- column.primary_key = type == :primary_key || options[:primary_key]
376
- column.collation = options[:collation]
377
- column.comment = options[:comment]
378
- column
377
+ options[:primary_key] ||= type == :primary_key
378
+ options[:null] = false if options[:primary_key]
379
+ create_column_definition(name, type, options)
379
380
  end
380
381
 
381
382
  private
382
- def create_column_definition(name, type)
383
- ColumnDefinition.new name, type
384
- end
383
+ def create_column_definition(name, type, options)
384
+ ColumnDefinition.new(name, type, options)
385
+ end
385
386
 
386
- def aliased_types(name, fallback)
387
- 'timestamp' == name ? :datetime : fallback
388
- end
387
+ def aliased_types(name, fallback)
388
+ "timestamp" == name ? :datetime : fallback
389
+ end
389
390
  end
390
391
 
391
392
  class AlterTable # :nodoc:
@@ -474,7 +475,7 @@ module ActiveRecord
474
475
 
475
476
  # Checks to see if a column exists.
476
477
  #
477
- # t.string(:name) unless t.column_exists?(:name, :string)
478
+ # t.string(:name) unless t.column_exists?(:name, :string)
478
479
  #
479
480
  # See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
480
481
  def column_exists?(column_name, type = nil, options = {})
@@ -495,9 +496,9 @@ module ActiveRecord
495
496
 
496
497
  # Checks to see if an index exists.
497
498
  #
498
- # unless t.index_exists?(:branch_id)
499
- # t.index(:branch_id)
500
- # end
499
+ # unless t.index_exists?(:branch_id)
500
+ # t.index(:branch_id)
501
+ # end
501
502
  #
502
503
  # See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
503
504
  def index_exists?(column_name, options = {})
@@ -588,8 +589,7 @@ module ActiveRecord
588
589
  # t.belongs_to(:supplier, foreign_key: true)
589
590
  #
590
591
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
591
- def references(*args)
592
- options = args.extract_options!
592
+ def references(*args, **options)
593
593
  args.each do |ref_name|
594
594
  @base.add_reference(name, ref_name, options)
595
595
  end
@@ -602,8 +602,7 @@ module ActiveRecord
602
602
  # t.remove_belongs_to(:supplier, polymorphic: true)
603
603
  #
604
604
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
605
- def remove_references(*args)
606
- options = args.extract_options!
605
+ def remove_references(*args, **options)
607
606
  args.each do |ref_name|
608
607
  @base.remove_reference(name, ref_name, options)
609
608
  end
@@ -7,16 +7,15 @@ module ActiveRecord
7
7
  # Adapter level by over-writing this code inside the database specific adapters
8
8
  module ColumnDumper
9
9
  def column_spec(column)
10
- spec = Hash[prepare_column_options(column).map { |k, v| [k, "#{k}: #{v}"] }]
11
- spec[:name] = column.name.inspect
12
- spec[:type] = schema_type(column).to_s
13
- spec
10
+ [schema_type_with_virtual(column), prepare_column_options(column)]
14
11
  end
15
12
 
16
13
  def column_spec_for_primary_key(column)
17
14
  return {} if default_primary_key?(column)
18
15
  spec = { id: schema_type(column).inspect }
19
16
  spec.merge!(prepare_column_options(column).except!(:null))
17
+ spec[:default] ||= "nil" if explicit_primary_key_default?(column)
18
+ spec
20
19
  end
21
20
 
22
21
  # This can be overridden on an Adapter level basis to support other
@@ -38,9 +37,9 @@ module ActiveRecord
38
37
  end
39
38
 
40
39
  default = schema_default(column) if column.has_default?
41
- spec[:default] = default unless default.nil?
40
+ spec[:default] = default unless default.nil?
42
41
 
43
- spec[:null] = 'false' unless column.null
42
+ spec[:null] = "false" unless column.null
44
43
 
45
44
  if collation = schema_collation(column)
46
45
  spec[:collation] = collation
@@ -52,54 +51,67 @@ module ActiveRecord
52
51
  end
53
52
 
54
53
  # Lists the valid migration options
55
- def migration_keys
56
- [:name, :limit, :precision, :scale, :default, :null, :collation, :comment]
54
+ def migration_keys # :nodoc:
55
+ column_options_keys
57
56
  end
57
+ deprecate :migration_keys
58
58
 
59
59
  private
60
60
 
61
- def default_primary_key?(column)
62
- schema_type(column) == :integer
63
- end
61
+ def default_primary_key?(column)
62
+ schema_type(column) == :bigint
63
+ end
64
64
 
65
- def schema_type(column)
66
- if column.bigint?
67
- :bigint
68
- else
69
- column.type
65
+ def explicit_primary_key_default?(column)
66
+ false
70
67
  end
71
- end
72
68
 
73
- def schema_limit(column)
74
- limit = column.limit unless column.bigint?
75
- limit.inspect if limit && limit != native_database_types[column.type][:limit]
76
- end
69
+ def schema_type_with_virtual(column)
70
+ if supports_virtual_columns? && column.virtual?
71
+ :virtual
72
+ else
73
+ schema_type(column)
74
+ end
75
+ end
77
76
 
78
- def schema_precision(column)
79
- column.precision.inspect if column.precision
80
- end
77
+ def schema_type(column)
78
+ if column.bigint?
79
+ :bigint
80
+ else
81
+ column.type
82
+ end
83
+ end
81
84
 
82
- def schema_scale(column)
83
- column.scale.inspect if column.scale
84
- end
85
+ def schema_limit(column)
86
+ limit = column.limit unless column.bigint?
87
+ limit.inspect if limit && limit != native_database_types[column.type][:limit]
88
+ end
85
89
 
86
- def schema_default(column)
87
- type = lookup_cast_type_from_column(column)
88
- default = type.deserialize(column.default)
89
- if default.nil?
90
- schema_expression(column)
91
- else
92
- type.type_cast_for_schema(default)
90
+ def schema_precision(column)
91
+ column.precision.inspect if column.precision
93
92
  end
94
- end
95
93
 
96
- def schema_expression(column)
97
- "-> { #{column.default_function.inspect} }" if column.default_function
98
- end
94
+ def schema_scale(column)
95
+ column.scale.inspect if column.scale
96
+ end
99
97
 
100
- def schema_collation(column)
101
- column.collation.inspect if column.collation
102
- end
98
+ def schema_default(column)
99
+ type = lookup_cast_type_from_column(column)
100
+ default = type.deserialize(column.default)
101
+ if default.nil?
102
+ schema_expression(column)
103
+ else
104
+ type.type_cast_for_schema(default)
105
+ end
106
+ end
107
+
108
+ def schema_expression(column)
109
+ "-> { #{column.default_function.inspect} }" if column.default_function
110
+ end
111
+
112
+ def schema_collation(column)
113
+ column.collation.inspect if column.collation
114
+ end
103
115
  end
104
116
  end
105
117
  end
@@ -1,6 +1,6 @@
1
- require 'active_record/migration/join_table'
2
- require 'active_support/core_ext/string/access'
3
- require 'digest'
1
+ require "active_record/migration/join_table"
2
+ require "active_support/core_ext/string/access"
3
+ require "digest"
4
4
 
5
5
  module ActiveRecord
6
6
  module ConnectionAdapters # :nodoc:
@@ -25,7 +25,7 @@ module ActiveRecord
25
25
 
26
26
  # Truncates a table alias according to the limits of the current adapter.
27
27
  def table_alias_for(table_name)
28
- table_name[0...table_alias_length].tr('.', '_')
28
+ table_name[0...table_alias_length].tr(".", "_")
29
29
  end
30
30
 
31
31
  # Returns the relation names useable to back Active Record models.
@@ -43,7 +43,7 @@ module ActiveRecord
43
43
  end
44
44
 
45
45
  # Returns an array of table names defined in the database.
46
- def tables(name = nil)
46
+ def tables
47
47
  raise NotImplementedError, "#tables is not implemented"
48
48
  end
49
49
 
@@ -69,7 +69,9 @@ module ActiveRecord
69
69
  end
70
70
 
71
71
  # Returns an array of indexes for the given table.
72
- # def indexes(table_name, name = nil) end
72
+ def indexes(table_name, name = nil)
73
+ raise NotImplementedError, "#indexes is not implemented"
74
+ end
73
75
 
74
76
  # Checks to see if an index exists on a table for a given index definition.
75
77
  #
@@ -120,7 +122,7 @@ module ActiveRecord
120
122
  checks = []
121
123
  checks << lambda { |c| c.name == column_name }
122
124
  checks << lambda { |c| c.type == type } if type
123
- (migration_keys - [:name]).each do |attr|
125
+ column_options_keys.each do |attr|
124
126
  checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
125
127
  end
126
128
 
@@ -174,7 +176,7 @@ module ActiveRecord
174
176
  # A Symbol can be used to specify the type of the generated primary key column.
175
177
  # [<tt>:primary_key</tt>]
176
178
  # The name of the primary key, if one is to be added automatically.
177
- # Defaults to +id+. If <tt>:id</tt> is false this option is ignored.
179
+ # Defaults to +id+. If <tt>:id</tt> is false, then this option is ignored.
178
180
  #
179
181
  # Note that Active Record models will automatically detect their
180
182
  # primary key. This can be avoided by using
@@ -271,8 +273,8 @@ module ActiveRecord
271
273
 
272
274
  yield td if block_given?
273
275
 
274
- if options[:force] && data_source_exists?(table_name)
275
- drop_table(table_name, options)
276
+ if options[:force]
277
+ drop_table(table_name, **options, if_exists: true)
276
278
  end
277
279
 
278
280
  result = execute schema_creation.accept td
@@ -300,9 +302,9 @@ module ActiveRecord
300
302
  # # Creates a table called 'assemblies_parts' with no id.
301
303
  # create_join_table(:assemblies, :parts)
302
304
  #
303
- # You can pass a +options+ hash can include the following keys:
305
+ # You can pass an +options+ hash which can include the following keys:
304
306
  # [<tt>:table_name</tt>]
305
- # Sets the table name overriding the default
307
+ # Sets the table name, overriding the default.
306
308
  # [<tt>:column_options</tt>]
307
309
  # Any extra options you want appended to the columns definition.
308
310
  # [<tt>:options</tt>]
@@ -339,7 +341,7 @@ module ActiveRecord
339
341
  column_options.reverse_merge!(null: false)
340
342
  type = column_options.delete(:type) || :integer
341
343
 
342
- t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key }
344
+ t1_column, t2_column = [table_1, table_2].map { |t| t.to_s.singularize.foreign_key }
343
345
 
344
346
  create_table(join_table_name, options.merge!(id: false)) do |td|
345
347
  td.send type, t1_column, column_options
@@ -428,7 +430,7 @@ module ActiveRecord
428
430
  # t.remove_index :company_id
429
431
  # end
430
432
  #
431
- # See also Table for details on all of the various column transformation.
433
+ # See also Table for details on all of the various column transformations.
432
434
  def change_table(table_name, options = {})
433
435
  if supports_bulk_alter? && options[:bulk]
434
436
  recorder = ActiveRecord::Migration::CommandRecorder.new(self)
@@ -478,10 +480,10 @@ module ActiveRecord
478
480
  #
479
481
  # Available options are (none of these exists by default):
480
482
  # * <tt>:limit</tt> -
481
- # Requests a maximum column length. This is number of characters for a <tt>:string</tt> column
483
+ # Requests a maximum column length. This is the number of characters for a <tt>:string</tt> column
482
484
  # and number of bytes for <tt>:text</tt>, <tt>:binary</tt> and <tt>:integer</tt> columns.
483
485
  # * <tt>:default</tt> -
484
- # The column's default value. Use nil for NULL.
486
+ # The column's default value. Use +nil+ for +NULL+.
485
487
  # * <tt>:null</tt> -
486
488
  # Allows or disallows +NULL+ values in the column. This option could
487
489
  # have been named <tt>:null_allowed</tt>.
@@ -490,7 +492,7 @@ module ActiveRecord
490
492
  # * <tt>:scale</tt> -
491
493
  # Specifies the scale for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
492
494
  #
493
- # Note: The precision is the total number of significant digits
495
+ # Note: The precision is the total number of significant digits,
494
496
  # and the scale is the number of digits that can be stored following
495
497
  # the decimal point. For example, the number 123.45 has a precision of 5
496
498
  # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
@@ -511,7 +513,7 @@ module ActiveRecord
511
513
  # Default is (38,0).
512
514
  # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
513
515
  # Default unknown.
514
- # * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
516
+ # * SqlServer: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
515
517
  # Default (38,0).
516
518
  #
517
519
  # == Examples
@@ -533,6 +535,10 @@ module ActiveRecord
533
535
  # add_column(:measurements, :huge_integer, :decimal, precision: 30)
534
536
  # # ALTER TABLE "measurements" ADD "huge_integer" decimal(30)
535
537
  #
538
+ # # Defines a column that stores an array of a type.
539
+ # add_column(:users, :skills, :text, array: true)
540
+ # # ALTER TABLE "users" ADD "skills" text[]
541
+ #
536
542
  # # Defines a column with a database-specific type.
537
543
  # add_column(:shapes, :triangle, 'polygon')
538
544
  # # ALTER TABLE "shapes" ADD "triangle" polygon
@@ -559,7 +565,7 @@ module ActiveRecord
559
565
  #
560
566
  # The +type+ and +options+ parameters will be ignored if present. It can be helpful
561
567
  # to provide these in a migration's +change+ method so it can be reverted.
562
- # In that case, +type+ and +options+ will be used by add_column.
568
+ # In that case, +type+ and +options+ will be used by #add_column.
563
569
  def remove_column(table_name, column_name, type = nil, options = {})
564
570
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
565
571
  end
@@ -767,11 +773,12 @@ module ActiveRecord
767
773
  end
768
774
 
769
775
  # Verifies the existence of an index with a given name.
770
- #
771
- # The default argument is returned if the underlying implementation does not define the indexes method,
772
- # as there's no way to determine the correct answer in that case.
773
- def index_name_exists?(table_name, index_name, default)
774
- return default unless respond_to?(:indexes)
776
+ def index_name_exists?(table_name, index_name, default = nil)
777
+ unless default.nil?
778
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
779
+ Passing default to #index_name_exists? is deprecated without replacement.
780
+ MSG
781
+ end
775
782
  index_name = index_name.to_s
776
783
  indexes(table_name).detect { |i| i.name == index_name }
777
784
  end
@@ -822,8 +829,8 @@ module ActiveRecord
822
829
  #
823
830
  # add_reference(:products, :supplier, foreign_key: {to_table: :firms})
824
831
  #
825
- def add_reference(table_name, *args)
826
- ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self))
832
+ def add_reference(table_name, ref_name, **options)
833
+ ReferenceDefinition.new(ref_name, options).add_to(update_table_definition(table_name, self))
827
834
  end
828
835
  alias :add_belongs_to :add_reference
829
836
 
@@ -947,13 +954,13 @@ module ActiveRecord
947
954
 
948
955
  # Checks to see if a foreign key exists on a table for a given foreign key definition.
949
956
  #
950
- # # Check a foreign key exists
957
+ # # Checks to see if a foreign key exists.
951
958
  # foreign_key_exists?(:accounts, :branches)
952
959
  #
953
- # # Check a foreign key on a specified column exists
960
+ # # Checks to see if a foreign key on a specified column exists.
954
961
  # foreign_key_exists?(:accounts, column: :owner_id)
955
962
  #
956
- # # Check a foreign key with a custom name exists
963
+ # # Checks to see if a foreign key with a custom name exists.
957
964
  # foreign_key_exists?(:accounts, name: "special_fk_name")
958
965
  #
959
966
  def foreign_key_exists?(from_table, options_or_to_table = {})
@@ -962,12 +969,12 @@ module ActiveRecord
962
969
 
963
970
  def foreign_key_for(from_table, options_or_to_table = {}) # :nodoc:
964
971
  return unless supports_foreign_keys?
965
- foreign_keys(from_table).detect {|fk| fk.defined_for? options_or_to_table }
972
+ foreign_keys(from_table).detect { |fk| fk.defined_for? options_or_to_table }
966
973
  end
967
974
 
968
975
  def foreign_key_for!(from_table, options_or_to_table = {}) # :nodoc:
969
- foreign_key_for(from_table, options_or_to_table) or \
970
- raise ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}"
976
+ foreign_key_for(from_table, options_or_to_table) || \
977
+ raise(ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}")
971
978
  end
972
979
 
973
980
  def foreign_key_column_for(table_name) # :nodoc:
@@ -985,8 +992,8 @@ module ActiveRecord
985
992
  end
986
993
 
987
994
  def dump_schema_information #:nodoc:
988
- versions = ActiveRecord::SchemaMigration.order('version').pluck(:version)
989
- insert_versions_sql(versions) if versions.any?
995
+ versions = ActiveRecord::SchemaMigration.order("version").pluck(:version)
996
+ insert_versions_sql(versions)
990
997
  end
991
998
 
992
999
  def insert_versions_sql(versions) # :nodoc:
@@ -1002,15 +1009,15 @@ module ActiveRecord
1002
1009
  end
1003
1010
  end
1004
1011
 
1005
- # Should not be called normally, but this operation is non-destructive.
1006
- # The migrations module handles this automatically.
1007
- def initialize_schema_migrations_table
1012
+ def initialize_schema_migrations_table # :nodoc:
1008
1013
  ActiveRecord::SchemaMigration.create_table
1009
1014
  end
1015
+ deprecate :initialize_schema_migrations_table
1010
1016
 
1011
- def initialize_internal_metadata_table
1017
+ def initialize_internal_metadata_table # :nodoc:
1012
1018
  ActiveRecord::InternalMetadata.create_table
1013
1019
  end
1020
+ deprecate :initialize_internal_metadata_table
1014
1021
 
1015
1022
  def internal_string_options_for_primary_key # :nodoc:
1016
1023
  { primary_key: true }
@@ -1022,17 +1029,18 @@ module ActiveRecord
1022
1029
  sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
1023
1030
 
1024
1031
  migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
1025
- versions = ActiveRecord::Migrator.migration_files(migrations_paths).map do |file|
1026
- ActiveRecord::Migrator.parse_migration_filename(file).first.to_i
1032
+ paths = migrations_paths.map { |p| "#{p}/[0-9]*_*.rb" }
1033
+ versions = Dir[*paths].map do |filename|
1034
+ filename.split("/").last.split("_").first.to_i
1027
1035
  end
1028
1036
 
1029
1037
  unless migrated.include?(version)
1030
1038
  execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version)})"
1031
1039
  end
1032
1040
 
1033
- inserting = (versions - migrated).select {|v| v < version}
1041
+ inserting = (versions - migrated).select { |v| v < version }
1034
1042
  if inserting.any?
1035
- if (duplicate = inserting.detect {|v| inserting.count(v) > 1})
1043
+ if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
1036
1044
  raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
1037
1045
  end
1038
1046
  if supports_multi_insert?
@@ -1045,7 +1053,7 @@ module ActiveRecord
1045
1053
  end
1046
1054
  end
1047
1055
 
1048
- def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
1056
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **) # :nodoc:
1049
1057
  type = type.to_sym if type
1050
1058
  if native = native_database_types[type]
1051
1059
  column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
@@ -1063,7 +1071,7 @@ module ActiveRecord
1063
1071
  raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
1064
1072
  end
1065
1073
 
1066
- elsif [:datetime, :time].include?(type) && precision ||= native[:precision]
1074
+ elsif [:datetime, :timestamp, :time, :interval].include?(type) && precision ||= native[:precision]
1067
1075
  if (0..6) === precision
1068
1076
  column_type_sql << "(#{precision})"
1069
1077
  else
@@ -1080,7 +1088,7 @@ module ActiveRecord
1080
1088
  end
1081
1089
 
1082
1090
  # Given a set of columns and an ORDER BY clause, returns the columns for a SELECT DISTINCT.
1083
- # PostgreSQL, MySQL, and Oracle overrides this for custom DISTINCT syntax - they
1091
+ # PostgreSQL, MySQL, and Oracle override this for custom DISTINCT syntax - they
1084
1092
  # require the order columns appear in the SELECT.
1085
1093
  #
1086
1094
  # columns_for_distinct("posts.id", ["posts.created_at desc"])
@@ -1123,7 +1131,6 @@ module ActiveRecord
1123
1131
  index_type ||= options[:unique] ? "UNIQUE" : ""
1124
1132
  index_name = options[:name].to_s if options.key?(:name)
1125
1133
  index_name ||= index_name(table_name, column_names)
1126
- max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
1127
1134
 
1128
1135
  if options.key?(:algorithm)
1129
1136
  algorithm = index_algorithms.fetch(options[:algorithm]) {
@@ -1137,10 +1144,9 @@ module ActiveRecord
1137
1144
  index_options = options[:where] ? " WHERE #{options[:where]}" : ""
1138
1145
  end
1139
1146
 
1140
- if index_name.length > max_index_length
1141
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
1142
- end
1143
- if data_source_exists?(table_name) && index_name_exists?(table_name, index_name, false)
1147
+ validate_index_length!(table_name, index_name, options.fetch(:internal, false))
1148
+
1149
+ if data_source_exists?(table_name) && index_name_exists?(table_name, index_name)
1144
1150
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
1145
1151
  end
1146
1152
  index_columns = quoted_columns_for_index(column_names, options).join(", ")
@@ -1162,7 +1168,10 @@ module ActiveRecord
1162
1168
  raise NotImplementedError, "#{self.class} does not support changing column comments"
1163
1169
  end
1164
1170
 
1165
- protected
1171
+ private
1172
+ def column_options_keys
1173
+ [:limit, :precision, :scale, :default, :null, :collation, :comment]
1174
+ end
1166
1175
 
1167
1176
  def add_index_sort_order(quoted_columns, **options)
1168
1177
  if order = options[:order]
@@ -1197,10 +1206,6 @@ module ActiveRecord
1197
1206
  def index_name_for_remove(table_name, options = {})
1198
1207
  return options[:name] if can_remove_index_by_name?(options)
1199
1208
 
1200
- # if the adapter doesn't support the indexes call the best we can do
1201
- # is return the default index name for the options provided
1202
- return index_name(table_name, options) unless respond_to?(:indexes)
1203
-
1204
1209
  checks = []
1205
1210
 
1206
1211
  if options.is_a?(Hash)
@@ -1250,56 +1255,57 @@ module ActiveRecord
1250
1255
  end
1251
1256
  end
1252
1257
 
1253
- private
1254
- def create_table_definition(*args)
1255
- TableDefinition.new(*args)
1256
- end
1257
-
1258
- def create_alter_table(name)
1259
- AlterTable.new create_table_definition(name)
1260
- end
1258
+ def create_table_definition(*args)
1259
+ TableDefinition.new(*args)
1260
+ end
1261
1261
 
1262
- def index_column_names(column_names)
1263
- if column_names.is_a?(String) && /\W/ === column_names
1264
- column_names
1265
- else
1266
- Array(column_names)
1262
+ def create_alter_table(name)
1263
+ AlterTable.new create_table_definition(name)
1267
1264
  end
1268
- end
1269
1265
 
1270
- def index_name_options(column_names) # :nodoc:
1271
- if column_names.is_a?(String) && /\W/ === column_names
1272
- column_names = column_names.scan(/\w+/).join('_')
1266
+ def index_column_names(column_names)
1267
+ if column_names.is_a?(String) && /\W/.match?(column_names)
1268
+ column_names
1269
+ else
1270
+ Array(column_names)
1271
+ end
1273
1272
  end
1274
1273
 
1275
- { column: column_names }
1276
- end
1274
+ def index_name_options(column_names)
1275
+ if column_names.is_a?(String) && /\W/.match?(column_names)
1276
+ column_names = column_names.scan(/\w+/).join("_")
1277
+ end
1277
1278
 
1278
- def foreign_key_name(table_name, options) # :nodoc:
1279
- identifier = "#{table_name}_#{options.fetch(:column)}_fk"
1280
- hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
1281
- options.fetch(:name) do
1282
- "fk_rails_#{hashed_identifier}"
1279
+ { column: column_names }
1283
1280
  end
1284
- end
1285
1281
 
1286
- def validate_index_length!(table_name, new_name) # :nodoc:
1287
- if new_name.length > allowed_index_name_length
1288
- raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
1282
+ def foreign_key_name(table_name, options)
1283
+ identifier = "#{table_name}_#{options.fetch(:column)}_fk"
1284
+ hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
1285
+ options.fetch(:name) do
1286
+ "fk_rails_#{hashed_identifier}"
1287
+ end
1289
1288
  end
1290
- end
1291
1289
 
1292
- def extract_new_default_value(default_or_changes)
1293
- if default_or_changes.is_a?(Hash) && default_or_changes.has_key?(:from) && default_or_changes.has_key?(:to)
1294
- default_or_changes[:to]
1295
- else
1296
- default_or_changes
1290
+ def validate_index_length!(table_name, new_name, internal = false)
1291
+ max_index_length = internal ? index_name_length : allowed_index_name_length
1292
+
1293
+ if new_name.length > max_index_length
1294
+ raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
1295
+ end
1297
1296
  end
1298
- end
1299
1297
 
1300
- def can_remove_index_by_name?(options)
1301
- options.is_a?(Hash) && options.key?(:name) && options.except(:name, :algorithm).empty?
1302
- end
1298
+ def extract_new_default_value(default_or_changes)
1299
+ if default_or_changes.is_a?(Hash) && default_or_changes.has_key?(:from) && default_or_changes.has_key?(:to)
1300
+ default_or_changes[:to]
1301
+ else
1302
+ default_or_changes
1303
+ end
1304
+ end
1305
+
1306
+ def can_remove_index_by_name?(options)
1307
+ options.is_a?(Hash) && options.key?(:name) && options.except(:name, :algorithm).empty?
1308
+ end
1303
1309
  end
1304
1310
  end
1305
1311
  end