Rails.application.configure do
config.after_initialize do
Bullet.enable = true
Bullet.alert = false
Bullet.bullet_logger = true
Bullet.console = true
Bullet.rails_logger = true
Bullet.add_footer = true
Bullet.skip_html_injection = false
end
end
Rails.application.configure do
config.after_initialize do
Bullet.enable = true
Bullet.raise = true
Bullet.bullet_logger = true
end
end
N+1 queries are the silent performance killer in Rails apps—they're easy to introduce during rapid development and expensive to diagnose in production. The Bullet gem monitors queries during development and test runs, raising alerts when it detects missing eager_load, includes, or preload calls. I configure it to raise exceptions in test mode so the CI pipeline catches regressions before they reach production. The most valuable insight Bullet provides is distinguishing between true N+1 issues and acceptable single queries, which helps prioritize optimization efforts. Once Bullet is integrated, I can refactor with confidence knowing that I'm not accidentally removing necessary eager loading that prevents hundreds of roundtrips to the database.
Related snips
class CommentsController < ApplicationController
before_action :set_post
def create
@comment = @post.comments.build(comment_params)
System test: asserting Turbo Stream responses
class Post < ApplicationRecord
belongs_to :author, class_name: 'User'
has_many :comments, dependent: :destroy
scope :published, -> { where.not(published_at: nil).where('published_at <= ?', Time.current) }
scope :draft, -> { where(published_at: nil) }
ActiveRecord scopes for reusable query logic
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
class PostsController < ApplicationController
def index
@posts = Post.includes(:author)
.order(created_at: :desc)
.page(params[:page])
.per(10)
Turbo Frames: infinite scroll with lazy-loading frame
require "csv"
class PeopleCsvStream
include Enumerable
HEADERS = %w[id full_name email signed_up_at plan].freeze
Resilient CSV Export as a Streamed Response
<form data-controller="query-sync" data-action="change->query-sync#apply">
<select name="status" class="rounded border p-2">
<option value="">Any</option>
<option value="open">Open</option>
<option value="closed">Closed</option>
</select>
Filter UI that syncs query params via Stimulus (no front-end router)
Share this code
Here's the card — post it anywhere.