Skip to content
Back to skills

Rails Hotwire Expert

ASecurity

当用 Rails 7+ 搭建带 Hotwire 的 Web 应用、做实时局部更新或后台任务时使用;产出 Active Record 防 N+1 查询、Turbo Frames/Streams 局部刷新、Action Cable 通道、Sidekiq Worker 与 RSpec 测试套件;不适用于非 Rails 栈、纯前端 SPA、仅需基础 Ruby 语法、或无法改动 Gemfile 与迁移的场景;触发词:Rails、Hotwire、Turbo、Action Cable、Sidekiq、Active Record、RSpec

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
ai-agentsgorubysqlreactvuedjangorailscode-reviewgitapi

Works with

  • cursor
  • cli
  • api

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add findscripter/everything-skills --skill rails-hotwire-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rails Hotwire Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rails Hotwire Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/findscripter-rails-hotwire-expert/badge)](https://www.skillsdirectory.com/skills/findscripter-rails-hotwire-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: rails-hotwire-expert
title: Rails 7+ 与 Hotwire 开发专家
description: 当用 Rails 7+ 搭建带 Hotwire 的 Web 应用、做实时局部更新或后台任务时使用;产出 Active Record 防 N+1 查询、Turbo Frames/Streams 局部刷新、Action Cable 通道、Sidekiq Worker 与 RSpec 测试套件;不适用于非 Rails 栈、纯前端 SPA、仅需基础 Ruby 语法、或无法改动 Gemfile 与迁移的场景;触发词:Rails、Hotwire、Turbo、Action Cable、Sidekiq、Active Record、RSpec
domain: 研发/backend
triggers: [Rails 7, Ruby on Rails, Hotwire, Turbo Frames, Turbo Streams, Stimulus, Action Cable, WebSocket, Active Record 优化, N+1 查询, includes/eager_load, Sidekiq 后台任务, RSpec Rails, strong parameters, service object]
tags: [rails, hotwire, turbo, active-record, sidekiq, action-cable, rspec, 研发]
level: 精通
status: stable
agents: [claude-code, codex, cursor, gemini-cli]
tools: [ruby, rails, hotwire, turbo-rails, stimulus, action-cable, sidekiq, rspec-rails, rubocop, factory_bot]
requires: []
related: [ruby-pro, laravel-app-specialist, django-async-pro, sveltekit-fullstack]
combines_with: [websocket-realtime-engineer, rest-api-endpoint-builder]
license: MIT
source: jeffallan/claude-skills
source_license: MIT
---
## 何时使用

适用:
- 用 Rails 7+ 搭建或扩展 Web 应用,前端走 Hotwire(Turbo + Stimulus)而非独立 SPA。
- 需要局部页面刷新(Turbo Frames / Streams)、WebSocket 实时推送(Action Cable)。
- 把慢操作(发信、导出、第三方调用)下沉到 Sidekiq 后台任务。
- 优化 Active Record:消除 N+1、补索引、加缓存;用 RSpec 补齐模型/请求/系统测试。

不该用(负边界):
- 非 Rails 栈,或后端用其他语言运行时。
- 纯前端 SPA(React/Vue 独立前端 + Rails 仅作 JSON API 也尽量用 Hotwire 思路,否则另选技能)。
- 只需基础 Ruby 语法解释。
- 无法改动 Gemfile、迁移文件或工具链(代码与迁移无从落地)。

## 步骤

1. 梳理需求:识别模型与关联、路由、实时需求、后台任务边界。
2. 脚手架:`rails generate model User name:string email:string`、`rails generate controller Users`。
3. 跑迁移:`rails db:migrate`,用 `rails db:schema:dump` 校验 schema。
   - 迁移失败:查 `db/schema.rb` 冲突 → `rails db:rollback` → 修正重试。
4. 实现:写瘦控制器(强参数)+ 模型(关联/校验),复杂逻辑放 service object;按需接入 Hotwire / Action Cable / Sidekiq。
5. 验证:`bundle exec rspec` 必须全绿;`bundle exec rubocop` 过风格检查。
   - 测试失败:加 `--format documentation` 看细节,修正失败用例后重跑。
   - 评审中冒出 N+1:补 `includes`/`eager_load` 后重跑。
6. 优化:审计 N+1、为 `WHERE`/`ORDER BY`/`JOIN` 列补索引、加缓存。

## 指令

- 实现一个 Rails 特性时,按需产出:迁移文件 → 模型(含关联与校验)→ 控制器(RESTful + 强参数)→ 视图或 Hotwire 装配 → RSpec(模型 + 请求)→ 关键架构决策一句话说明。
- 集合查询凡涉及关联,一律用 `includes`/`eager_load` 防 N+1。
- 控制器保持瘦身,复杂业务逻辑抽到 service object。
- 慢操作走 `perform_later` 入 Sidekiq,绝不在请求周期内同步执行。
- 原始 SQL 必须参数化或 `sanitize_sql`;勿在 URL 直接暴露内部自增 ID(按需用 UUID/slug)。

## 示例

防 N+1(includes / eager_load):

```ruby
# BAD — 触发 N+1
posts = Post.all
posts.each { |post| puts post.author.name }

# GOOD — 预加载关联
posts = Post.includes(:author).all

# GOOD — eager_load 强制 JOIN(按关联字段过滤时用)
posts = Post.eager_load(:author).where(authors: { verified: true })
```

Turbo Frame 局部更新:

```erb
<%# 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 %>
```

```ruby
# app/controllers/posts_controller.rb
def index
  @posts = Post.includes(:author).page(params[:page])
  @next_page = @posts.next_page
end
```

Sidekiq Worker 模板:

```ruby
# app/jobs/send_welcome_email_job.rb
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}")
    # 记录已不存在,不再 raise,重试无意义
  end
end

# 从控制器或模型回调入队
SendWelcomeEmailJob.perform_later(user.id)
```

强参数 + 瘦控制器:

```ruby
# app/controllers/posts_controller.rb
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)
  end
end
```

## 注意事项

- 必做:每个关联集合查询防 N+1;测试争取 >95% 覆盖;复杂逻辑用 service object;为 `WHERE`/`ORDER BY`/`JOIN` 列补索引;慢操作下沉 Sidekiq。
- 禁做:跳过迁移直接改 schema;用未 sanitize 的原始 SQL;无脑在 URL 暴露内部 ID。
- 表单校验失败时 `render :new, status: :unprocessable_entity`(422),Turbo 才会正确替换帧而非误判成功跳转。
- Sidekiq 任务参数只传 ID 等可序列化值,不要传整个 AR 对象。

## 互见

- requires:`ruby-pro` —— Rails 之上需先具备 Ruby/Rails 惯用法与 RSpec 基础
- related:`backend-architecture-patterns`、`database-design-advisor`、`code-reviewer`
- combines_with:`rest-api-endpoint-builder` —— Rails API 模式下做端点契约;`database-design-advisor` —— 配合做迁移与索引设计

---
采编自 [jeffallan/claude-skills](https://github.com/Jeffallan/claude-skills)(MIT)。

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…