145
167

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2018-11-13

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開発するときにどんどん活用してみてください。


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

145
167
2

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
145
167

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?