Skip to content

Commit 70d3b87

Browse files
authored
Merge pull request rails#47863 from aharpole/fix-create-table-index-name-compatibility
Ensure pre-7.1 migrations use legacy index names when using create_table
2 parents 6cd8ddd + aa909b2 commit 70d3b87

File tree

2 files changed

+58
-26
lines changed

2 files changed

+58
-26
lines changed

activerecord/lib/active_record/migration/compatibility.rb

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,36 @@ def self.find(version)
3333
V7_1 = Current
3434

3535
class V7_0 < V7_1
36+
module LegacyIndexName
37+
private
38+
def legacy_index_name(table_name, options)
39+
if Hash === options
40+
if options[:column]
41+
"index_#{table_name}_on_#{Array(options[:column]) * '_and_'}"
42+
elsif options[:name]
43+
options[:name]
44+
else
45+
raise ArgumentError, "You must specify the index name"
46+
end
47+
else
48+
legacy_index_name(table_name, index_name_options(options))
49+
end
50+
end
51+
52+
def index_name_options(column_names)
53+
if expression_column_name?(column_names)
54+
column_names = column_names.scan(/\w+/).join("_")
55+
end
56+
57+
{ column: column_names }
58+
end
59+
60+
def expression_column_name?(column_name)
61+
column_name.is_a?(String) && /\W/.match?(column_name)
62+
end
63+
end
3664
module TableDefinition
65+
include LegacyIndexName
3766
def column(name, type, **options)
3867
options[:_skip_validate_options] = true
3968
super
@@ -44,11 +73,18 @@ def change(name, type, **options)
4473
super
4574
end
4675

76+
def index(column_name, **options)
77+
options[:name] = legacy_index_name(name, column_name) if options[:name].nil?
78+
super
79+
end
80+
4781
private
4882
def raise_on_if_exist_options(options)
4983
end
5084
end
5185

86+
include LegacyIndexName
87+
5288
def add_column(table_name, column_name, type, **options)
5389
options[:_skip_validate_options] = true
5490
super
@@ -109,32 +145,6 @@ class << t
109145
end
110146
super
111147
end
112-
113-
def legacy_index_name(table_name, options)
114-
if Hash === options
115-
if options[:column]
116-
"index_#{table_name}_on_#{Array(options[:column]) * '_and_'}"
117-
elsif options[:name]
118-
options[:name]
119-
else
120-
raise ArgumentError, "You must specify the index name"
121-
end
122-
else
123-
legacy_index_name(table_name, index_name_options(options))
124-
end
125-
end
126-
127-
def index_name_options(column_names)
128-
if expression_column_name?(column_names)
129-
column_names = column_names.scan(/\w+/).join("_")
130-
end
131-
132-
{ column: column_names }
133-
end
134-
135-
def expression_column_name?(column_name)
136-
column_name.is_a?(String) && /\W/.match?(column_name)
137-
end
138148
end
139149

140150
class V6_1 < V7_0

activerecord/test/cases/migration/compatibility_test.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,28 @@ def migrate(x)
566566
assert_match(/is too long/i, error.message)
567567
end
568568

569+
def test_create_table_add_index_errors_on_too_long_name_7_0
570+
migration = Class.new(ActiveRecord::Migration[7.0]) {
571+
def migrate(x)
572+
create_table :more_testings do |t|
573+
t.integer :foo
574+
t.integer :bar
575+
t.integer :very_long_column_name_to_test_with
576+
t.index [:foo, :bar, :very_long_column_name_to_test_with]
577+
end
578+
end
579+
}.new
580+
581+
error = assert_raises(StandardError) do
582+
ActiveRecord::Migrator.new(:up, [migration], @schema_migration, @internal_metadata).migrate
583+
end
584+
585+
assert_match(/index_more_testings_on_foo_and_bar_and_very_long_column_name_to_test_with/i, error.message)
586+
assert_match(/is too long/i, error.message)
587+
ensure
588+
connection.drop_table :more_testings rescue nil
589+
end
590+
569591
def test_add_reference_on_6_0
570592
create_migration = Class.new(ActiveRecord::Migration[6.0]) {
571593
def version; 100 end

0 commit comments

Comments
 (0)