LoginSignup
1
0

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

Posted at

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

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

初学者なので間違っていればご指摘お願いします。

ActiveRecord::StatementInvalid in Tasks#index

現場Railsのチャプター4が最後まで進んだので、実装できているか改めて確認しようとログインをしたらエラーが発生しました。

スクリーンショット 2023-05-09 14.21.53.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のカラムがないよー)とあったので、マイグレーションファイルかモデルファイルにタイプミスがあるか確認をしました。

モデルファイル

まずはモデルファイルから確認します。

user.rb
class User < ApplicationRecord
  has_secure_password

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

  has_many :tasks
end
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つとも書籍とコードを見比べてみましたが、タイプミスは見つけられませんでした。

マイグレーションファイル

次にマイグレーションファイルの確認です。

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

STEP2

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

スクリーンショット 2023-05-09 14.52.17.png

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

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

STEP3

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

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

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

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

エラーの原因

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

参考文献

1
0
0

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
1
0