🫢

Rails初学者がやりがちな5つのミス、まとめてみました

2025/01/04に公開

Rails初学者がやりがちな5つのミス、まとめてみました

それがこちら。

  1. nilオブジェクトへの呼び出し、メソッドのタイポや未定義
  2. DBに存在しないレコードを参照している
  3. パラメータ構造とコントローラ設定がずれている(ストロングパラメータ関連)
  4. テーブルやカラムがまだDBに作られていない(マイグレーションの実行漏れ)
  5. routes.rbに必要なルートが未定義(ルーティング設定の抜け)

これらを、下記の3つの観点から解説します。

  • 事象(ミスっている内容)
  • 遭遇するエラーメッセージ
  • 主な原因と対処法

ではでは、早速解説へ。

1. nilオブジェクトへの呼び出し、メソッドのタイポや未定義

遭遇するエラーメッセージ

NoMethodError: undefined method `full_name' for nil:NilClass
NoMethodError: undefined method `ful_name' for #<User:0x00007f9c8e2c9a20>

主な原因と対処法

  • 原因1: 変数自体がnilで、呼び出し対象のインスタンスが存在しない(このパターン、めっちゃ多い)

    • 対処法:
      • Rails consoleで該当のインスタンスを取得できるか確認してください
      • コントローラやモデル内で@user.present?など、nilチェックを入れて想定どおりの値が入っているか調べてください
  • 原因2: メソッド名のつづりが誤っている('full_name'のつもりが'ful_name' など)

    • 対処法:
      • コントローラやモデルで定義しているメソッド名を再確認してください(エディターで文字列検索してヒットするか確認する、など)
      • Rails consoleでUser.instance_methodsなどを呼び出し、そのメソッドが本当に存在するか確かめてください
  • 原因3: モデルにメソッドを定義していない、またはprivateメソッドで呼び出せない

    • 対処法:
      • モデルのファイルを見て、メソッドが定義されているか確認してください
      • 意図せずprivate配下に記述していたとしたら、publicメソッドとして定義してください
      • 例:
        class User < ApplicationRecord
          def full_name
            "#{first_name} #{last_name}"
          end
        
          private
          # プライベートメソッドに記述されている場合は上部に移動
        end
        

2. DBに存在しないレコードを参照している

遭遇するエラーメッセージ

ActiveRecord::RecordNotFound: Couldn't find User with 'id'=999

主な原因と対処法

  • 原因1: 指定したID(params[:id]など)がDBに存在しない

    • 対処法:
      • Rails consoleで下記を実行し、本当にレコードがあるかチェックしてください
        $ rails console
        > User.find(999)
        
  • 原因2: where句などの条件によってヒットしない

    • 対処法:
      • Userモデルのスコープを使用していた場合、その条件が意図通りか確認してください
      • 例:
      class User < ApplicationRecord
        scope :active, -> { where(active: true) }
      end
      
      User.active.find(999)といったコードを書いていたら、上記のエラーになる可能性がある。
      

3. パラメータ構造とコントローラ設定がずれている(ストロングパラメータ関連)

遭遇するエラーメッセージ

Unpermitted parameters: :name

もしくはログにのみ警告が出て、保存されないケース

Started POST "/users" for 127.0.0.1
Unpermitted parameters: :name

主な原因と対処法

  • 原因1: form_withやform_forから送信されるパラメータとストロングパラメータの記述が噛み合っていない

    • 対処法:
      • コントローラ側のpermitに必要なキーを追加してください
        private
        
        def user_params
          params.require(:user).permit(:name, :email)
        end
        
  • 原因2: ネストされたフォームを使用していて、キー階層が合っていない

    • 対処法:
      • ビューのHTMLソースをチェックし、'user[name]'がどう送られるかを確認してください
      • コントローラでp paramsして、実際どのキーが送られているかを確かめてください

4. テーブルやカラムがまだDBに作られていない(マイグレーションの実行漏れ)

遭遇するエラーメッセージ

ActiveRecord::StatementInvalid: Mysql2::Error: Table 'my_app_development.users' doesn't exist
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.email' in 'field list'

主な原因と対処法

  • 原因1: モデルやマイグレーションを作成後、rails db:migrateを実行し忘れている

    • 対処法:
      • 必ず以下を実行してください
        $ rails db:migrate
        
  • 原因2: マイグレーションが途中で失敗してテーブルやカラムが作られていない

    • 対処法:
      • ターミナルでエラーログを確認し、原因を修正したら再度rails db:migrateを試してください
      • rails db:migrate:statusを使うと、未実行のマイグレーションファイルが残っていないか確認できます

5. routes.rbに必要なルートが未定義(ルーティング設定の抜け)

遭遇するエラーメッセージ

ActionController::RoutingError (No route matches [GET] "/articles")

主な原因と対処法

  • 原因1: config/routes.rbに必要なルートを宣言していない

    • 対処法:
      • rails routesを実行し、目的のパスが定義されているか確かめてください
      • 必要ならroutes.rbにresources :articlesなどを追加してください
  • 原因2: 同じパスを複数定義してしまい、意図しないルートにマッチしている

    • 対処法:
      • routes.rbを見直し、重複ルートを削除してください
      • 似たようなパスがある場合、別のパス名やスコープを使うなど明確に区別してください
  • 原因3: resources :xxxなどの自動生成ルートを誤解している

    • 対処法:
      • rails routesで生成されたパスを確認し、正しいURL・HTTPメソッドを把握してください
      • 不要なルートが含まれている場合はonly:except:オプションを使って制限しましょう

まとめ

「初学者がやりがち」と書きましたが、この5つの事象はエンジニアだったらいつでも出くわすエラーだと思います。
初代のズバットみたいな感じで、序盤のオツキミ山に出てくるポケモンと思いきや、チャンピオンロードにも出現してきて不意を突かれます。

「このパターンはこれが原因かもなー」という知識を頭の片隅に置いておくと、Rails学習時のトラブルシュートがぐっとスムーズになるはずです。ぜひ参考にしてみてください。

Discussion