Rails binding.pry実践:コントローラー・モデル・テストでのデバッグ

スポンサーリンク

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入門:セットアップと基本コマンドの使い方」を参照してください。