关于 rails-expert
rails-expert 是面向 Rails 应用开发与维护的技能,提供分阶段工作流、按主题组织的参考资料、实现模式,以及测试和性能检查。
主要功能
- 01Rails 功能开发工作流
- 02Hotwire 与 Active Record 指南
- 03后台任务和 API 参考
- 04RSpec 与 RuboCop 验证
- 05N+1 查询和索引检查
适用场景
- 01规划并实现 Rails 资源
- 02选择 Hotwire 界面模式
- 03排查迁移和失败的测试
- 04检查查询性能与数据库索引
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jeffallan/ claude-skills --skill rails-expert安装后在 Claude Code 中输入/rails-expert确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/active-record.mdapi-development.mdbackground-jobs.mdhotwire-turbo.mdrspec-testing.md详细介绍
Rails 专家
核心工作流
- 分析需求 — 确定模型、路由、实时需求和后台任务
- 搭建资源 —
rails generate model User name:string email:string、rails generate controller Users - 运行迁移 — 执行
rails db:migrate,并通过rails db:schema:dump验证架构- 如果迁移失败:检查
db/schema.rb中是否存在冲突,使用rails db:rollback回滚,修复后重试
- 如果迁移失败:检查
- 实现功能 — 编写控制器、模型,并添加 Hotwire(见下方参考指南)
- 验证 —
bundle exec rspec必须通过;使用bundle exec rubocop检查代码风格- 如果测试失败:检查错误输出,修复失败的示例,并使用
--format documentation重新运行以查看详细信息 - 如果评审时发现 N+1 查询:添加
includes/eager_load(见常见模式),并重新运行测试
- 如果测试失败:检查错误输出,修复失败的示例,并使用
- 优化 — 检查 N+1 查询、添加缺失的索引,并添加缓存
参考指南
根据上下文加载详细指南:
| 主题 | 参考资料 | 加载时机 |
|---|---|---|
| Hotwire/Turbo | references/hotwire-turbo.md | 使用 Turbo Frames、Streams、Stimulus 控制器时 |
| Active Record | references/active-record.md | 处理模型、关联、查询和性能时 |
| 后台任务 | references/background-jobs.md | 使用 Sidekiq,或设计任务、队列和错误处理时 |
| 测试 | references/rspec-testing.md | 编写模型、请求、系统测试或工厂时 |
| API 开发 | references/api-development.md | 使用纯 API 模式,或处理序列化、身份验证时 |
常见模式
使用 includes/eager_load 防止 N+1
# BAD — triggers N+1
posts = Post.all
posts.each { |post| puts post.author.name }
# GOOD — eager load association
posts = Post.includes(:author).all
posts.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(局部页面更新)
<%# 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 %>
# app/controllers/posts_controller.rb
def index
@posts = Post.includes(:author).page(params[:page])
@next_page = @posts.next_page
end
Sidekiq Worker 模板
# 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}")
# Do not re-raise; record is gone, no point retrying
end
end
# Enqueue from controller or model callback
SendWelcomeEmailJob.perform_later(user.id)
强参数(控制器模板)
# 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
约束
必须做到
- 对涉及关联的每个集合查询使用
includes/eager_load,防止 N+1 查询 - 编写全面的测试,目标覆盖率 >95%
- 复杂业务逻辑使用服务对象;保持控制器精简
- 为每个用于
WHERE、ORDER BY或JOIN的列添加数据库索引 - 将耗时操作交由 Sidekiq 处理,绝不能在请求周期中同步运行
禁止事项
- 架构变更时跳过迁移
- 未经清理就使用原始 SQL(只能使用
sanitize_sql或参数化查询) - 不加考虑地在 URL 中暴露内部 ID
输出模板
实现 Rails 功能时,请提供:
- 迁移文件(如果需要更改架构)
- 包含关联和验证的模型文件
- 包含 RESTful 操作和强参数的控制器
- 视图文件或 Hotwire 设置
- 模型和请求的测试文件
- 对架构决策的简要说明
由 @jeffallan 维护,他是 Synergetic Solutions 的首席顾问。
评论
支持 Markdown