13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

マイグレショーンファイルを作成する際のnull: false

Last updated at Posted at 2019-04-10

今回はnull: falseオプションについてです。
このオプションはマイグレーションファイルにてカラムを追加する際によく使います。

役割としては、カラムに何もデータを入れなければエラーが出ますよ、というものです。

#今回出現したエラー

terminal

rake 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

今回、userテーブルとtaskテーブルを関連づけるために以下のマイグレーションファイルを作成しました。

関係としては、has_many :tasks、belongs_to :userという1対多の関係性です。

xxxxxxxxxxxxxx_add_user_id_to_tasks.rb
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
  def up
    add_reference :tasks, :user, null :false, index: true
  end

  def down
    remove_reference :tasks, :user, index: true
  end
end

として、Taskテーブルにuser_idという外部キーを設置しようとしました。
しかし、何度、マイグレーションファイルを実行してもエラーが出てしまう。

実は以前、同じエラーが出た時にカラムを追加するテーブルにnullなレコードがあったのが原因だったことがありまして、いったん"rails c"で"Task.delete_all"と念の為"User.delete_all"をしてみましたが、一向に改善する気配はありません。

#解決方法
解決方法としては、結論からいうと、null制約のオプションはカラム追加と別に行う、というものでした。

と言いますのも、エラー内容からもしかして、null: falseがなければ実行できるのでは、と思いやってみると、やはりできました。

これは、もしかするとMySQLの特性なのかもしれません(おそらくですが)。

そして、さらにマイグレーションファイルを追加しました。

xxxxxxxxxxxxxx_change_user_id_to_tasks.rb

class ChangeUserIdToTasks < ActiveRecord::Migration[5.2]
  def change
    change_column :tasks, :user_id, :integer, null: false
  end
end

これで、無事にuser_idにnull制約をつけることができました。

みなさまの参考になれば幸いです。

13
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?