Railsライブラリ: Bullet

最近Bulletというライブラリを知ったのでメモとして残しておきます。

リポジトリ

https://github.com/flyerhzm/bullet

概要

* N + 1を発見してくれるgem

使用方法

開発環境で設定

参考: https://github.com/flyerhzm/bullet#configuration

config/environments/development.rb

Rails.application.configure do
...
    config.after_initialize do
        Bullet.enable = true
        Bullet.sentry = true
        Bullet.alert = true
        Bullet.bullet_logger = true
        Bullet.console = true
        Bullet.growl = true
        Bullet.xmpp = { :account  => 'bullets_account@jabber.org',
                     :password => 'bullets_password_for_jabber',
                     :receiver => 'your_account@jabber.org',
                     :show_online_status => true }
        Bullet.rails_logger = true
        Bullet.honeybadger = true
        Bullet.bugsnag = true
        Bullet.appsignal = true
        Bullet.airbrake = true
        Bullet.rollbar = true
        Bullet.add_footer = true
        Bullet.skip_html_injection = false
        Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
        Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware', ['my_file.rb', 'my_method'], ['my_file.rb', 16..20] ]
        Bullet.slack = { webhook_url: 'http://some.slack.url', channel: '#default', username: 'notifier' }
    end
...
end

必要なオプションだけ設定すれば大丈夫です。

N+1が発生しているAPIなどを呼んだ場合、以下のようにエラーが発生します。(デバッグモードONになっています)

スクリーンショット_2021-11-08_9_48_03


テスト環境で設定

参考: https://github.com/flyerhzm/bullet#run-in-tests

config/environments/test.rb

Rails.application.configure do
...
    config.after_initialize do
        Bullet.enable = true
        Bullet.bullet_logger = true
        Bullet.raise = true # raise an error if n+1 query occurs
    end
...
end

spec/rails_helper.rb

RSpec.configure do |config|
...

    if Bullet.enable?
        config.before(:each) do
            Bullet.start_request
        end
        
        config.after(:each) do
            Bullet.perform_out_of_channel_notifications if Bullet.notification?
            Bullet.end_request
        end
    end
...
end

rspecを実行して、N+1が発生している場合、以下のようなエラーが発生します。

     Failure/Error:
      get admin_api_v1_test_path(organization),
        headers: authenticated_header(admin_user),
        params: { sortBy: 'user.email' }
    
    Bullet::Notification::UnoptimizedQueryError:
      user: tanaka
      GET /admin/api/v1/test/1/members
      USE eager loading detected
        OrganizationUser => [:user]
        Add to your query: .includes([:user])


まとめ

実際に動いているプロダクトで実行してみましたが、N+1エラーが出ていました。

こういった便利ツールを使って、未然にN+1を防いで行きたいですね。

この記事が気に入ったらサポートをしてみませんか?