其他
用 Rails 7+ 构建 Web 应用时,优化…
适用于 Rails 7+ 项目(Hotwire/Turbo、Action Cable、Sidekiq、RSpec)的功能实现、N+1 优化与后台任务配置。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 38/100 ×0.15
适用场景
用 Rails 7+ 构建 Web 应用特定
解决思路
- 先分析需求:确定需要哪些 model、路由、实时功能与后台任务。
- 用 `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` 回滚,修复后重试。
- 实现阶段:编写 controller、model,并接入 Hotwire。
- 验证阶段:`bundle exec rspec` 必须全部通过,`bundle exec rubocop` 检查代码风格。
- spec 失败时:查看错误输出,修复失败用例,用 `--format documentation` 重新运行以获取细节。
- 评审中发现 N+1 时:补上 `includes`/`eager_load` 后重新运行 spec。
- 优化阶段:审计 N+1 查询、补充缺失索引、增加缓存。
- 按上下文加载参考文档:Turbo Frames/Streams/Stimulus 读 `references/hotwire-turbo.md`;模型、关联、查询与性能读 `references/active-record.md`;Sidekiq、job 设计、队列与错误处理读 `references/background-jobs.md`;model/request/system spec 与 factory 读 `references/rspec-testing.md`;API-only 模式、序列化与认证读 `references/api-development.md`。
- 防 N+1:不要 `Post.all` 后逐个调用 `post.author.name`;改用 `Post.includes(:author).all` 预加载关联。
- 需要按关联字段过滤时,用 `Post.eager_load(:author).where(authors: { verified: true })` 强制生成 JOIN。
- Turbo Frame 局部更新:在 `app/views/posts/index.html.erb` 中用 `turbo_frame_tag "posts"` 包裹 `render @posts` 和「Load More」链接;在 `_post.html.erb` 中用 `turbo_frame_tag dom_id(post)` 包裹单条内容及其 Edit 链接。
- controller 中的分页写法:`@posts = Post.includes(:author).page(params[:page])`,并把 `@posts.next_page` 赋给 `@next_page` 供「加载更多」使用。
- Sidekiq worker 模板:继承 `ApplicationJob`,声明 `queue_as :default` 与 `sidekiq_options retry: 3, dead: false`。
- job 内按 id 查记录;捕获 `ActiveRecord::RecordNotFound`,用 `Rails.logger.warn` 记录后不要重新抛出(记录已不存在,重试无意义)。
- 从 controller 或 model 回调中用 `SendWelcomeEmailJob.perform_later(user.id)` 入队。
- controller 使用强参数:`before_action :set_post, only: %i[show edit update destroy]`,私有方法 `post_params` 用 `params.require(:post).permit(:title, :body, :published_at)`。
- create 成功时 `redirect_to @post, notice: "Post created."`,失败时 `render :new, status: :unprocessable_entity`。
- 对所有涉及关联的集合查询都使用 `includes`/`eager_load` 防止 N+1。
- 编写覆盖率超过 95% 的完整 spec。
- 把复杂业务逻辑抽成 service object,保持 controller 精简。
- 为所有出现在 `WHERE`、`ORDER BY`、`JOIN` 中的列建立数据库索引。
- 把慢操作交给 Sidekiq,绝不在请求周期内同步执行。
- 不要跳过 schema 变更对应的 migration。
- 不要使用未经转义的原始 SQL,只能用 `sanitize_sql` 或参数化查询。
- 不要在 URL 中不加考虑地暴露内部 ID。
- 交付时按模板输出:migration 文件(如需改 schema)、含关联与校验的 model、含 RESTful action 与强参数的 controller、view 或 Hotwire 配置、model 与 request spec 文件、简要的架构决策说明。
适用边界 · 注意事项
- 非 Rails 项目(如纯 Ruby、Sinatra、Hanami 或其他语言框架)不适用。
- Rails 6 及更早版本没有 Hotwire,Turbo Frames/Streams 相关做法不适用。
- 项目无需实时更新或后台任务时,不应强行引入 Action Cable/Sidekiq。