#ビューでタスク一覧を開こうとしたところ以下のエラーが発生した。
ActionView::Template::Error (SQLite3::SQLException: no such column: tasks.user_id: SELECT "tasks".* FROM "tasks" WHERE "tasks"."user_id" = ? ORDER BY "tasks"."created_at" DESC):
11: th= Task.human_attribute_name(:created_at)
12: th
13: tbody
14: - @tasks.each do |task|
15: tr
16: td= link_to task.name, task
17: td= task.created_at
app/views/tasks/index.html.slim:14:in `_app_views_tasks_index_html_slim___960545833629484385_70134346560000'
tasks.user_idのカラム(列)が見つからないと出ているので、マイグレーションファイルか、コントローラーか、モデルファイルに間違いがあり、うまくデータを紐付けできていないと考えた。
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
class User < ApplicationRecord
has_secure_password
validates :name, presence: true
validates :email, presence: true, uniqueness: true
has_many :tasks
end
class Task < ApplicationRecord
validates :name, presence: true
validates :name, length: { maximum: 30 }
validate :validate_name_not_including_comma
belongs_to :user
scope :recent, -> { order(created_at: :desc) }
private
def validate_name_not_including_comma
errors.add(:name, 'カンマを含めることはできません') if name&.include?(',')
end
end
tasksテーブルにuser_idというカラムを追加するにはジェネレータで作成したマイグレーションファイル(xxxxxxxxxxxxxx_add_user_id_to_tasks.rb)に「execute 'DELETE FROM tasks' :tasks」で今まで作られたタスクを全て削除し、「add_reference :tasks, :user, null: false, index: true」でtasksテーブルに外部キーであるuser_idカラムを作成し、モデルファイルのuser.rbとtask.rbにそれぞれ、「has_many :tasks」と「belongs_to :user」を記入することでそれぞれのクラス同士の紐付けを定義するということは理解できたが、該当するファイルに間違いはありませんでした。
#原因
結論、マイグレーションファイルを直接変更した後にrails db:migrateをしても変更が反映されない」ということがわかりました。原因としては、マイグレーションファイルを直接変更した場合、マイグレーションの現在のバージョンとファイルが一致しているため再実行されないからということでした。解決方法は、マイグレーションファイルを前のバージョンに戻す(rails db:rollback)→マイグレーションの再実行(rails db:nigrate)、もしくは、この二つの機能を備えた「rails db:migrate:redo」を使うことで再実行可能になりました。その結果、エラーを解決することができました。
#migrate コマンド
・マイグレーションファイルを前のバージョンに戻す
$ rails db:rollback
・マイグレーションの再実行
$ rails db:migrate
・ 「マイグレーションファイルを前のバージョンに戻す」、「マイグレーションの再実行」 を同時に行う場合
$ rails db:migrate:redo