Query objects for complex ActiveRecord queries

When queries become too complex for scopes—involving multiple joins, subqueries, or raw SQL fragments—I extract them into dedicated query objects. Each query object is a plain Ruby class that encapsulates one specific query pattern and returns an Acti

ActiveRecord callbacks for lifecycle hooks

Callbacks hook into the ActiveRecord lifecycle to execute code before or after operations like create, update, or destroy. I use before_validation to normalize data (like downcasing emails), after_create to trigger welcome emails, and before_destroy t

Strong parameters for mass assignment protection

Strong parameters prevent mass assignment vulnerabilities by explicitly whitelisting which attributes can be set via user input. Without this protection, attackers could modify sensitive fields like admin or account_balance by including them in reques

Database transactions for data consistency

Transactions ensure that multiple database operations either all succeed or all fail together, preventing partial updates that leave data in inconsistent states. Rails provides ActiveRecord::Base.transaction which wraps a block of code in a database t

CORS configuration for cross-origin API requests

When building APIs consumed by frontend applications hosted on different domains, CORS (Cross-Origin Resource Sharing) headers are mandatory. The rack-cors gem simplifies configuration by letting me whitelist specific origins, HTTP methods, and header

Health check endpoint for deployment monitoring

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 databa

Fragment caching for expensive JSON serialization

Serializing complex ActiveRecord objects to JSON can consume significant CPU time, especially when rendering collections with nested associations. Fragment caching stores rendered JSON fragments in Redis keyed by a cache key that includes the record's

Service objects for complex business logic

As business logic grows, controllers become bloated with transaction management, error handling, and cross-model orchestration. Service objects extract this complexity into dedicated classes with a single public method (usually call), keeping controll

Database indexes for query optimization

Proper indexing is the difference between millisecond and multi-second query response times. I add indexes to foreign keys automatically since Rails doesn't do this by default, and I create composite indexes for common query patterns that filter on mu

ActiveRecord scopes for reusable query logic

Scopes encapsulate reusable query logic directly in the model, improving code readability and reducing duplication across controllers and services. I use scopes for common filters like active, published, or recent rather than writing raw where clauses

Background jobs with Sidekiq and reliable queues

Moving slow operations to background jobs keeps API response times fast and improves perceived performance. Sidekiq with Redis provides a robust, production-proven job queue that handles millions of jobs per day. I organize workers into separate queue

N+1 query detection with Bullet gem

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 mi