no such column エラー


ビューでタスク一覧を開こうとしたところ以下のエラーが発生した。

エラー文
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のカラム(列)が見つからないと出ているので、マイグレーションファイルか、コントローラーか、モデルファイルに間違いがあり、うまくデータを紐付けできていないと考えた。

xxxxxxxxxxxxxx_add_user_id_to_tasks.rb
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
app/models/user.rb
class User < ApplicationRecord
  has_secure_password

  validates :name, presence: true
  validates :email, presence: true, uniqueness: true

  has_many :tasks
end
app/models/tasks.rb
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