mcpField
R
rails-refactorer

rails-refactorer

github.com/majesticlabs-devDevelopment5053 installsUpdated 7w ago
Repository

About rails-refactorer

rails-refactorer is a skill guide for refactoring Rails applications using Rails conventions, Ruby idioms, and Sandi Metz rules. It also covers test maintenance and production-safe database migrations, with a defined summary and status format for reporting changes.

Key features

  1. 01Analyze code and tests before changes
  2. 02Apply Rails controller and model conventions
  3. 03Use Sandi Metz rules and Ruby idioms
  4. 04Maintain test coverage during refactoring
  5. 05Review migration safety and reversibility
  6. 06Report changes, test status, and warnings

Use cases

  1. 01Refactoring Rails controllers and models
  2. 02Breaking down complex service operations
  3. 03Reviewing migrations for data loss and locking risks

Install

Copy the command and run it in a terminal.

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

After installing, type/rails-refactorerin Claude Code to confirm it loaded.

Details

From the project README

Rails Refactorer

Refactoring Approach

1. Analyze Before Changing

Before any refactoring:

  • Read the existing code thoroughly
  • Identify existing test coverage (spec/ or test/)
  • Understand the code's purpose and context
  • Check for existing patterns in the codebase
2. Apply Rails Conventions

Controllers:

  • Keep controllers thin (orchestration only)
  • Use before_action for common setup
  • Limit to 7 RESTful actions; create new controllers for custom actions
  • Use strong parameters
# 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

Models:

  • Keep business logic in models
  • Use concerns for shared behavior
  • Use scopes for common queries
  • Semantic association naming
# Before
belongs_to :user

# After
belongs_to :author, class_name: "User"

Service Objects (when appropriate):

  • Use for complex multi-step operations
  • Use for operations spanning multiple models
  • Keep them single-purpose
3. Apply Sandi Metz Rules
RuleLimitAction
Class length100 linesExtract classes
Method length5 linesExtract methods
Parameters4 maxUse parameter objects
Controller objects1Use facades
4. Idiomatic Ruby

Prefer:

# 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: }

Avoid:

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

# Manual checks
items.length > 0
email != nil && email != ""
5. Maintain Test Coverage
  • Run tests before and after refactoring
  • Update tests if interfaces change
  • Add tests for extracted classes/methods
  • Never break existing tests

Migration Safety

When refactoring involves migrations, review for production safety, data preservation, and reversibility.

Safety Tools

Recommended gems:

# Gemfile
gem "strong_migrations"      # Catches dangerous operations
gem "database_consistency"   # Validates model <-> DB constraints
gem "anchor_migrations"      # DDL lock timeout protection
Reversibility
# 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
Safe Column Operations
# 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
Long-Running Operations
# 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
Data Loss Scenarios
OperationRiskSafe Alternative
Change column typeTruncationAdd new column, migrate, drop old
Remove columnData lossArchive first, then remove
Rename columnApp errorsAdd + backfill + remove
Change precisionData lossExpand only, never contract
Migration Review Checklist
  • Migration reversible or has explicit down?
  • Data preserved before destructive changes?
  • Long-running ops use algorithm: :concurrently?
  • NOT NULL added safely (nullable -> backfill -> constrain)?
  • strong_migrations passing?
  • Lock timeouts configured for DDL?

Output Format

After refactoring, provide:

  1. Summary - What was refactored and why
  2. Changes - Files modified with key changes
  3. Test Status - Confirmation tests still pass
  4. Warnings - Any potential issues or follow-up needed

Comments

Markdown supported