初めに
某ガイドの学習中にエラーが発生したため、その解決方法を記事にします。
初めての投稿ですので、至らぬ点などあればご指摘いただけますと幸いです。
エラーが発生した状況
- UserテーブルとTaskテーブルがあります。
- User : Taskの間で1 : 多の関係となるように、マイグレーションファイルを作成し、マイグレーションを行ったタイミングで下記エラーが発生しました。
発生したエラー
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: Cannot add a NOT NULL column with default value NULL: ALTER TABLE "tasks" ADD "user_id" integer NOT NULL
エラー内容を見てみると「Cannot add a NOT NULL column with default value」と記載があるとおり、columnにNOT NULLを与えることができないとなっています。
エラーが発生した際のマイグレーションファイルは以下のとおりです。
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
def up
execute "DELETE FROM tasks;"
add_reference :tasks, :user, null: false, index: true
end
end
execute "DELETE FROM tasks;"はSQLによって、ここまでに作成したタスクを削除しています。
add_reference :tasks, :user, null: false, index: trueでは、tasksにuserと関連付けたuser_idカラムを追加し、制約としてnull: false, index: trueオプションをつけようとしています。
このadd_reference行についてエラーが発生しました。
解決した方法
先にも記載したとおり「Cannot add a NOT NULL column with default value」ということでしたので、null: falseを削除したら無事マイグレーションできました。
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
def up
execute "DELETE FROM tasks;"
add_reference :tasks, :user, index: true
end
end
原因について詳しく特定できていませんが、某ガイドの指定しているデータベースとは別のデータベースを用いているのが理由なのかなと考えています。試していないので断言はできませんが。。。
なお、下記を行うことでNOT NULL制約を与えることができました。
class ChangeUserIdToTasks < ActiveRecord::Migration[5.2]
def change
change_column :tasks, :user_id, :integer, null: false
end
end