Railsのデバッグに役立ちそうなコマンドやメソッド
おはようございます。
スペースマーケットでWebエンジニアをしているs0arです。
花粉にやられています。
くしゃみでかなりカロリーを消費しているのでダイエットと呼んで差し支えないと思います。
実際鼻水とか涙で水抜きになってるのでこれ完全に減量です。
本題です。
Rails歴がそれなりになってきたので、Railsのデバッグをするときに知っていると少し役に立つかもしれないことをいくつか紹介しようと思います。
コマンド
Railsのコマンド一覧はここにあります。
以下、自分がデバッグによく使うかな…というものを抜粋します。
rails console
rails c
読んで字の如く、Railsのコンソールを開きます。
Railsアプリケーションで実装されているメソッドを実行したりできます。
主にデータ周りの確認に使うことが多いですね。
Rails console内でヘルパーメソッドを使いたい
使いたいヘルパーをinclude
すれば使えるようになります。
やらないと undefined method
と言われます。
意外と忘れやすいので一応(自分だけかも)
Rails consoleにコードの変更を反映したい
reload!
しましょう。
(何回やっても「あっ…」ってなります)
rails routes
設定されているroutesが一覧表示できます。
URLとアクションの関係を洗い出すときに使えます。
rails db
あんまり使わないかもしれませんが、知っていると少し便利かもしれません。
rails db:migrate
とかはよく使う気がしますが、実はrails db
でRailsアプリケーションが使用するDBのコマンドラインツールが起動します。
DBを確認するツール(Sequel Aceとか)を別途使っていればそちらから確認するのが良いかもしれませんが、コンソール上で手っ取り早く確認ができるので自分はちょいちょい使います。
でもActiveRecordに自信ニキネキのみなさんならRails Console上でコード書いたほうが早いかもしれません。お好みですね。
ちなみに、find_by_sql
とかselect_all
とかを使えばRails Consoleからでも生SQLを実行できます。これもお好みで。
デバッグに使うコード
pp
オブジェクトを人間が読みやすい形で文字列にして出力してくれます。
(inspectとputsをあわせたやつです)
例えば以下のような感じになります。
class Hoge
def initialize
@name = 'hoge'
@age = 20
end
end
hoge = Hoge.new
pp hoge
#<Hoge:0x0000562f5f2048f8 @age=20, @name="hoge">
Railsだと諸々のインスタンスや、Controllerでパラメータの中身を確認するときに便利です。
ブレークポイントを設定する
確認したいところで止めたいこと、よくあると思います。
デバッグツール
binding.pry
, byebug
, ruby/debug
等のツールを使用する方法です。
以下のようなコードを書くことで、その行で止まります。
-
binding.pry(pry-rails)
- Railsで使用する対話型シェルをirbからpryに変えるgemです
class Hoge def initialize @name = 'hoge' @age = 20 end def update(name, age) @name = name binding.pry # ここでとまる @age = age end end
- Railsで使用する対話型シェルをirbからpryに変えるgemです
-
byebug
- Railsに同梱されているデバッグ用のgemです
class Hoge def initialize @name = 'hoge' @age = 20 end def update(name, age) @name = name byebug # ここでとまる @age = age end end
- Railsに同梱されているデバッグ用のgemです
-
ruby/debug
- Rails7からはこちらが標準になるようです
class Hoge def initialize @name = 'hoge' @age = 20 end def update(name, age) @name = name binding.break # ここでとまる @age = age end end
- Rails7からはこちらが標準になるようです
raise
gemに依存せずに処理を止める方法としては、例外発生させる方法があります。
(ガチで止まるのでデバッグツールと比較すると利便性は低くなります)
怪しいところとか確認したいところでとりあえず例外を発生させるのは割とやると思います。
確認のためにraiseするだけなら、例外の型は指定せずにメッセージだけ指定する方法を使います。
メッセージのみを指定するとRuntimeErrorが発生します。
raise 'error'
# Main.rb:1:in `<main>': error (RuntimeError)
例外の型を指定してやると、その型の例外が発生します。
こちらはデバッグ時より実際の処理で書くことが多いコードですね。
raise ArgumentError, 'args error'
# Main.rb:1:in `<main>': args error (ArgumentError)
methods
対象のオブジェクトが実装しているメソッド一覧を返します。
「そもそも何が実装されてるんだっけ…?」とか「こういうメソッドって実装されてたっけ…?」とかを調べるときに使えます。
メソッド名のシンボルの配列を返すので、selectメソッドなどをチェーンして検索できます。
to_sql
ActiveRecordが発行するSQL文を返すメソッドです。
[1] pry(main)> User.order(updated_at: :desc).limit(10).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL ORDER BY `users`.`updated_at` DESC LIMIT 10"
「コードを書いたはいいけど、本当にこれでいいんだろうか…?」と不安になったらこれで実際のSQL文を確認したり、EXPLAINして実行計画を確認してみたりすると安心ですね。
余談ですが、やろうと思えばActiveRecord::Base.connection.execute
メソッド使ってRails上で実行計画の出力までできそうですね(やらんでいい)。
まとめ
いざ挙げてみるとそんなになかった & 真新しいものはなかったですね。
逆に言うとこれぐらい知っていればデバッグはできますね(たぶん)
なにか思い出したらまた追記しようと思います。
おわりに
弊社では一緒にサービスを盛り上げていく仲間を募集中です。
少しでも「気になる!」と思ったあなた、カジュアルにお話しませんか?
スペースを簡単に貸し借りできるサービス「スペースマーケット」のエンジニアによる公式ブログです。 弊社採用技術スタックはこちら -> whatweuse.dev/company/spacemarket
Discussion