📑

Railsのデバッグ方法まとめてみた

に公開

動作環境

  • Rails 7.2.2
  • Ruby 3.4.1

サンプルコード:

https://github.com/okdyy75/dev-rails/tree/debug

# サンプルコード実行時は事前にseedも実行してください
docker compose run --rm api rails db:seed

VS CodeからローカルでRailsを起動してデバッグ

事前設定

  1. VSCode rdbg Ruby Debugger をインストール
    https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg

  2. debug gemもインストールします(ローカルPC)

gem install debug
  1. launch.jsonを作成
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "rdbg",
      "name": "Debug Local Rails",
      "request": "launch",
      "cwd": "${workspaceFolder}/apps/api",
      "script": "bin/rails server -p 3000",
      "useBundler": true
    },
  ]
}

後は左のデバッグアイコンから「Debug Local Rails」を選択して起動。変数の中身をデバッグしたり、ステップ実行が可能です

VSCode_rails_local_debug.gif


サンプルコードを使用した際にDBエラーが発生する場合はDBコンテナを起動してみてください

docker compose up -d db

https://github.com/okdyy75/dev-rails/tree/debug

VS CodeでDockerからRailsを起動してデバッグ

事前設定

  1. launch.jsonに下記を追記します
// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "rdbg",
      "name": "Debug Remote Rails",
      "debugPort": "localhost:12345",
      "localfsMap": "/rails:${workspaceFolder}/apps/api",
      "request": "attach",
    },
  ]
}
  1. debug gemがインストールされていることを確認してください
# apps/api/Gemfile
group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"
end
  1. docker-compose.override.ymlの作成

既存のdocker-compose.ymlのRails起動のコマンドを参考にdocker-compose.override.ymlを作成してください。既存のdocker-compose.ymlを変更せずにcommandを上書きして実行が可能なので、他の開発メンバーの環境を汚さずにデバッグが可能です。

# docker-compose.yml
  api:
    build: ./apps/api
    command: bundle exec rails server -p 3000 -b 0.0.0.0
    volumes:
      - ./apps/api:/rails
    ports:
      - 3000:3000
    environment:
      RAILS_ENV: development
      DATABASE_HOST: db
      DATABASE_USERNAME: postgres
      DATABASE_PASSWORD: postgres
      DATABASE_NAME: dev_rails_development
    depends_on:
      - db
# docker-compose.override.yml
services:
  api:
    command: >
      bash -c "
        rm -f tmp/pids/server.pid &&
        bundle exec rdbg -n --open --host 0.0.0.0 --port 12345 -c -- bundle exec bin/rails s -p 3000 -b '0.0.0.0'
      "
    ports:
      - 12345:12345

docker-compose.override.ymlはgit管理からグローバルで除外するのがお勧めです。

# ~/.config/git/ignore
docker-compose.override.yml

後は左のデバッグアイコンから「Debug Remote Rails」を選択して起動すれば同様にデバッグ実行が可能です

VSCode_rails_docker_debug.gif

Rakeタスクのデバッグ

apiのリクエストはRailsサーバーの起動をbindする事でデバッグ出来ていましたが、Rakeタスクはapiとはまた別のスレッドとして起動されるので別の方法でデバッグする必要があります。今回はbinding.pryを使用したデバッグ方法を紹介します

事前設定

  1. Gemfileにpry-railspry-byebugのgemがインストールされていることを確認してください
group :development, :test do
  # debugging with pry-rails https://github.com/pry/pry-rails
  gem "pry-rails"
  # advanced debugging with pry-byebug https://github.com/deivid-rodriguez/pry-byebug
  gem "pry-byebug"
end

使い方はシンプルで、止めたい箇所にbinding.pryと記述するだけです。試しに適当なRakeタスクを作成して

(DBのTodoリストをmarkdownに出力するRakeタスク)

# apps/api/lib/tasks/todos.rake
namespace :todos do
  desc "Export todos to Markdown"
  task export_markdown: :environment do
    output_file = Rails.root.join("tmp/Todoリスト.md")
    File.open(output_file, "w") do |file|
      file.puts "# Todoリスト"
      Todo.order(:id).each do |todo|
        checkbox = todo.completed? ? "[x]" : "[ ]"
        file.puts "- #{checkbox} #{todo.title}"
      end
    end
    puts "✅ Todoを Markdown にエクスポートしました: #{output_file}"
  end
end

Rakeタスクを実行してみると

docker compose exec api bin/rake todos:export_markdown

このような感じでデバッグ実行できます

binding_pry_debug.gif

簡単にコマンド紹介

  • @: 現在地点を表示
  • next: 次の行まで実行
  • continue: 次の binding.pry まで実行
  • step: ステップ実行(メソッドの呼び出し先に入る)
  • exit!: 強制終了

参考リンク

Discussion