Rails binding.pry実践:コントローラー・モデル・テストでのデバッグ
はじめに
binding.pry の基本的な使い方は「Rails binding.pry入門:セットアップと基本コマンドの使い方」で解説しています。
この記事ではコントローラー・モデル・RSpecでの実践的なデバッグ手順を紹介します。
コントローラーでのデバッグ
リクエストパラメータの確認
フォームの送信値やURLパラメータが正しく渡ってきているか確認します。
def create binding.pry @user = User.new(user_params) if @user.save redirect_to @user else render :new end end
[1] pry(#<UsersController>)> params => <ActionController::Parameters {"name"=>"田中太郎", "email"=>"", "action"=>"create", ...}> [2] pry(#<UsersController>)> params[:user] => <ActionController::Parameters {"name"=>"田中太郎", "email"=>""}>
バリデーションエラーの原因がすぐ分かります。
ストロングパラメータの確認
user_params が意図した値を返しているか確認できます。
[3] pry(#<UsersController>)> user_params => <ActionController::Parameters {"name"=>"田中太郎", "email"=>"tanaka@example.com"} permitted: true>
before_action の確認
class UsersController < ApplicationController before_action :set_user, only: [:show, :edit, :update] def show binding.pry end private def set_user @user = User.find(params[:id]) end end
[1] pry(#<UsersController>)> @user => #<User id: 1, name: "田中太郎">
before_action で設定したインスタンス変数が正しくセットされているか確認できます。
モデルでのデバッグ
バリデーションの挙動確認
バリデーションが通らない原因を調べます。
class User < ApplicationRecord before_validation :normalize_email validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP } private def normalize_email binding.pry self.email = email.downcase.strip if email.present? end end
[1] pry(#<User>)> email => " TANAKA@EXAMPLE.COM " [2] pry(#<User>)> email.downcase.strip => "tanaka@example.com"
変換前後の値をその場で確認できます。
コールバックのデバッグ
class Order < ApplicationRecord after_create :send_confirmation_email private def send_confirmation_email binding.pry UserMailer.confirmation(self).deliver_later end end
[1] pry(#<Order>)> self => #<Order id: 1, user_id: 3, total: 5000> [2] pry(#<Order>)> user => #<User id: 3, name: "山田花子">
スコープやクエリの確認
def index binding.pry @users = User.active.order(:name) end
[1] pry(#<UsersController>)> User.active.to_sql => "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"status\" = 'active' ORDER BY \"users\".\"name\" ASC" [2] pry(#<UsersController>)> User.active.count => 5
to_sql で実際に発行されるSQLを確認できます。
RSpecでのデバッグ
テストが失敗している原因を調べるときにも binding.pry が使えます。
テストコードに挿入する
RSpec.describe UsersController, type: :request do describe 'POST /users' do it 'ユーザーを作成する' do binding.pry # テスト実行中に一時停止 post users_path, params: { user: { name: '田中太郎', email: 'tanaka@example.com' } } expect(response).to have_http_status(:redirect) end end end
bundle exec rspec spec/requests/users_spec.rb
テスト実行中に一時停止して、レスポンスやDBの状態を確認できます。
[1] pry(#<RSpec::ExampleGroups::UsersController>)> response.status => 422 [2] pry(#<RSpec::ExampleGroups::UsersController>)> User.last => nil [3] pry(#<RSpec::ExampleGroups::UsersController>)> response.body => "..."
モデルのテストでの使い方
RSpec.describe User, type: :model do describe 'バリデーション' do it 'emailがないと無効' do user = User.new(name: '田中太郎', email: '') binding.pry expect(user).not_to be_valid end end end
[1] pry(#<RSpec::ExampleGroups::User>)> user.valid? => false [2] pry(#<RSpec::ExampleGroups::User>)> user.errors.full_messages => ["Emailを入力してください"]
バリデーションエラーの内容をそのまま確認できます。
よく使うデバッグパターン
ActiveRecordオブジェクトの属性確認
[1] pry> user.attributes => {"id"=>1, "name"=>"田中太郎", "email"=>"tanaka@example.com", "created_at"=>...}
エラーメッセージの確認
[2] pry> user.errors.full_messages => ["Emailは不正な値です", "Nameを入力してください"]
SQLの確認
[3] pry> User.where(status: :active).to_sql => "SELECT ... WHERE \"users\".\"status\" = 1"
セッションやCookieの確認(コントローラー内で)
[4] pry> session[:user_id] => 3 [5] pry> cookies[:remember_token] => "abc123"
まとめ
| シーン | デバッグのポイント |
|---|---|
| パラメータエラー | params / user_params を直接確認 |
| バリデーション失敗 | before_validation に挿入して変換前後を確認 |
| クエリの問題 | to_sql で発行SQLを確認 |
| テスト失敗 | テストコードに挿入してレスポンス・DBの状態を確認 |
| コールバックのバグ | コールバックメソッドに挿入して self を確認 |
基本コマンドについては「Rails binding.pry入門:セットアップと基本コマンドの使い方」を参照してください。