关于 rails-audit-thoughtbot
面向 Claude Code 的 Ruby on Rails 审计 Skill,依据 thoughtbot 的 Ruby Science 和测试实践检查应用。支持全项目或指定路径审查,可选收集 SimpleCov、RubyCritic 指标并生成 Markdown 报告。
主要功能
- 01全项目或定向 Rails 审计
- 02可选 SimpleCov 覆盖率指标
- 03可选 RubyCritic 质量指标
- 04检查测试、安全、设计与数据库
- 05生成 RAILS_AUDIT_REPORT.md
适用场景
- 01审查整个 Rails 应用
- 02审计指定文件或目录
- 03梳理安全与测试问题的优先级
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thoughtbot/ rails-audit-thoughtbot --skill rails-audit-thoughtbot安装后在 Claude Code 中输入/rails-audit-thoughtbot确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSECODEOWNERSREADME.mdagents/simplecov_agent.mdrubycritic_agent.mdreferences/rails_antipatterns.mdporo_patterns.mdreport_template.mdsecurity_checklist.mdcode_smells.mdtesting_guidelines.md详细介绍
Rails 审计技能(thoughtbot 最佳实践)
根据 thoughtbot 的 Ruby Science 和 Testing Rails 最佳实践,对 Ruby on Rails 应用进行全面审计,重点关注优先使用普通 Ruby 对象(PORO),而非 Service Object。
审计范围
审计可以通过两种模式运行:
- 完整应用审计:分析整个 Rails 应用
- 定向审计:分析指定文件或目录
执行流程
步骤 1:确定审计范围
询问用户,或根据请求推断:
- 完整审计:分析整个
app/、spec/或test/、config/、db/、lib/ - 定向审计:仅分析指定路径
步骤 2:收集可选指标(SimpleCov + RubyCritic)
通过一次 AskUserQuestion 提前同时询问用户这两个问题,让用户可以一次性做出选择:
- 问题:“开始审计前,是否要收集自动化指标?\n\n1. SimpleCov — 运行测试套件以获取实际代码覆盖率百分比\n2. RubyCritic — 分析代码复杂度、重复和异味(不运行测试)\n\n建议同时使用两者,以进行最全面的审计。”
- 选项:“两者都要(推荐)” / “仅 SimpleCov” / “仅 RubyCritic” / “两者都跳过”
根据用户的选择,使用 Task 工具并行启动已获准的子 Agent。两者可以同时运行,因为 SimpleCov 会修改测试辅助文件,而 RubyCritic 只读取源文件,两者不会冲突。
SimpleCov 子 Agent(如获准):
阅读文件
agents/simplecov_agent.md并遵循其中描述的所有步骤。审计范围为:{{SCOPE from Step 1}}。按照该文件指定的输出格式返回覆盖率数据。
RubyCritic 子 Agent(如获准):
阅读文件
agents/rubycritic_agent.md并遵循其中描述的所有步骤。审计范围为:{{SCOPE from Step 1}}。按照该文件指定的输出格式返回代码质量数据。
两个 Agent 完成后,进行清理:
- 如果运行了 SimpleCov:
rm -rf coverage/ - 如果运行了 RubyCritic:
rm -rf tmp/rubycritic/
解读响应:
COVERAGE_FAILED/RUBYCRITIC_FAILED:该工具没有数据 — SimpleCov 使用估算模式,或省略 RubyCritic 部分。请在报告中注明失败原因。COVERAGE_DATA:解析并保留在上下文中,供步骤 4 和 5 使用(总体覆盖率、各目录明细、覆盖率最低的文件、覆盖率为零的文件)。RUBYCRITIC_DATA:解析并保留在上下文中,供步骤 4 和 5 使用(总评分、各目录评级、评级最低的文件、主要异味、复杂度最高的文件)。
步骤 3:加载参考资料
开始分析前,阅读相关参考文件:
references/code_smells.md- 需要识别的代码异味模式references/testing_guidelines.md- 测试最佳实践references/poro_patterns.md- PORO 和 ActiveModel 模式references/security_checklist.md- 安全漏洞模式references/rails_antipatterns.md- Rails 专属反模式(外部服务、迁移、性能)
第 4 步:按类别分析代码
所有分析都必须限制在项目根目录和 bundle 路径内。要检查 gem 源码,请使用 bundle show <gem> 定位(参见 Analysis Commands 下的“Locate gem source”)——切勿运行 find / 等全文件系统搜索。如果将以下任何类别委派给子 Agent,请在每个子 Agent 的提示词中注明此限制。
按以下顺序分析:
-
测试覆盖率与质量
- 如果在第 2 步收集了 SimpleCov 数据,请使用实际覆盖率百分比,而非估算值
- 交叉核对每个文件的 SimpleCov 数据:覆盖率为 0% 的文件 =“缺少测试”
- 检查是否缺少测试文件
- 找出未经测试的公共方法
- 检查测试结构(四阶段测试)
- 检查测试反模式
-
安全漏洞
- SQL 注入风险
- 批量赋值漏洞
- XSS 漏洞
- 身份验证/授权问题
- 敏感数据泄露
-
模型与数据库
- 检测臃肿模型
- 缺少验证
- N+1 查询风险
- 回调复杂度
- 违反迪米特法则(窥视型模型)
- 如果收集了 RubyCritic 数据,标记评级为 D/F 或复杂度较高的模型
-
控制器
- 检测臃肿控制器
- 控制器中的业务逻辑
- 缺少强参数
- 响应处理
- 单体控制器(非 RESTful 操作、操作数 > 7)
- 臃肿的会话(存储对象而非 ID)
- 如果收集了 RubyCritic 数据,标记评级为 D/F 或复杂度较高的控制器
-
代码设计与架构
- 服务对象 → 建议重构为 PORO
- 类过大
- 方法过长
- 特性嫉妒
- 违反迪米特法则
- 违反单一职责原则
- 如果收集了 RubyCritic 数据,将评级为 D/F 或复杂度较高的文件与人工代码审查结果交叉核对
-
视图与 Presenter
- 视图中的逻辑(PHPitis)
- 缺少用于 DRY 的局部视图
- 助手复杂度
- 视图中的查询逻辑
-
外部服务与错误处理
- 发后不管(HTTP 调用缺少异常处理)
- 响应迟缓的服务(缺少超时设置、应放到后台处理却仍同步执行的调用)
- 裸 rescue 语句
- 静默失败(保存时未检查返回值)
-
数据库与迁移
- 混乱的迁移(引用模型、缺少 down 方法)
- 外键、多态关联、唯一性验证缺少索引
- 性能反模式(使用 Ruby 迭代而非 SQL 查询)
- 未使用事务的批量操作
第 5 步:生成审计报告
在项目根目录创建 RAILS_AUDIT_REPORT.md,结构按照 references/report_template.md 中的定义。
如果在第 2 步收集了 SimpleCov 覆盖率数据,请在报告中使用测试部分的 SimpleCov 变体。如果没有覆盖率数据,请使用估算变体。
如果在第 2b 步收集了 RubyCritic 数据,请在报告中使用报告模板中的 RubyCritic 变体,并包含 代码质量指标部分。如果没有 RubyCritic 数据,请使用不可用变体。
严重程度定义
- 严重:安全漏洞、数据丢失风险、会导致生产环境故障的问题
- 高:性能问题、关键路径缺少测试、重大代码异味
- 中:代码异味、违反约定、可维护性问题
- 低:风格问题、细微改进、建议
关键检测模式
服务对象 → PORO 重构
当你在 app/services/ 中发现类时:
- 名称为
*Service、*Manager、*Handler的类 - 仅有
.call或.perform方法的类 - 建议:重命名为领域名词,并包含
ActiveModel::Model
臃肿模型检测
符合以下情况的模型:
- 超过 200 行
- 超过 15 个公共方法
- 承担多项互不相关的职责
- 建议:使用组合方式提取为 PORO
臃肿控制器检测
控制器存在以下情况时:
- 操作超过 15 行
- 包含业务逻辑(而非请求/响应处理)
- 多次赋值实例变量
- 建议:提取为表单对象或领域模型
缺少测试检测
对于 app/ 中的每个 Ruby 文件:
- 检查是否有对应的
_spec.rb或_test.rb - 检查公共方法是否经过测试
- 报告未测试的文件和方法
分析命令
使用 Claude Code 的内置工具,而非 shell 命令——它们速度更快、能正确处理权限,并且输出效果更好:
- 按类型查找 Ruby 文件:使用 Glob 工具和
app/models/**/*.rb、app/controllers/**/*.rb、app/services/**/*.rb等模式 - 查找测试文件:使用 Glob 工具和
spec/**/*_spec.rb或test/**/*_test.rb - 搜索代码中的模式:使用 Grep 工具(例如搜索
rescue\s*$、\.save\b、params\.permit!) - 读取文件并统计行数:使用 Read 工具检查文件;根据输出统计行数
- 查找较长的文件:使用 Glob 列出所有
app/**/*.rb文件,然后逐个使用 Read 检查行数 - 定位 gem 源码:当分析需要读取 gem 提供的代码(例如来自 Devise、Administrate 或 Madmin 等引擎的基础控制器或 concern)时,使用
bundle show <gem>(或bundle exec gem which <gem>/<path>)查找已安装 gem 的目录,然后在其中使用 Read/Grep。切勿在项目根目录和 bundle 路径之外搜索——不要使用find /或覆盖整个主目录的 glob。
报告输出
始终将审计报告保存到项目根目录下的 RAILS_AUDIT_REPORT.md,并提供给用户。