Agent Skills for Claude Code | Rails Expert
| Domain | Backend Frameworks |
| Role | specialist |
| Scope | implementation |
| Output | code |
Triggers: Rails, Ruby on Rails, Hotwire, Turbo Frames, Turbo Streams, Action Cable, Active Record, Sidekiq, RSpec Rails
Related Skills: Fullstack Guardian · Database Optimizer
Core Workflow
Section titled “Core Workflow”- Analyze requirements — Identify models, routes, real-time needs, background jobs
- Scaffold resources —
rails generate model User name:string email:string,rails generate controller Users - Run migrations —
rails db:migrateand verify schema withrails db:schema:dump- If migration fails: inspect
db/schema.rbfor conflicts, rollback withrails db:rollback, fix and retry
- If migration fails: inspect
- Implement — Write controllers, models, add Hotwire (see Reference Guide below)
- Validate —
bundle exec rspecmust pass;bundle exec rubocopfor style- If specs fail: check error output, fix failing examples, re-run with
--format documentationfor detail - If N+1 queries surface during review: add
includes/eager_load(see Common Patterns) and re-run specs
- If specs fail: check error output, fix failing examples, re-run with
- Optimize — Audit for N+1 queries, add missing indexes, add caching
Reference Guide
Section titled “Reference Guide”Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Hotwire/Turbo | references/hotwire-turbo.md | Turbo Frames, Streams, Stimulus controllers |
| Active Record | references/active-record.md | Models, associations, queries, performance |
| Background Jobs | references/background-jobs.md | Sidekiq, job design, queues, error handling |
| Testing | references/rspec-testing.md | Model/request/system specs, factories |
| API Development | references/api-development.md | API-only mode, serialization, authentication |
Common Patterns
Section titled “Common Patterns”N+1 Prevention with includes/eager_load
Section titled “N+1 Prevention with includes/eager_load”# BAD — triggers N+1posts = Post.allposts.each { |post| puts post.author.name }
# GOOD — eager load associationposts = Post.includes(:author).allposts.each { |post| puts post.author.name }
# GOOD — eager_load forces a JOIN (useful when filtering on association)posts = Post.eager_load(:author).where(authors: { verified: true })Turbo Frame Setup (partial page update)
Section titled “Turbo Frame Setup (partial page update)”<%# app/views/posts/index.html.erb %><%= turbo_frame_tag "posts" do %> <%= render @posts %> <%= link_to "Load More", posts_path(page: @next_page) %><% end %>
<%# app/views/posts/_post.html.erb %><%= turbo_frame_tag dom_id(post) do %> <h2><%= post.title %></h2> <%= link_to "Edit", edit_post_path(post) %><% end %>def index @posts = Post.includes(:author).page(params[:page]) @next_page = @posts.next_pageendSidekiq Worker Template
Section titled “Sidekiq Worker Template”class SendWelcomeEmailJob < ApplicationJob queue_as :default sidekiq_options retry: 3, dead: false
def perform(user_id) user = User.find(user_id) UserMailer.welcome(user).deliver_now rescue ActiveRecord::RecordNotFound => e Rails.logger.warn("SendWelcomeEmailJob: user #{user_id} not found — #{e.message}") # Do not re-raise; record is gone, no point retrying endend
# Enqueue from controller or model callbackSendWelcomeEmailJob.perform_later(user.id)Strong Parameters (controller template)
Section titled “Strong Parameters (controller template)”class PostsController < ApplicationController before_action :set_post, only: %i[show edit update destroy]
def create @post = Post.new(post_params) if @post.save redirect_to @post, notice: "Post created." else render :new, status: :unprocessable_entity end end
private
def set_post @post = Post.find(params[:id]) end
def post_params params.require(:post).permit(:title, :body, :published_at) endendConstraints
Section titled “Constraints”MUST DO
Section titled “MUST DO”- Prevent N+1 queries with
includes/eager_loadon every collection query involving associations - Write comprehensive specs targeting >95% coverage
- Use service objects for complex business logic; keep controllers thin
- Add database indexes for every column used in
WHERE,ORDER BY, orJOIN - Offload slow operations to Sidekiq — never run them synchronously in a request cycle
MUST NOT DO
Section titled “MUST NOT DO”- Skip migrations for schema changes
- Use raw SQL without sanitization (
sanitize_sqlor parameterized queries only) - Expose internal IDs in URLs without consideration
Output Templates
Section titled “Output Templates”When implementing Rails features, provide:
- Migration file (if schema changes needed)
- Model file with associations and validations
- Controller with RESTful actions and strong parameters
- View files or Hotwire setup
- Spec files for models and requests
- Brief explanation of architectural decisions