0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bulletの使い方 --Rails開発でN+1問題を指摘してくれるgem

Posted at

はじめに

Rails開発において、パフォーマンスの問題で最も頻繁に遭遇するのが「N+1問題」です。開発環境では気づきにくいこの問題は、本番環境で深刻なパフォーマンス低下を引き起こす可能性があります。

本記事では、N+1問題を自動的に検出してくれる強力なgem「Bullet」について、基本的な使い方を解説します。

何ができるの?

Bulletの主要機能

Bulletは、Railsアプリケーションにおいて以下の問題を検出・通知してくれます。

1. N+1クエリの検出

# N+1問題が発生するコード例
users = User.all
users.each do |user|
  puts user.posts.count  # ユーザー数分のクエリが発生
end

2. 使用されていないeager loadingの検出

# postsを読み込んでいるが使用していない
users = User.includes(:posts)
users.each do |user|
  puts user.name  # postsは使用されていない
end

どうやって通知してくれるの?

Bulletは検出した問題を様々な方法で教えてくれます。

  • ブラウザのJavaScriptアラート
    スクリーン ショット 2025-08-29 に 20.31.45 午後.png

  • ブラウザのコンソールログ
    スクリーン ショット 2025-08-29 に 20.30.14 午後.png

  • Railsログ

     user: root
     GET /api/v1/test_n_plus_one/unused_eager_loading
     AVOID eager loading detected
       User => [:running_records, :monthly_goals]
       Remove from your query: .includes([:running_records, :monthly_goals])
     Call stack
    /myapp/app/controllers/api/v1/test_n_plus_one_controller.rb:60:in 'Enumerable#map'
    /myapp/app/controllers/api/v1/test_n_plus_one_controller.rb:60:in 'Api::V1::TestNPlusOneController#unused_eager_loading'
    

他にも以下の形式で通知ができるようです。

  • Slack通知
  • メール通知

詳しくはBullet 公式リポジトリでご確認ください🙇

導入

インストール

Gemfileに以下を追加:

group :development do
  gem 'bullet'
end

その後、bundleコマンドを実行:

bundle install

基本設定

インストールしたら以下のコマンドを実行:

bundle exec rails g bullet:install

config/environments/development.rbに以下の設定が追加されます。

Rails.application.configure do
  config.after_initialize do
    Bullet.enable = true
    Bullet.alert = true         # ブラウザのJavaScriptアラート
    Bullet.bullet_logger = true # Bulletのログファイル(log/bullet.log)
    Bullet.console = true       # ブラウザのコンソールログ
    Bullet.rails_logger = true  # Railsのログ
    Bullet.add_footer = true    # ページ下部に通知を表示
  end
end

使用方法

基本的な使い方

N+1問題の検出と解決

N+1問題を発生するコードが実行されるときに、先に示した方法で警告が表示されます。
警告の中に解決方法が示されているので、その指示に従うと解決できます。

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    # N+1問題が発生するコード
    @posts = Post.all
    
    # Bulletが警告を出す
    # USE eager loading detected
    #   Post => [:user]
    #   Add to your query: .includes([:user])
  end
end
<!-- app/views/posts/index.html.erb -->
<% @posts.each do |post| %>
  <h3><%= post.title %></h3>
  <p>著者: <%= post.user.name %></p>  <!-- ここでN+1が発生 -->
<% end %>

解決方法:

class PostsController < ApplicationController
  def index
    # includesを使用してN+1を解決
    @posts = Post.includes(:user)
  end
end

まとめ

開発初期からの導入をオススメします!

  • プロジェクト開始時からBulletを導入することで、N+1問題の蓄積を防ぐことができます。

注意点

  • すべての警告に対応する必要はないと思います。使ってみるとノイズに感じる場面もありました。そんなときはセーフリストに設定することもできるのでそちらも検討してみてください!

Bulletは、Rails開発において必須とも言えるツールです。適切に設定・運用することで、アプリケーションのパフォーマンスを大幅に改善できます。ぜひ導入して、快適なRails開発を実現してください!

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?