Railsのmigrationでreferencesの張られたカラムを削除するとき、自動生成されたmigrationのままではカラムの削除ができなくてハマったので書き残しておく。
何も考えずにremove_columnをつかって
$ rails generate migration remove_カラム名_from_テーブル名
でカラムの削除をしようとすると、外部キー制約に引っかかるため削除ができない。
「カラム名:references」を後尾につけると、remove_reference と remove_foreign_key が自動付与されるので良い。
$ rails generate migration remove_カラム名_from_テーブル名 カラム名:references
$ rails g migration remove_content_from_item content:references
class RemoveContentIdFromItem < ActiveRecord::Migration
def change
remove_reference :items, :content, index: true
remove_foreign_key :items, :contents
end
end
$ bundle exec rake db:migrate
== 20160226074929 RemoveArticleFromContent: migrating =========================
-- remove_reference(:contents, :article, {:index=>true})
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Cannot drop index 'index_contents_on_article_id': needed in a foreign key constraint: ALTER TABLE `contents` DROP `article_id`/Users/imachan0322/Project/kapiyva-20160226/db/migrate/20160226074929_remove_article_from_content.rb:3:in `change'
できない・・・
原因がわからなくて1時間くらいハマってようやく以下でできた。
class RemoveContentFromItem < ActiveRecord::Migration
def change
remove_foreign_key :items, :contents
remove_reference :items, :content, index: true
end
end
remove_foreign_key と remove_reference の順序を逆にすると大丈夫だった。