はじめに
railsで実装の途中で新しくDBテーブルを作成した際に、下記の様にエラーが出て"rails db:migrate"が失敗してしまいました。
初めてのエラーだったので、原因と解決法を備忘録として残そうと思います。
~# bundle exec rails db:migrate
Running via Spring preloader in process 1026
== 20221005061523 ~: migrating =========================
-- create_table(:テーブル名)
-> 0.1328s
== 20221005061523 ~: migrated (0.1333s) ================
== 20221005061746 ~: migrating ===================
-- create_table(:テーブル名)
-> 0.0240s
== 20221005061746 ~: migrated (0.0241s) ==========
== 20221005062652 ~: migrating ==================
-- create_table(:テーブル名)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
"Index name '~' on table '~' is too long; the limit is 64 characters"
原因
原因は、エラー文読めばすぐわかりました。
index名が64文字の制限を超えちゃってるので修正してね、ということです。
"Index name '~' on table '~' is too long; the limit is 64 characters"
#=> 翻訳 「テーブル '~' のインデックス名 '~' が長すぎます。制限は 64 文字です」
下記は例ですが、"very_so_very_long_string"というDBテーブルを作成し、"very_so_very_long_foreign_key"というDBテーブルと関連付けをするために"t.references"を用いて外部キーに設定しています。
class CreateVerySoVerySoVeryLongString < ActiveRecord::Migration[6.1]
def change
create_table :very_so_very_so_very_long_string do |t|
t.string :very_so_very_so_very_long_string_name
t.references :very_so_very_so_very_long_foreign_key, null: false, foreign_key: true
t.timestamps
end
end
end
ちなみにデフォルトのindex名は、"作成したDBテーブル名 on 関連付けするDBテーブル_id"の法則がある様なので、
今回の例だと下記になります。
76文字なのでエラーが発生してしまいますね。
#デフォルトのindex名は、"作成したDBテーブル名 on 関連付けするDBテーブル_id"
#今回の場合 =>
"very_so_very_so_very_long_string_on_very_so_very_so_very_long_foreign_key_id"
解決法
そもそも長すぎるテーブル名も考えものかもしれませんが、無理やりテーブル名を短くしてわかりづらくなってしまったら本末転倒だと思います。
テーブル名は変更せずにこのエラーを回避するためには、"t.references"の箇所にindex名を設定するオプションを追加すれば問題なくrails db:migrateが成功します。
#index: { name: '変更名' }を追加し、"change_short_string"に変更
class CreateVerySoVerySoVeryLongString < ActiveRecord::Migration[6.1]
def change
create_table :very_so_very_so_very_long_string do |t|
t.string :very_so_very_so_very_long_string_name
t.references :very_so_very_so_very_long_foreign_key, null: false, foreign_key: true, index: { name: 'change_short_string' }
t.timestamps
end
end
end
参考