class HealthController < ApplicationController
skip_before_action :verify_authenticity_token
def liveness
render json: { status: 'ok' }, status: :ok
end
def readiness
checks = {
database: check_database,
redis: check_redis,
sidekiq: check_sidekiq
}
all_healthy = checks.values.all? { |status| status == 'ok' }
status_code = all_healthy ? :ok : :service_unavailable
render json: { status: all_healthy ? 'ok' : 'degraded', checks: checks }, status: status_code
end
private
def check_database
ActiveRecord::Base.connection.execute('SELECT 1')
'ok'
rescue StandardError
'failed'
end
def check_redis
Redis.current.ping == 'PONG' ? 'ok' : 'failed'
rescue StandardError
'failed'
end
def check_sidekiq
Sidekiq.redis(&:ping) == 'PONG' ? 'ok' : 'failed'
rescue StandardError
'failed'
end
end
Rails.application.routes.draw do
get 'health/liveness', to: 'health#liveness'
get 'health/readiness', to: 'health#readiness'
end
Load balancers and orchestration platforms like Kubernetes rely on health check endpoints to determine if an application instance is ready to serve traffic. A robust health check doesn't just return 200 OK—it verifies critical dependencies like database connectivity, Redis availability, and background job processing. I implement separate /health/liveness and /health/readiness endpoints: liveness checks if the app process is running, while readiness checks if all dependencies are available. This distinction allows orchestrators to restart unhealthy instances while giving newly deployed instances time to warm up before receiving traffic. Health checks should complete quickly (under 100ms) to avoid triggering false positives during traffic spikes.
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.