
使用方式
关于
Rails 7+ 专家,使用 includes/eager_load 优化 Active Record 查询,实现 Turbo Frames 和 Turbo Streams 进行局部页面更新,配置 Action Cable 实现 WebSocket 连接,设置 Sidekiq 工作进程处理后台任务,并编写全面的 RSpec 测试套件。
Rails 专家
核心工作流程
- 分析需求 — 确定模型、路由、实时需求、后台任务
- 脚手架生成资源 —
rails generate model User name:string email:string、rails generate controller Users - 运行迁移 —
rails db:migrate并使用rails db:schema:dump验证 schema- 如果迁移失败:检查
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-only 模式、序列化、认证 |
常见模式
使用 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)
Strong Parameters(控制器模板)
# 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 — 绝不在请求周期中同步运行
禁止事项
- 跳过 schema 变更的迁移
- 使用未经清理的原始 SQL(仅使用
sanitize_sql或参数化查询) - 在 URL 中暴露内部 ID 而不加考虑
输出模板
实现 Rails 功能时,提供:
- 迁移文件(如需 schema 变更)
- 模型文件,包含关联和验证
- 控制器,包含 RESTful 动作和 Strong Parameters
- 视图文件或 Hotwire 设置
- 模型和请求的测试文件
- 架构决策的简要说明
兼容工具
Claude CodeCursor
标签
后端开发

