【Rails】ActiveRecordのエラー解決法。no such column

railsの勉強でエラーにぶつかりまくって、パンクしそうなのでメモに残そうと思い、この記事を書きました。

同じようなエラーで困っている方の参考になれば嬉しいです。

初学者なので間違っていればご指摘お願いします。
## ActiveRecord::StatementInvalid in Tasks#index
現場Railsのチャプター4が最後まで進んだので、実装できているか改めて確認しようとログインをしたらエラーが発生しました。

![スクリーンショット 2023-05-09 14.21.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676271/4e06bc36-b650-20cd-8528-54379a20c5ce.png)

```
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):
```
no such column:tasks.user_id(user_idのカラムがないよー)とあったので、マイグレーションファイルかモデルファイルにタイプミスがあるか確認をしました。

## モデルファイル
まずはモデルファイルから確認します。
```ruby:user.rb
class User < ApplicationRecord
  has_secure_password

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

  has_many :tasks
end
```
```ruby:tasks.rb
class Task < ApplicationRecord
  validates :name, presence: true, 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
```
2つとも書籍とコードを見比べてみましたが、タイプミスは見つけられませんでした。
## マイグレーションファイル
次にマイグレーションファイルの確認です。
```ruby
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
  def change
    def up
      execute 'DELETE FROM tasks;'
      add_reference :tasks, :user, null: false, index:true # 半角スペースがない
    end                                                    # index: trueに修正

    def down
      remove_reference :tasks, :user, index: true
    end 
  end
end
```
upメソッドの「index:true」のtrueの前に半角スペースがなかったのでここか？と思い、修正後「rails db:migrate」を実行しました。

しかし、エラーは治らず…。その後、色々と調べた結果以下の手順で解決できました。

## 解決法
### STEP1
まず、「rails db:migrate:status」でマイグレーションの状態が調べられるそうなので、コマンドを実行します。

![スクリーンショット 2023-05-09 14.46.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676271/8c0c7394-1c6c-c3c4-8164-fbf62bf494a8.png)

### STEP2
次に、「rails c」でコンソールを立ち上げた後に、「Task.column_names」と打つと反映されているカラム名が確認できます。

![スクリーンショット 2023-05-09 14.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676271/43668a1c-1937-dc03-ebd7-aa7eaa03feca.png)

やはり、user_idカラムが追加されていませんでした。ということはデータベースにuser_idカラムがないということだから、また新しくファイルを作って追加しないといけないのか…。

でも、Add user id to tasksでuser_id追加されるんじゃないの？とモヤモヤし念のためにもう一度マイグレーションファイルを確認。

### STEP3
```ruby
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
  def change
    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
end
```
Railsガイドから、changeメソッドの代わりにupとdownメソッドを使うことができると知りました。

もう一度確認してみると、案の定changeメソッドが残ったままでした。完全に知識不足ですね…。

### STEP4
```ruby
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
```
はい、これが正しいコードでした。修正後はこちらもサイトなどを見て「rails db:rollback」をして前のバージョンに戻してから再度「rails db:migrate」しました。

### STEP5
まずは、rollbackでバージョンを戻します。

![スクリーンショット 2023-05-09 15.09.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676271/f1ac7897-47c6-be64-bb49-b412f2c9e022.png)

user_idカラムと関連がある「Add user id to tasksファイル」がちゃんとdownになっているので前のバージョンに戻せています。

再度「rails db:migrate」を実行をすると、ついにログインができるようになりました！

## エラーの原因
- upとdownメソッドはchangeメソッドの代わりに使っていることを知らずに、change メソッドで囲ってしまっていた。
- 半角スペースがなかったところがあった
- すでにマイグレーションしたファイルを後から修正して、そのままマイグレーションしても、内容は反映されない。一度そのファイルをrollbackでバージョンを戻してからmigrateする必要があった。

## 参考文献
https://railsguides.jp/active_record_migrations.html

https://qiita.com/Tatsu88/items/233e724e03139bddf30a

https://qiita.com/oden-09/items/2a0da0a0363c3ff86a61