rails
ABOUTME: Rails 8 service-oriented architecture, validation contracts, background jobs, Hotwire
ABOUTME: API development with thin controllers, services, forms, filters, and modern Rails stack
Ruby on Rails - Modern Development
Quick Reference
bundle exec lefthook run all # Quality checks
bundle exec rspec # Tests
rails s / bin/dev # Server (bin/dev for Hotwire)
bin/jobs # Solid Queue workers
See also: _AST_GREP.md (sg patterns), _PATTERNS.md, source-control
Architecture calls:
MyService.new(user:, params:).call # Service
MyForm.new(params, user).save # Form
MyFilter.result(params, scope) # Filter
MyJob.perform_async(id) # Sidekiq
MyJob.perform_later(id) # Solid Queue
Sacred Rules (NON-NEGOTIABLE)
- NO LOGIC IN CONTROLLERS - HTTP layer only
- ALL LOGIC IN SERVICES/FORMS/FILTERS
- NO ACTIVERECORD VALIDATIONS - Dry-validation contracts only
- MINIMUM MODEL LOGIC - Data structures + associations
- NO MODEL CALLBACKS - Exception: attachment destruction
Ruby 3.4 & Rails 8
YJIT enabled by default (15-30% faster). New it block parameter:
users.map { it.name } # replaces _1
Solid Trifecta (DB-backed alternatives to Redis):
| Component | Purpose | Use When |
|---|---|---|
| Solid Queue | Jobs | <100 jobs/sec, no Redis needed |
| Solid Cache | Caching | 10TB+ possible |
| Solid Cable | WebSockets | No Redis infra |
Use Sidekiq when: latency <100ms required, 10k+ jobs/min
Pattern Summary
Service: Complex business logic, multi-step operations, transactions
MyService.new(user:, params:).call # Returns OpenStruct(success, record)
Form: User input validation + persistence
MyForm.new(params, user).save # Returns true/false
Contract: Validation rules (Dry-validation)
CreateContract.new.call(params) # Returns Result(success?, errors)
Controller: HTTP layer only, no business logic
def create
form = CreateForm.new(params, current_user)
form.save ? render(json: form.model, status: :created) : render(json: { errors: form.errors }, status: :unprocessable_entity)
end
Model: Associations, enums, simple scopes. NO validations, NO callbacks, NO business logic.
belongs_to :user
has_many :tags, dependent: :destroy
enum :status, { draft: 0, published: 1 }
scope :recent, -> { order(created_at: :desc) }
Quality Checklist
Before commit: bundle exec lefthook run all
- NO controller logic
- Validation in contracts only
- Business logic in services
- Jobs idempotent
- Tests pass
Resources
- https://guides.rubyonrails.org/
- https://dry-rb.org/gems/dry-validation/
- https://github.com/rails/solid_queue
- https://turbo.hotwired.dev/
Key gems: Dry-validation, Sidekiq/Solid Queue, Scenic, Pundit, Devise/Rodauth, ViewComponent/Phlex
For detailed patterns and examples, see references/rails-patterns.md
More from maroffo/claude-forge
email-cleanup
Clean up Gmail - archive old emails, delete promotions, manage storage. Use when user wants to clean inbox, archive emails, or free up space.
25newsletter-digest
Process newsletters into Second Brain digest. Use when user wants to process newsletters, create digest, or catch up on subscriptions. Not for web clippings (use process-clippings) or email bookmarks (use process-email-bookmarks).
22table-image
Render markdown tables as hand-drawn sketch images. Use when user wants a table rendered as an image, visual table, or diagram illustration.
21apple-swift
Apple platform development with Swift, SwiftUI, async/await, and performance. Use when working with .swift files, Package.swift, Xcode projects, or building for iOS/macOS/watchOS/visionOS.
20react-nextjs
React + Next.js App Router development. Use when working with .tsx/.jsx files, next.config, or user asks about Server Components, data fetching, state management, forms, or React testing.
20inbox-triage
Review and prioritize Gmail inbox. Use when user wants to check email, review inbox, or see what needs attention.
19