mcpField
R
rails-refactorer

rails-refactorer

github.com/majesticlabs-dev开发5053 次安装7 周前更新
代码仓库

关于 rails-refactorer

rails-refactorer 是用于重构 Rails 应用的技能指南,结合 Rails 约定、Ruby 惯用写法和 Sandi Metz 规则。它也涵盖测试维护与生产环境迁移安全,并规定重构结果的报告格式。

主要功能

  1. 01变更前分析代码与测试
  2. 02遵循 Rails 控制器和模型约定
  3. 03应用 Sandi Metz 规则与 Ruby 惯用写法
  4. 04重构期间维护测试覆盖
  5. 05检查迁移安全性与可逆性
  6. 06报告变更、测试状态和警告

适用场景

  1. 01重构 Rails 控制器和模型
  2. 02拆分复杂的服务操作
  3. 03检查迁移的数据丢失与锁表风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/majesticlabs-dev/majestic-marketplace --skill rails-refactorer

安装后在 Claude Code 中输入/rails-refactorer确认已加载。

详细介绍

Rails 重构器

重构方法

1. 先分析,再修改

开始任何重构前:

  • 彻底阅读现有代码
  • 确认现有测试覆盖情况(spec/ 或 test/)
  • 了解代码的用途和上下文
  • 检查代码库中现有的模式
2. 遵循 Rails 约定

控制器:

  • 保持控制器精简(仅负责协调)
  • 使用 before_action 进行通用设置
  • 限制为 7 个 RESTful 操作;自定义操作应新建控制器
  • 使用强参数
# Before: Custom action
class MessagesController < ApplicationController
  def archive
    @message = Message.find(params[:id])
    @message.update(archived: true)
  end
end

# After: Dedicated controller
class Messages::ArchivesController < ApplicationController
  def create
    @message = Message.find(params[:message_id])
    @message.update(archived: true)
  end
end

模型:

  • 将业务逻辑放在模型中
  • 使用 concern 共享行为
  • 使用作用域处理常见查询
  • 使用语义明确的关联命名
# Before
belongs_to :user

# After
belongs_to :author, class_name: "User"

服务对象(适用时):

  • 用于复杂的多步骤操作
  • 用于涉及多个模型的操作
  • 保持单一职责
3. 遵循 Sandi Metz 规则
规则限制做法
类长度100 行拆分类
方法长度5 行拆分方法
参数数量最多 4 个使用参数对象
控制器对象1 个使用外观对象
4. 遵循 Ruby 惯用写法

优先使用:

# Guard clauses
return unless user.active?

# Semantic methods
items.any?
email.present?

# Symbol to proc
users.map(&:name)

# Hash shorthand (Ruby 3.x)
{ name:, email: }

避免使用:

# Nested conditionals
if user
  if user.active?
    # ...
  end
end

# Manual checks
items.length > 0
email != nil && email != ""
5. 保持测试覆盖
  • 在重构前后运行测试
  • 如果接口发生变化,则更新测试
  • 为拆分出的类/方法添加测试
  • 绝不破坏现有测试

迁移安全性

重构涉及迁移时,应检查其在生产环境中的安全性、数据保留情况和可逆性。

安全工具

推荐的 gem:

# Gemfile
gem "strong_migrations"      # Catches dangerous operations
gem "database_consistency"   # Validates model <-> DB constraints
gem "anchor_migrations"      # DDL lock timeout protection
可逆性
# PROBLEM: Irreversible migration
def change
  remove_column :users, :legacy_id
end

# SOLUTION: Explicit up/down with data preservation
def up
  execute "CREATE TABLE legacy_user_ids AS SELECT id, legacy_id FROM users"
  remove_column :users, :legacy_id
end

def down
  add_column :users, :legacy_id, :integer
  execute "UPDATE users SET legacy_id = (SELECT legacy_id FROM legacy_user_ids WHERE legacy_user_ids.id = users.id)"
end
安全的列操作
# PROBLEM: Adding NOT NULL locks table
add_column :users, :status, :string, null: false

# SOLUTION: Three-step migration
add_column :users, :status, :string
User.update_all(status: 'active')
change_column_null :users, :status, false
长时间运行的操作
# PROBLEM: Locks table during index creation
add_index :orders, :customer_id

# SOLUTION: Concurrent index (PostgreSQL)
disable_ddl_transaction!
add_index :orders, :customer_id, algorithm: :concurrently
数据丢失场景
操作风险安全替代方案
更改列类型截断添加新列、迁移数据,再删除旧列
删除列数据丢失先归档,再删除
重命名列应用出错添加列 + 回填数据 + 删除旧列
更改精度数据丢失仅扩大精度,绝不缩小
迁移审查清单
  • 迁移可逆,或明确实现了 down?
  • 破坏性更改前是否保留了数据?
  • 长时间运行的操作是否使用 algorithm: :concurrently?
  • 是否安全地添加了 NOT NULL(允许为空 -> 回填数据 -> 添加约束)?
  • strong_migrations 是否通过?
  • 是否为 DDL 配置了锁定超时?

输出格式

重构后,请提供:

  1. 摘要 - 重构了什么以及原因
  2. 更改 - 修改的文件及关键更改
  3. 测试状态 - 确认测试仍然通过
  4. 警告 - 潜在问题或需要后续处理的事项

评论

支持 Markdown