🧪

Rails初心者のためのPryマスターガイド〜デバッグの基礎〜(2025.03.14 更新)

2025/03/13に公開

デバッグが苦手な私へ

Railsアプリケーション開発で必須のスキルとなるデバッグ。その中でも特に強力なツールが「Pry」です。
この記事では、デバッグが苦手な私でもわかるよう、医療システムの開発を例に、Pryの使い方について説明します!

1. Pryとは?

Pryは、Rubyのirbをベースにした、さらに多機能なコンソールツールです。
通常のirbと違い、コードのシンタックスハイライトや高度なデバッグ機能を備えています。
特にRailsでの開発では、エラーの原因を特定するためのデバッグに非常に役立ちます。

2. 環境設定:必要なGemをインストールする

まずはPryを使えるようにするための設定を行います。

Gemfileに以下を追加します。

group :development, :test do
  gem 'pry-rails'    # Rails consoleでPryを使えるようにする
  gem 'pry-byebug'   # デバッグ機能を強化する
  gem 'pry-doc'      # メソッドのソースコードを参照可能にする
end

ターミナルでbundle installを実行します。

$ bundle install

これでPryを起動する準備は終わりです。

3. 基本的な使い方:binding.pryを使ったデバッグ

例題:患者登録フォームのデバッグ

薬局管理システムで患者情報が正しく保存されないという問題が発生したとします。

まず、コントローラーにbinding.pryを設置してデバッグしてみます。

class PatientsController < ApplicationController
  def create
    @patient = Patient.new(params[:patient])
    binding.pry  # ここでプログラムが一時停止する

    if @patient.save
      redirect_to @patient, notice: '患者情報が登録されました'
    else
      render :new
    end
  end

  private

  def patient_params
    params.require(:patient).permit(:name, :age, :medical_history, :insurance_number)
  end
end

患者情報の登録処理が行われる際にbinding.pryの位置で処理を一時停止し、その時点での変数の値や環境を調査できるようにします。

実際の操作手順

  1. 患者登録フォームに情報を入力して送信する
  2. サーバーログのあるターミナルがPryモードになる
From: /app/controllers/patients_controller PatientsController#create:

    3: def create
 => 4:   @patient = Patient.new(patient_params)
    5:   binding.pry

    6:   if @patient.save
    7:     redirect_to @patient, notice: '患者情報が登録されました'

[1] pry(#<PatientsController>)>
  1. ここでparamsと入力すると、フォームから送信されたパラメータを確認できる
[1] pry(#<PatientsController>)> params
=> {"name"=>"", "age"=>"45", "medical_history"=>"高血圧", "insurance_number"=>"12345678"}

ここで、nameが空の値になっていることがわかります。
これにより、フォームから名前が正しく送信されていないことが判明します。

  1. Pryモードを終了するにはexitと入力します

4. ビューでのデバッグ

ビューファイル内でもbinding.pryが使えます。

患者詳細ページでのデバッグ例

<h1>患者詳細</h1>

<% binding.pry %>

<div class="patient-info">
  <p><strong>名前:</strong> <%= @patient.name %></p>
  <p><strong>年齢:</strong> <%= @patient.age %></p>
  <p><strong>病歴:</strong> <%= @patient.medical_history %></p>
  <p><strong>保険番号:</strong> <%= @patient.insurance_number %></p>
</div>

ビューがレンダリングされる際にPryモードが起動し、@patientの内容を確認できます。

[1] pry(#<#<Class:0x000000010b7fa1f0>>)> @patient
=> #<Patient id: 1, name: "田中 一郎", age: 65, medical_history: "高血圧、糖尿病", insurance_number: "1234567890", created_at: "2025-3-12 15:54:41.708225000 +0000", updated_at: "2025-3-12 15:54:41.708225000 +0000">

5. Pryの便利コマンド

Pryモードでは以下のような便利なコマンドが使えます:

コマンド 説明
show-routes ルーティング一覧を表示する
show-models モデル一覧を表示する
show-source メソッドの定義を表示する
show-doc ドキュメントを表示する

5.1 ルーティングの確認をする

[1] pry(main)> show-routes
     Prefix Verb   URI Pattern                   Controller#Action
   patients GET    /patients(.:format)           patients#index
            POST   /patients(.:format)           patients#create
new_patient GET    /patients/new(.:format)       patients#new
...

特定のモデルのルーティングだけ表示したい場合

[1] pry(main)> show-routes --grep patient

5.2 モデルの確認をする

[1] pry(main)> show-models Patient
  --------
  id: integer
  name: string
  age: integer
  medical_history: text
  insurance_number: string
  created_at: datetime
  updated_at: datetime
  
  Associations:
    has_many :prescriptions
    has_many :medications, through: :prescriptions
    belongs_to :doctor

特定のモデルだけ表示する場合

[1] pry(main)> show-model Patient

5.3 メソッドの定義を確認する

[1] pry(main)> show-source Patient.find_by_insurance_number

6. pry-byebugを活用する

pry-byebugを使うと、さらに高度なデバッグが可能になります。

コマンド 機能
break ブレイクポイントを設定する
next 次の行を実行する
step メソッド内部に入って実行す?
finish 現在のメソッドを終了するまで実行する
continue プログラムの実行を再開する(次のPryまでを実行する)

例題:処方箋生成メソッドのデバッグ

以下のようなメソッドをデバッグする場合

def generate_prescription
  binding.pry
  patient = Patient.find(params[:patient_id])
  medications = Medication.where(id: params[:medication_ids])
  
  prescription = Prescription.new(
    patient: patient,
    doctor: current_doctor,
    issue_date: Time.zone.today
  )
  
  if prescription.save
    medications.each do |medication|
      PrescriptionItem.create(
        prescription: prescription,
        medication: medication,
        dosage: params[:dosages][medication.id.to_s],
        instructions: params[:instructions][medication.id.to_s]
      )
    end
    return prescription
  else
    return nil
  end
end

Pryモードになったら、以下のように段階的にデバッグできます

[1] pry(#<PrescriptionsController>)> next
# params[:patient_id]の行を実行する

[2] pry(#<PrescriptionsController>)> patient
=> #<Patient id: 1, name: "田中 一郎", ...>

[3] pry(#<PrescriptionsController>)> next
# params[:medication_ids]の行を実行する

[4] pry(#<PrescriptionsController>)> medications
=> [#<Medication id: 1, name: "アムロジピン", ...>, ...]

[5] pry(#<PrescriptionsController>)> step
# prescription = Prescription.new の行に入る

7. 実践的なデバッグ例:薬の相互作用チェック機能

class PrescriptionValidator
  def check_interactions(prescription)
    binding.pry
    medications = prescription.medications
    
    interactions = []
    
    medications.combination(2).each do |med1, med2|
      interaction = Interaction.find_by(
        medication1_id: med1.id, 
        medication2_id: med2.id
      ) || Interaction.find_by(
        medication1_id: med2.id, 
        medication2_id: med1.id
      )
      
      interactions << interaction if interaction
    end
    
    interactions
  end
end

このようなコードをデバッグする場合、stepnextを組み合わせて実行の流れを追い、各変数の状態を確認できます。

まとめ

  • Pryは強力なデバッグツールで、特にRailsアプリケーション開発には欠かせません
  • binding.pryを設置することで、任意の場所でプログラムを一時停止してデバッグできます
  • pry-byebugを使うことで、ステップ実行や変数の確認など高度なデバッグが可能になります

Pryを使うことでバグの発見や修正が格段に効率化され、開発スピードと品質が向上します!
Pryをマスターして、めざせ!脱初心者🔰

参考

練習用リポジトリ:https://github.com/funxxfun/medilab

今回のコードを実行した環境

  • OS:macOS Sequoia 15.3
  • ハードウェア:MacBook Pro
  • Rails 8.0.2
  • 依存している主要なGemのバージョン:
    • pry-rails (0.3.11)
    • pry-byebug (3.10.1)
    • pry-doc (1.5.0)
  • データベース:SQLite3 2.6.0

Discussion