Claude Code for Ruby Developers
Complete Guide 2026

From Rails 8 and Hotwire to RSpec, Sidekiq, Sorbet, and dry-rb — everything Ruby developers need to get the most out of Claude Code, with 40+ copy-paste prompts.

Rails 8 Hotwire RSpec Sidekiq ActiveRecord Sorbet dry-rb Minitest Bundler Ruby 3.3

Rails 8 & ActiveRecord

Claude Code understands Rails conventions inside-out — from routing and controllers to ActiveRecord associations, migrations, and the new Rails 8 defaults including Solid Queue, Solid Cache, and Propshaft.

ActiveRecord Queries

N+1 prevention with includes/preload/eager_load, counter caches, complex joins, custom scopes, raw SQL with sanitize_sql, and Arel for dynamic query building.

Migrations & Schema

Reversible migrations, adding indices safely on large tables (algorithm: :concurrently), bulk changes, change_column_null, polymorphic associations, and STI patterns.

Controllers & Routing

Strong parameters, nested resources, concerns, before_action filters, respond_to blocks, API-mode controllers, and Rails 8 authentication generator.

Rails 8 Features

Solid Queue (no Redis background jobs), Solid Cache (DB-backed fragment caching), Solid Cable (DB-backed ActionCable), Propshaft asset pipeline, and the new authentication scaffold.

ActionCable & Realtime

Channel subscriptions, broadcasting from models and jobs, Turbo Streams over cable, authentication with current_user, and scaling with Redis Pub/Sub or Solid Cable.

Service Objects & Concerns

PORO service objects, ActiveSupport::Concern for shared model/controller behaviour, policy objects, query objects, and form objects wrapping complex multi-model forms.

RSpec & Minitest

Claude Code writes idiomatic test suites — shared examples, FactoryBot factories with traits, request specs, system specs with Capybara, and VCR cassettes for external APIs.

RSpec Best Practices

describe/context/it nesting, let/let! memoisation, subject, custom matchers with RSpec::Matchers.define, shared examples via it_behaves_like, and aggregate failures.

FactoryBot

Factory inheritance, traits, sequences, lazy attributes, after(:create) hooks, create_list, and association strategies (build vs create) to keep test suite fast.

System Specs (Capybara)

Feature specs with Capybara + Cuprite (no Selenium), driven_by :cuprite, screenshot-on-failure, login helpers, JS interactions, and testing Hotwire Turbo streams end-to-end.

Mocking & Stubbing

RSpec doubles, instance_double, class_double, allow/expect on doubles, partial doubles, spy, and when to use Mocha vs RSpec mocks.

Sidekiq & Background Jobs

Claude Code writes idempotent Sidekiq workers, handles retries correctly, and also understands Rails 8's Solid Queue for when Redis isn't available.

Sidekiq Workers

Idempotent perform methods, sidekiq_options retry: 5, custom retry logic with sidekiq_retries_exhausted, unique jobs, scheduled jobs with sidekiq-cron, and Sidekiq Pro batches.

Solid Queue (Rails 8)

DB-backed queue with no Redis dependency, recurring jobs via config/recurring.yml, concurrency controls, pausing queues, and monitoring via Mission Control Jobs UI.

Active Job Adapters

Switching between Sidekiq and Solid Queue via Active Job, perform_later/perform_now, wait/wait_until, queue priority, and bulk enqueue.

Testing Jobs

RSpec with sidekiq/testing inline or fake mode, ActiveJob::TestCase, perform_enqueued_jobs, assert_enqueued_with, and testing retry exhaustion.

Hotwire: Turbo & Stimulus

Claude Code is fluent in all three Hotwire layers: Turbo Drive for navigation, Turbo Frames for partial replacement, Turbo Streams for server-push DOM updates, and Stimulus for sprinkled JavaScript.

Turbo Frames

Lazy-loaded frames with src attribute, inline editing patterns, replacing only the results section of a search, and avoiding the common Devise redirect pitfall with turbo_frame_tag.

Turbo Streams

Broadcasting from controllers with respond_to do |f| f.turbo_stream, from jobs via Turbo::StreamsChannel.broadcast_replace_to, and template helpers like turbo_stream.replace.

Stimulus Controllers

Lifecycle callbacks (connect/disconnect/initialize), targets, values with type coercion, CSS classes, outlets for cross-controller communication, and lazy controller registration.

Morphing (Rails 8)

Rails 8's native broadcasts_refreshes with Turbo 8 morphing — whole-page refresh that preserves scroll position, retains input focus, and only patches changed DOM nodes.

Sorbet & RBS Type Annotations

Claude Code adds Sorbet signatures incrementally, generates RBI stubs for gems, and integrates type checking into your CI pipeline.

Sorbet Sigs

sig { params(x: Integer).returns(String) }, T.nilable, T::Array[Model], T.proc.params(arg0: String).returns(T::Boolean), and typed struct values.

Typing Levels

Gradual adoption with # typed: false → ignore → true → strict → strong, using T.untyped and T.unsafe as escape hatches while migrating a large codebase incrementally.

sorbet-rails

Generating RBI files for ActiveRecord models (rails generate sorbet:rails), annotating associations, scopes, and attribute accessors, and running srb tc in CI.

RBS (Ruby 3+)

Writing .rbs signature files, using steep type checker, generating stubs with rbs prototype, and integrating with VSCode via the ruby-lsp extension.

dry-rb Ecosystem

Claude Code composes dry-rb pipelines for complex business logic: validation schemas, monadic result types, immutable structs, and dependency injection.

dry-validation

Contract schemas with type coercions (params vs json vs hash schemas), custom predicates, cross-field rules, array schemas, and message customisation.

dry-monads

Result (Success/Failure), Maybe (Some/None), Try for exception wrapping, Do notation for flat monadic pipelines, and pattern matching on outcomes.

dry-struct & dry-types

Immutable value objects with strict coercion, optional/default attributes, sum types with Types::Strict::String.enum, and nested structs for rich domain models.

dry-transaction

Multi-step business logic pipelines with step, map, tee, and check operations, short-circuiting on Failure, composing transactions, and Around middleware.

Performance & Profiling

Query Optimisation

Bullet gem for N+1 detection, EXPLAIN ANALYZE in console, adding partial indices, covering indices for counter caches, and PostgreSQL-specific optimisations via pg gem.

Memory Profiling

memory_profiler, allocation_tracer, identifying string object churn, frozen_string_literal: true across the codebase, and Symbol vs String key decisions.

Ruby 3 Ractors & Fibers

Ractor-safe data sharing, immutable Ractor communication, the Async gem for non-blocking I/O, Fiber.scheduler integration, and when concurrency beats parallelism in MRI.

Production Profiling

rack-mini-profiler for page-level flamegraphs, StackProf for CPU sampling, rbspy for profiling without instrumentation overhead, and Skylight/Scout APM integration.

40+ Copy-Paste Claude Code Prompts for Ruby

Use these verbatim in Claude Code — each is written to produce production-ready Ruby/Rails code.

Rails 8 & ActiveRecord

N+1 fix
Find all N+1 queries in this controller and its views using includes/preload/eager_load. Show the EXPLAIN ANALYZE output before and after, add a Bullet initializer to catch regressions, and write an RSpec spec that asserts the query count stays under 3.
Rails 8 auth scaffold
Use the Rails 8 authentication generator to add email/password auth. Extend it with: email confirmation via token (15-minute expiry), password reset flow, remember-me cookie (30 days), and rate-limiting login attempts with rack-attack (5 attempts per 20 seconds per IP).
Complex migration
Write a reversible migration that adds a NOT NULL column to a 10M-row table safely: add nullable, backfill in batches of 1000 with sleep(0.05) between batches, then add NOT NULL constraint using PostgreSQL's NOT VALID + VALIDATE CONSTRAINT approach to avoid locking the table.
Multi-model form
Create a form object (PORO, include ActiveModel::Model) for a checkout form that creates an Order, OrderItems, and Address in a single transaction. Add validations on each, wrap in ApplicationRecord.transaction with a rollback on any failure, and write RSpec model + controller specs.
GraphQL API
Add a GraphQL endpoint using graphql-ruby with: query for paginated products (Relay cursor pagination), mutation for creating an order with line items, N+1 prevention using dataloader, authentication via context[:current_user], and rate limiting per user. Write RSpec specs using graphql-ruby's spec helpers.

Testing

Full RSpec coverage
Write complete RSpec coverage for this service class: model specs for validations and associations, service spec with mocked external dependencies, request spec for the API endpoint, and a system spec with Capybara that tests the UI flow end-to-end. Use FactoryBot with traits for test data.
VCR cassettes
Add VCR cassettes for all specs that hit the Stripe API. Configure record: :none in CI (raise on missing cassette), record: :new_episodes locally, filter the Stripe secret key from cassettes, and add a Rake task to refresh all cassettes against the Stripe test environment.
Shared examples
Extract shared RSpec examples for "acts as soft-deletable" (has deleted_at, .only_deleted scope, .with_deleted scope, #restore! method) and "acts as auditable" (creates AuditLog on create/update/destroy). Apply them to User and Order models.
Performance test
Add an RSpec performance spec using rspec-benchmark that asserts the OrdersController#index action stays under 50ms for 1000 records, uses perform_under matcher, seeds data with FactoryBot.create_list, and runs only when PERF_SPECS=1 env var is set.

Sidekiq & Jobs

Idempotent worker
Create an idempotent Sidekiq worker that processes webhook events: check for duplicate event IDs using Redis SET NX with 24h TTL, parse the payload, update the database, emit a domain event, retry up to 5 times with exponential backoff, and log to structured JSON. Write RSpec using sidekiq/testing fake mode.
Batch processing
Implement a batch CSV import using Sidekiq Pro batches: a parent BatchImportJob that reads S3 and enqueues child ItemImportJob for each row, tracks progress via Sidekiq batch callbacks, upserts using activerecord-import in chunks of 500, and sends a completion email when all children succeed.
Solid Queue migration
Migrate our Active Job queues from Sidekiq to Solid Queue (Rails 8): add the gem, run the migration generator, configure recurring jobs in config/recurring.yml, set up Mission Control Jobs for monitoring, and update the Procfile to use the solid_queue supervisor process instead of Sidekiq.

Hotwire

Live search
Build a live product search with Hotwire: Stimulus controller that debounces input by 300ms, issues a Turbo Frame GET request to /products?q=, replaces only the results turbo-frame, shows a loading spinner during fetch via CSS class toggling, announces result count to screen readers with aria-live, and writes a Capybara system spec.
Inline editing
Implement inline record editing using Turbo Frames: clicking a field replaces a frame with an frame (form), submitting sends a PATCH and responds with turbo_stream.replace back to show mode on success or turbo_stream.replace with errors on failure. Add optimistic UI via a pending CSS class during save.
Real-time updates
Add real-time order status updates using Turbo Streams over ActionCable: subscribe from the order show page using turbo_stream_from, broadcast from an OrderStatusJob using Turbo::StreamsChannel.broadcast_replace_to, authenticate the cable connection using signed stream name, and write a system spec with Capybara that asserts the status badge updates without a page refresh.
Rails 8 morphing
Enable Turbo 8 morphing for our dashboard: add broadcasts_refreshes to the Dashboard model, configure Turbo.session.drive = false for forms that shouldn't trigger morphing, add data-turbo-permanent to the sidebar to preserve state across refreshes, and test that the scroll position is maintained after a live update.

Types & Architecture

Sorbet migration
Migrate this service class to Sorbet strict typing: add sig blocks to all public methods, use T.nilable for optional returns, type the params hash with T::Hash[Symbol, T.untyped], run srb tc and fix all type errors, update CI to fail on Sorbet errors, and generate RBI stubs for any untyped gems.
dry-transaction pipeline
Refactor this fat controller action into a dry-transaction pipeline: step :validate (dry-validation schema), step :authorize (pundit policy check returning Failure on deny), step :persist (ActiveRecord wrapped in Result), step :notify (Sidekiq enqueue), step :track (analytics event). Handle each Failure type distinctly in the controller and write RSpec specs for each step in isolation.
Value objects
Create dry-struct value objects for Money (amount_cents: Integer, currency: String), Email (value: String with format validation), and PhoneNumber. Add custom coercions, equality by value, and serialize/deserialize for ActiveRecord using composed_of or custom attribute types. Write RSpec specs for edge cases.

Performance

Query optimisation
Profile this Rails controller action: add rack-mini-profiler with Flamegraph, identify the slowest SQL queries using EXPLAIN (ANALYZE, BUFFERS), add missing indices, convert any N+1 to includes, cache the result with Rails.cache.fetch keyed by a cache_key_with_version, and add an RSpec spec that asserts query count stays under 5.
Memory audit
Run a memory profiler on this CSV export action using the memory_profiler gem: identify the top 10 object allocations by class, add frozen_string_literal: true to the file, switch from Array to lazy Enumerator for streaming, use find_each instead of all for the ActiveRecord query, and measure before/after RSS with ab or wrk.
Caching strategy
Design a caching strategy for the /products page: HTTP cache headers (stale-while-revalidate), Russian-doll fragment caching in the view using cache/touch, counter caches for product counts, low-level Rails.cache.fetch for expensive computations, and cache invalidation on model callbacks. Use Solid Cache for the cache store (Rails 8 default).

Frequently Asked Questions

Yes — Claude Code has deep knowledge of Rails conventions including ActiveRecord associations (has_many :through, polymorphic, STI), validations, callbacks, scopes, and migrations. It writes correct query optimisations (includes/preload to avoid N+1, counter caches, index hints), uses Rails 8 features like Solid Queue and Solid Cache, generates proper strong parameters in controllers, and follows RESTful routing conventions. It understands the asset pipeline, importmap-rails, Propshaft, and both the classic autoloader and Zeitwerk. Prompt: "Add a paginated JSON API endpoint for orders with eager-loaded items and user, filter by status and date range, wrap in a service object, add rate limiting via rack-attack, and write RSpec request specs covering the happy path and 3 edge cases."
Claude Code writes idiomatic RSpec with describe/context/it blocks, shared examples, let/let! memoisation, subject declarations, and custom matchers via RSpec::Matchers. It uses FactoryBot for fixtures (traits, sequences, after-create hooks), VCR/WebMock for HTTP, and DatabaseCleaner or Rails transactional fixtures for isolation. For Minitest it writes test classes inheriting ActiveSupport::TestCase, uses fixtures or FactoryBot, and leverages minitest-spec for the expect DSL. It always tests behaviour not implementation, avoiding over-mocking. Prompt: "Write RSpec model + service specs for a User with email uniqueness validation, a RegistrationService that sends a welcome email and creates a Stripe customer — mock Stripe and ActionMailer, cover validation errors and success path."
Yes. Claude Code understands Sidekiq worker patterns including retry handling (sidekiq_options retry: 5), dead-job sets, unique jobs via sidekiq-unique-jobs, scheduled jobs via sidekiq-cron, and Sidekiq Pro batches. It also understands Rails 8's new Solid Queue (DB-backed, no Redis dependency) and Active Job's queue adapters. It writes idempotent workers that handle re-queuing safely, avoids passing complex ActiveRecord objects (pass IDs instead), and adds instrumentation via Sidekiq middleware. Prompt: "Create an idempotent Sidekiq worker that imports a CSV of products from S3, upserts records in batches of 500 using activerecord-import, sends progress updates via ActionCable, retries on transient errors, and writes an RSpec test using sidekiq/testing inline mode."
Claude Code understands Hotwire's three pillars: Turbo Drive (SPA-like navigation), Turbo Frames (partial page replacement), and Turbo Streams (server-sent DOM updates). It writes Stimulus controllers with connect/disconnect lifecycle hooks, targets, values, and CSS classes, and follows the naming convention that pairs controllers with HTML data attributes. It knows when to reach for Turbo Streams in controllers (respond_to html/turbo_stream), in Action Cable channels (stream_from), and after form submissions. It avoids the common mistake of mixing Turbo Drive navigation with full-page Devise redirects. Prompt: "Add a live-search Stimulus controller that debounces input, issues a Turbo Frame fetch to /products?q=..., updates only the results frame, shows a loading spinner during fetch, and announces result count to screen readers."
Yes. Claude Code writes Sorbet signatures with T.nilable, T::Array, T::Hash, T.proc, and T.untyped. It adds # typed: strict comments, uses sig blocks correctly, and generates runtime checks via extend T::Sig. It also generates RBS type definitions (sig/), understands the difference between Sorbet's gradual typing levels, and knows when to use T.cast vs T.must vs T.unsafe as escape hatches. For Rails, it uses sorbet-rails to generate RBI files for models. Prompt: "Add Sorbet strict typing to this service class — annotate all public methods, use T.nilable for optional params, return typed structs, and update the matching RSpec spec to pass type checks."
Yes. Claude Code is fluent in the dry-rb ecosystem: dry-validation (schemas, rules, custom predicates), dry-monads (Result, Maybe, Do notation), dry-struct (immutable value objects with type coercion), dry-container and dry-auto_inject for dependency injection, dry-transaction for composable business logic pipelines, and rom-rb for functional persistence. It composes monadic pipelines using the >> operator and Do notation, handles errors at the boundary with pattern matching on Success/Failure, and integrates dry-validation schemas as input contracts. Prompt: "Refactor this controller action into a dry-transaction pipeline with steps for validation (dry-validation), authorisation, ActiveRecord persistence wrapped in a Result monad, and Sidekiq enqueue — expose a single #call(params) entry point and handle each Failure type in the controller."
Claude Code helps identify and fix common Ruby performance issues: N+1 queries (recommends Bullet gem for detection), expensive allocations (uses memory_profiler and allocation_tracer), slow regex (advises on patterns), String frozen_string_literal: true, Symbol vs String keys in hashes, and GC pressure from excessive object creation. It also understands Ractors for parallelism (Ruby 3+), Fiber-based concurrency with the Async gem, and how to profile with rack-mini-profiler, StackProf, and rbspy for production profiling. Prompt: "Profile this Rails controller action that takes 800ms — add Bullet for N+1 detection, identify the slowest SQL queries using explain, cache expensive computations with Rails.cache.fetch, and instrument with ActiveSupport::Notifications so I can see flame graphs in Skylight."

Other Language Guides

More Claude Tools

⚡ Using Claude Code? 30 power prompts that 2× your output · £5 £3 first 10Get PDF £3 →