name: dhh-rails-style description: 这个技能应用于编写Ruby和Rails代码时,采用DHH独特的37signals风格。它适用于编写Ruby代码、Rails应用程序、创建模型、控制器或任何Ruby文件。在Ruby/Rails代码生成、重构请求、代码审查或用户提到DHH、37signals、Basecamp、HEY或Campfire风格时触发。体现了REST纯净性、胖模型、瘦控制器、Current属性、Hotwire模式以及“清晰性优于聪明性”的哲学。
<objective> 应用37signals/DHH Rails约定到Ruby和Rails代码。这个技能提供了从分析生产37signals代码库(Fizzy/Campfire)和DHH的代码审查模式中提取的全面领域专业知识。 </objective>
<essential_principles>
核心哲学
“最好的代码是你没有写的代码。第二好的是明显正确的代码。”
纯Rails就足够了:
- 丰富的领域模型优于服务对象
- CRUD控制器优于自定义动作
- 使用Concerns进行水平代码共享
- 记录作为状态而不是布尔列
- 数据库支持一切(不使用Redis)
- 在寻找gem之前构建解决方案
他们故意避免的:
- devise(使用自定义约150行的认证代替)
- pundit/cancancan(在模型中进行简单的角色检查)
- sidekiq(使用数据库的Solid Queue)
- redis(一切用数据库)
- view_component(部分视图工作良好)
- GraphQL(REST与Turbo足够)
- factory_bot(fixtures更简单)
- rspec(Rails自带Minitest)
- Tailwind(原生CSS与层)
开发哲学:
- 发布、验证、完善 – 将原型质量的代码发布到生产环境以学习
- 修复根本原因,而不是症状
- 写时操作优于读时计算
- 数据库约束优于ActiveRecord验证 </essential_principles>
<intake> 你在做什么?
- 控制器 – REST映射、concerns、Turbo响应、API模式
- 模型 – Concerns、状态记录、回调、作用域、POROs
- 视图和前端 – Turbo、Stimulus、CSS、部分视图
- 架构 – 路由、多租户、认证、作业、缓存
- 测试 – Minitest、fixtures、集成测试
- Gems和依赖 – 使用什么vs避免什么
- 代码审查 – 根据DHH风格审查代码
- 一般指导 – 哲学和约定
指定一个数字或描述你的任务。 </intake>
<routing>
| 响应 | 阅读参考 |
|---|---|
| 1, controller | controllers.md |
| 2, model | models.md |
| 3, view, frontend, turbo, stimulus, css | frontend.md |
| 4, architecture, routing, auth, job, cache | architecture.md |
| 5, test, testing, minitest, fixture | testing.md |
| 6, gem, dependency, library | gems.md |
| 7, review | 阅读所有参考,然后审查代码 |
| 8, general task | 基于上下文阅读相关参考 |
阅读相关参考后,将模式应用到用户的代码。 </routing>
<quick_reference>
命名约定
动词: card.close, card.gild, board.publish(不是set_style方法)
谓词: card.closed?, card.golden?(从相关记录的存在派生)
Concerns: 描述能力的形容词(Closeable, Publishable, Watchable)
控制器: 匹配资源的名词(Cards::ClosuresController)
作用域:
chronologically,reverse_chronologically,alphabetically,latestpreloaded(标准急切加载名称)indexed_by,sorted_by(参数化)active,unassigned(业务术语,非SQL风格)
REST映射
代替自定义动作,创建新资源:
POST /cards/:id/close → POST /cards/:id/closure
DELETE /cards/:id/close → DELETE /cards/:id/closure
POST /cards/:id/archive → POST /cards/:id/archival
Ruby语法偏好
# 符号数组,括号内有空格
before_action :set_message, only: %i[ show edit update destroy ]
# 私有方法缩进
private
def set_message
@message = Message.find(params[:id])
end
# 条件语句的无表达式case
case
when params[:before].present?
messages.page_before(params[:before])
else
messages.last_page
end
# Bang方法用于快速失败
@message = Message.create!(params)
# 三元运算符用于简单条件
@room.direct? ? @room.users : @message.mentionees
关键模式
状态作为记录:
Card.joins(:closure) # 关闭的卡片
Card.where.missing(:closure) # 开放的卡片
Current属性:
belongs_to :creator, default: -> { Current.user }
模型上的授权:
class User < ApplicationRecord
def can_administer?(message)
message.creator == self || admin?
end
end
</quick_reference>
<reference_index>
领域知识
所有详细模式在references/中:
| 文件 | 主题 |
|---|---|
| controllers.md | REST映射、concerns、Turbo响应、API模式、HTTP缓存 |
| models.md | Concerns、状态记录、回调、作用域、POROs、授权、广播 |
| frontend.md | Turbo Streams、Stimulus控制器、CSS层、OKLCH颜色、部分视图 |
| architecture.md | 路由、认证、作业、Current属性、缓存、数据库模式 |
| testing.md | Minitest、fixtures、单元/集成/系统测试、测试模式 |
| gems.md | 他们使用什么vs避免什么、决策框架、Gemfile示例 |
| </reference_index> |
<success_criteria> 代码遵循DHH风格当:
- 控制器映射到资源的CRUD动词
- 模型使用concerns进行水平行为
- 状态通过记录跟踪,而不是布尔值
- 没有不必要的服务对象或抽象
- 优先选择数据库支持的解决方案,而不是外部服务
- 测试使用Minitest和fixtures
- Turbo/Stimulus用于交互性(无重JS框架)
- 原生CSS与现代功能(层、OKLCH、嵌套)
- 授权逻辑位于User模型上
- 作业是调用模型方法的浅包装器 </success_criteria>
<credits> 基于非官方37signals/DHH Rails风格指南由Marc Köhlbrugge编写,通过对Fizzy代码库的265个拉取请求进行深入分析生成。
重要免责声明:
- LLM生成的指南 – 可能包含不准确之处
- Fizzy的代码示例根据O’Saasy许可证许可
- 不与37signals关联或认可 </credits>