AgentSkillsCN

ruby-development

开展项目评估、头脑风暴与愿景演进。涵盖项目状态评估、问题空间探索、创意生成,以及战略方向的持续迭代。在需要退后一步、从全局视角审视项目时,或当用户询问“当前项目处于何种状态?”或“帮我想想这个问题该怎么解决?”时,可加以运用。

SKILL.md
--- frontmatter
name: ruby-development
description: >-
  Covers Ruby and Rails 8+ development following the DHH/37signals way. Includes Ruby idioms,
  Hotwire, Solid Queue, Minitest, gem development, and CLI tools. Use when building Rails apps,
  writing background jobs, or when the user asks "how do I add Hotwire?" or "what's the Rails
  convention for X?"

Ruby Development

The DHH/37signals way: convention over configuration, programmer happiness, and elegant simplicity.

Philosophy

The Rails Doctrine

  • Optimize for programmer happiness - Ruby's beauty isn't accidental
  • Convention over configuration - Sensible defaults, deviate only with reason
  • The menu is omakase - Trust the chef's curated choices
  • No one paradigm - Mix OOP, functional, metaprogramming as needed
  • Exalt beautiful code - Code is read more than written
  • Provide sharp knives - Power tools for capable developers
  • Value integrated systems - The majestic monolith over distributed chaos
  • Progress over stability - Embrace change, don't fear upgrades
  • Push up a big tent - Welcome diverse approaches

Calm Development

From "It Doesn't Have to Be Crazy at Work":

  • Work sustainably, not heroically
  • 40-hour weeks produce better code than crunch
  • Meetings are a last resort
  • Deep work requires long, uninterrupted stretches

Ruby Idioms

Expressive Code

ruby
# Prefer readable over clever
users.select(&:active?).map(&:email)

# Guard clauses over nested conditionals
def process(user)
  return unless user.active?
  return if user.banned?

  # Happy path at normal indentation
  send_notification(user)
end

# Implicit returns
def full_name
  "#{first_name} #{last_name}"
end

# Trailing conditionals for simple cases
send_email if user.subscribed?
raise ArgumentError, "Invalid" unless valid?

Duck Typing

ruby
# Check behavior, not class
def export(target)
  target.write(data) if target.respond_to?(:write)
end

# Accept anything that quacks like a duck
class Report
  def initialize(formatter)
    @formatter = formatter  # Any object with #format method
  end
end

Blocks and Iterators

ruby
# Blocks for configuration
Rails.application.configure do |config|
  config.cache_store = :memory_store
end

# Blocks for resource management
File.open("data.txt") do |file|
  process(file.read)
end  # File automatically closed

# Custom iterators
def each_with_status
  items.each_with_index do |item, i|
    yield item, "#{i + 1}/#{items.size}"
  end
end

Stack Overview

Rails 8 (Default)

ComponentDefaultAlternative
DatabaseSQLite (dev/prod)PostgreSQL
Background JobsSolid QueueSidekiq
CachingSolid CacheRedis
WebSocketsSolid CableRedis
AssetsPropshaft + Import Mapsesbuild
CSSTailwind (standalone)Bootstrap
DeploymentKamalCapistrano

Beyond Rails

Use CaseToolNotes
MicroservicesSinatra, RodaWhen Rails is overkill
API-onlyGrapeLightweight REST APIs
Full-stack alternativeHanamiClean architecture
CLI toolsThor, TTYCommand-line interfaces
Gem developmentBundlerStandard tooling
Background jobsSidekiqWhen you need Redis anyway

Quick Reference

bash
# Rails 8 app
rails new myapp --database=postgresql

# Sinatra microservice
bundle gem my_service --no-test

# CLI tool
bundle gem my_cli --no-test
# Add thor to gemspec

# Generators (Rails)
bin/rails g model User name:string email:string
bin/rails g controller Posts index show
bin/rails g authentication

# Development
bin/dev                    # Start with Procfile.dev
bin/rails test             # Run tests
bin/rails db:migrate       # Run migrations

# Deployment (Kamal)
kamal setup && kamal deploy

Topics

TopicReferenceUse When
Corecore.mdWriting idiomatic Ruby, organizing Rails files
Modelsmodels.mdCreating models, validations, associations, migrations
Controllerscontrollers.mdBuilding RESTful actions, strong params, filters
Viewsviews.mdCreating templates, partials, layouts, helpers
Hotwirehotwire.mdAdding Turbo Drive/Frames/Streams, Stimulus
APIapi.mdBuilding JSON APIs, versioning, authentication
Jobsjobs.mdSetting up Solid Queue, Active Job, recurring jobs
Securitysecurity.mdImplementing authentication, authorization, CSRF
Testingtesting.mdWriting Minitest, fixtures, system tests
Performanceperformance.mdFixing N+1 queries, caching, indexing
Deploymentdeployment.mdDeploying with Kamal, Docker, zero-downtime
Stylingstyling.mdSetting up Tailwind CSS, responsive design
Servicesservices.mdCreating service objects, result patterns
Assetsassets.mdConfiguring Propshaft, Import Maps
Mobilemobile.mdBuilding Hotwire Native, Bridge Components
Debuggingdebugging.mdUsing binding.irb, byebug, Rails console

Critical Rules

Always

  • Follow Ruby/Rails naming conventions exactly
  • Write expressive, readable code over clever code
  • Use generators (bin/rails g) for scaffolding
  • Write tests first (TDD with Minitest)
  • Keep controllers thin (under 10 lines per action)
  • Return proper HTTP status codes
  • Use strong parameters for all user input
  • Index foreign keys in migrations

Never

  • Fight conventions without excellent reason
  • Put business logic in controllers or views
  • Skip model validations
  • Use render after successful mutations (use redirect_to)
  • Store secrets in code (use credentials:edit)
  • Write custom CSS when Tailwind utilities exist
  • Reach for microservices before the monolith fails

File Organization

Rails

code
app/
├── controllers/     # HTTP request handling
├── models/          # Business logic and data
├── views/           # Templates and partials
├── services/        # Complex operations
├── jobs/            # Background processing
├── javascript/      # Stimulus controllers
│   └── controllers/
└── assets/
    └── stylesheets/ # Tailwind CSS

Gem

code
my_gem/
├── lib/
│   ├── my_gem.rb         # Entry point
│   └── my_gem/
│       ├── version.rb
│       └── ...
├── test/                  # Minitest
├── my_gem.gemspec
└── Gemfile

Decision Guide

NeedSolution
Web applicationRails 8
CRUD operationsRESTful controllers
Dynamic updatesTurbo Frames/Streams
Complex business logicService objects
Background processingSolid Queue jobs
External APIAPI controller + token auth
Mobile appHotwire Native
MicroserviceSinatra or Roda
CLI toolThor + TTY
Shared libraryGem