【Rails】NoMethodError (undefined method `fetch_value’ for nil:NilClass)の原因と対処法

プログラミング

undefined method `fetch_value' for nil:NilClass
undefined method `fetch_value' for nil:NilClass

再現

2.6.3 :004 > User.new
Traceback (most recent call last):
1: from (irb):4
NoMethodError (undefined method `fetch_value' for nil:NilClass)
2.6.3 :005 >

上記のように、モデルクラスのインスタンスを作成しようとすると発生する。

原因

対象のテーブルにRubyの予約語が含まれているため

2.6.3 :003 > User.column_names
=> ["id", "class", "admin", "name", "mail", "password_digest", "age", "area", "single_word", "created_at", "updated_at"]

上記の場合、"class"が予約語。Rubyの予約語一覧はこちらを参照

対策

カラム名を変更してマイグレーションを再実行

まず、マイグレーションファイルを作成する。

$ rails generate migration rename_class_column_to_users
Running via Spring preloader in process 11871
      invoke  active_record
      create    db/migrate/20211211230221_rename_class_column_to_users.rb

編集する。

class RenameClassColumnToUsers < ActiveRecord::Migration[6.0]
  def change
    # rename_column :テーブル名, :変更前カラム名, :変更後カラム名
    rename_column :users, :class, :grade
  end
end

マイグレーションを実行する。

$ rails db:migrate
== 20211211230221 RenameClassColumnToUsers: migrating =========================
-- rename_column(:users, :class, :grade)
   -> 0.0348s
== 20211211230221 RenameClassColumnToUsers: migrated (0.0360s) ================

再実行して確認してみる。

2.6.3 :001 > User.new
   (0.4ms)  SELECT sqlite_version(*)
 => #<User id: nil, grade: nil, admin: nil, name: nil, mail: nil, password_digest: nil, age: nil, area: nil, single_word: nil, created_at: nil, updated_at: nil> 

これで解決!

twitterもやっています。

Rubyをある程度学んだら、こちらの書籍がおすすめです。

自分も読んでます。