ActiveRecordエラー
ActiveRecord::StatementInvalid
SQLite3::SQLException: no such column: tasks.user_id:
error文に書いてあるとおりtasksテーブルにuser_idカラムがないというエラーである。 データベース上でUserとTaskを紐付ける際に発生した。 まず、ジェネレータでマイグレーションを作成し、
$rails g migration AddUserIdToTasks
マイグレーションファイルを以下のように編集しマイグレーションを実行した。
class AddUserIdToTasks < ActiveRecord::Migration[5.2] def up execute 'DELETE FROM tasks;' add_reference :tasks, :user, null: false, index: true end def down remove_reference :tasks, :user, index: true end end $bin/rails db:migrate
データベースの状態を確認したところ、マイグレーションを実行したにもかかわらず、データベースにuser_idカラムはつくられていないことがわかった。
#データベースへ接続 $rails db =>SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. #データベースの一覧を確認 sqlite>.database #テーブル一覧を取得 sqlite>.tables ar_internal_metadata tasks schema_migrations users #テーブルの中のカラムを確認(今回はtasksテーブル) sqlite> PRAGMA TABLE_INFO(tasks); 0|id|integer|1||1 1|name|varchar|1||0 2|description|text|0|NULL|0 3|created_at|datetime|1||0 4|updated_at|datetime|1||0 sqlite> .exit
結論
ジェネレータの書き方が間違っていた。マイグレーションファイルにchangeメソッドがなかった。書籍では、bin/rails g migration AddUserIdToTasksで実行しているが、 「rails g migration Addカラム名Toテーブル名 カラム名:カラムのデータ型」このように、カラム名とカラムのデータ型を追加したら Tasksテーブルにuser_idカラムを追加することができた。マイグレーションをやり直すために、最初に作成したファイルを削除する必要がある。
#まず、ステータスを確認する。 $rails db:migrate:status Status Migration ID Migration Name -------------------------------------------------- up 20210323195016 Create tasks up 20210329092418 Change tasks name not null up 20210329175420 Create users up 20210329190039 Add admin to users down 20210331174646 Add user id to tasks #upの場合、「$bin/rails db:migrate:down VERSION=migration_file_id」を実行し、downにする。 #downは、まだデータベースへ反映されていないので、削除しても問題ない。削除を実行。 $rm db/migrate/20210331174646_add_user_id_to_tasks.rb #削除できたかステータスを確認。 $rails db:migrate:status Status Migration ID Migration Name -------------------------------------------------- up 20210323195016 Create tasks up 20210329092418 Change tasks name not null up 20210329175420 Create users up 20210329190039 Add admin to users
削除が確認できたらマイグレーションを「rails g migration Addカラム名Toテーブル名 カラム名:カラムのデータ型」で作成。
$bin/rails g migration AddUserIdToTasks user_id:integer Running via Spring preloader in process 65692 invoke active_record create db/migrate/20210401072016_add_user_id_to_tasks.rb
マイグレーションファイルを以下のように編集し、マイグレーションを実行。 マイグレーションファイルでは、changeメソッドの中でテーブルが作成される。
class AddUserIdToTasks < ActiveRecord::Migration[5.2] def change add_column :tasks, :user_id, :integer end def up execute 'DELETE FROM tasks;' add_reference :tasks, :user, null: false, index: true end def down remove_reference :tasks, :user, index: true end end $bin/rails db:migrate == 20210401072016 AddUserIdToTasks: migrating ================================= -- add_column(:tasks, :user_id, :integer) -> 0.0010s == 20210401072016 AddUserIdToTasks: migrated (0.0011s) ======================== #ステータスを確認 $bin/rails db:migrate:status Status Migration ID Migration Name -------------------------------------------------- up 20210323195016 Create tasks up 20210329092418 Change tasks name not null up 20210329175420 Create users up 20210329190039 Add admin to users up 20210401072016 Add user id to tasks
user_idカラムが作成されているかデータベースを確認。
$rails db SQLite version 3.28.0 2019-04-15 14:49:49 Enter ".help" for usage hints. sqlite> .databases sqlite> .tables ar_internal_metadata tasks schema_migrations users sqlite> PRAGMA TABLE_INFO(tasks); 0|id|integer|1||1 1|name|varchar|1||0 2|description|text|0|NULL|0 3|created_at|datetime|1||0 4|updated_at|datetime|1||0 5|user_id|integer|0||0 sqlite> .exit
無事にuser_idカラムが作成され、解決。