Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[Rails初心者必見]Rails あるあるのエラーを解説

TL;DR

Webアプリケーションを作成して行く段階でエラーが出るのはつきもの!
そのなかで、いかにエラーとしっかり向き合うかが重要かと個人的には思っております!

今回は、あるあるのエラーを何個か抜粋して解説していきます。


2020/04/19 編集点 ↓

Loggerの使い方を追記しました。


エラー文

undefined method 'id' for nil:NilClass

例えば、すごく簡素的な例ですが、

def update
  @tweet = Tweet.find(params[:id])
  if @tweet.update(tweet_params)
    ...
end

みたいなコードがあったとしましょう!

このとき、undefined method 'update' for nil:NilClassとエラーが出たと仮定します!

この意味としては、NilClassnilオブジェクトに対して、updateメソッドは定義されていないよ!ってことです。

つまり、@tweetnilになっているということです!

findメソッドは、見つからなかった場合にnilオブジェクトを返します。

そのため、このような簡素的なコードでは、エラーが起こりにくいかもしれませんが、
UsecasesServicesなどのようにディレクトリを分岐させていった時に直面するので、findメソッドを使った時は、@tweet.present?を書いてハンドリングすることをお勧めします。

undefined local variable or method

これもあるあるで、エラー文で示された行に未定義の変数、もしくはメソッドがあると言うことですね!

よくあるのは、"hello"のようなString型のオブジェクトを返したかったにも関わらず、helloと変数もしくはメソッドにしてしまっていた、、、などがあると思います。

RoutingError (No route matches [GET] "/tweets")

単に、URIにマッチするRoutingが存在していない!ということです。

しかし、これに関しては、たまに起こると思います!

特にdeviseで Userサインアップ、サインインのルーティングが存在している時に、usersコントローラを作成し、usersコントローラのルーティングをdeviseのルーティングの前に記述すると、users/:idのルーティングの時にエラーになるので気をつけましょう。

ActiveRecord::NodatabaseError

データベースが存在しない時に出るエラーです。

$ bundle exec rails db:create # Rails ver5以降
$ bundle exec rake db:create  # Rails ver5以前

したら治ると思います!

SyntaxError

単純に文法のミスです!
タイプミスをしていないかの確認、修正でいいと思います。

ActionView::MissingTemplete

該当するViewが存在していないよ〜ってことですね!

コントローラに対するViewが存在するかを確認してください!
renderなどを用いると発生しやすいと思います。

ArgumentError

そもそも、Argument引数のことですので、
メソッドの引数の数などが正しいことを確認しましょう!

個人的に行なっている対策

  1. loggerを使う!(Rails.logger.debugというメソッドが使えます。) *1(下に追記があります)
  2. binding.pryで止めて、メソッドの返り値を確認する。
  3. tail -f log/development.logを入力し、ログを確認(RSpecの場合はtest.log)
  4. logに出力された、SQLを読む
  5. どの部分のなんのエラーかを正確に見極める。

Loggerの使い方(2020/04/19追記部分)

一般的なTweetsController#createを例に解説させていただきます。

app/controllers/tweets_controller.rb
class TweetsController < ApplicationController
  ...
  def create
    @tweet = tweet.new(tweet_params) # *1
    if @tweet.save
      flash[:success] = "ツイートを作成しました"
      redirect_to tweets_path
    else
      flash.now[:danger] = @tweet.errors.full_messages
      render :new
    end
  end
  ...
end

このときに「*1@tweetの中身が知りたい!」なんてことがあると思います!
そんなときに以下の1行を追加すると、中身がわかると思います!

app/controllers/tweets_controller.rb
...
    @tweet = tweet.new(tweet_params) # *1
    Rails.logger.debug "@tweet : #{@tweet.inspect}" # この1行を追加
    if @tweet.save
...

inspectメソッドは、オブジェクトの中身を標準出力してくれるメソッドです。
これでcreateアクションが走ると、development.logに以下のように出力されると思います。

logs/development.log
@tweet : #<Tweet id: nil, user_id: 1, content: "Qiitaの記事用のツイートです", image_data: "{
\"id\":\"1b73ccb4ded451d874761e038a5dfe73.png\",\"stor...", created_at: nil,updated_
at: nil, tweet_id: nil>

こうすることで、@tweet.contentなどの中身を知ることができます!

このloggerメソッドは、サービス層でも利用可能なので、Rails開発するときにどんどん活用してみてください。


以上です。ありがとうございました!

gonzaemon111
都内の某W大学情報系研究科に通うM1年生。 普段の研究内容は、HCI(Human Computing Interaction)です。 得意: Rails , Go, Docker, Nuxt 勉強中
https://gonzaemon.site/
waffleapp
早稲田生用アプリWAFFLEを運営する学生チームです!
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away