
A Claude Code plugin that refines Ruby on Rails code following **37signals patterns** and the **One Person Framework** philosophy. Transform complex code into clean, maintainable Rails conventions.

---

## What Is This?

A Claude Code skill that:

- **Simplifies** service objects into rich model methods and concerns
- **Converts** custom controller actions to CRUD resources
- **Transforms** boolean state columns into state records
- **Optimizes** fat controllers into thin controllers with model methods
- **Applies** Rails best practices like I18n, `Time.current`, and eager loading
- **Detects** N+1 queries and suggests fixes

---

## Philosophy

### The One Person Framework

From DHH (December 2021):

> "A toolkit so powerful that it allows a single individual to create modern applications upon which they might build a competitive business."

### Conceptual Compression

From RailsConf 2018:

> "Like a video codec that throws away irrelevant details such that you might download the film in real-time."

### Vanilla Rails is Plenty

From Jorge Manrubia at 37signals:

> "If you have the luxury of starting a new Rails app today, go vanilla."

---

## Quick Start

### 1. Add the Marketplace

```bash
/plugin marketplace add maquina-app/rails-claude-code
```

### 2. Install the Plugin

```bash
/plugin install rails-simplifier@maquina
```

### 3. Start Simplifying

```
> Review recent changes using the rails-simplifier skill
```

---

## What It Simplifies

| Pattern | Simplification |
|---------|---------------|
| Service objects | Rich model methods + concerns |
| Custom controller actions | CRUD resources |
| Boolean state columns | State records (`has_one :closure`) |
| Fat controllers | Thin controllers, model methods |
| `Time.now` | `Time.current` |
| Hardcoded strings | I18n keys |
| N+1 queries | `includes` / `preload` |
| Date tests without `travel_to` | Freeze time to fixture |

---

## Usage Examples

### Review Recent Changes

```
> Review recent changes using the rails-simplifier skill
```

The skill analyzes your recent commits and suggests simplifications based on 37signals patterns.

### Review a Specific Controller

```
> Use rails-simplifier to review the bookings controller
```

### Review a Model

```
> Use rails-simplifier to review the Order model
```

### Full Project Review

```
> Run rails-simplifier on the app directory
```

---

## Simplification Patterns

### Service Objects to Model Methods

**Before:**

```ruby
# app/services/order_processor.rb
class OrderProcessor
  def initialize(order)
    @order = order
  end

  def process
    @order.update(processed_at: Time.current)
    @order.line_items.each(&:fulfill)
    OrderMailer.confirmation(@order).deliver_later
  end
end

# In controller
OrderProcessor.new(@order).process
```

**After:**

```ruby
# app/models/order.rb
class Order < ApplicationRecord
  def process!
    update(processed_at: Time.current)
    line_items.each(&:fulfill)
    OrderMailer.confirmation(self).deliver_later
  end
end

# In controller
@order.process!
```

### Boolean States to State Records

**Before:**

```ruby
class Post < ApplicationRecord
  scope :published, -> { where(published: true) }
  scope :draft, -> { where(published: false) }
end
```

**After:**

```ruby
class Post < ApplicationRecord
  has_one :publication

  scope :published, -> { joins(:publication) }
  scope :draft, -> { where.missing(:publication) }

  def publish!
    create_publication!
  end

  def unpublish!
    publication&.destroy
  end
end
```

### Custom Actions to CRUD

**Before:**

```ruby
# config/routes.rb
resources :posts do
  member do
    post :publish
    post :unpublish
    post :archive
  end
end

# app/controllers/posts_controller.rb
def publish
  @post.update(published: true)
  redirect_to @post
end
```

**After:**

```ruby
# config/routes.rb
resources :posts do
  resource :publication, only: [:create, :destroy]
  resource :archival, only: [:create, :destroy]
end

# app/controllers/publications_controller.rb
class PublicationsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @post.create_publication!
    redirect_to @post
  end

  def destroy
    @post = Post.find(params[:post_id])
    @post.publication.destroy
    redirect_to @post
  end
end
```

### N+1 Query Detection

**Before:**

```ruby
def index
  @posts = Post.all
end

# In view: @posts.each { |post| post.author.name }
```

**After:**

```ruby
def index
  @posts = Post.includes(:author)
end
```

---

## Team Installation

Add to your project's `.claude/settings.json`:

```json
{
  "extraKnownMarketplaces": {
    "maquina": {
      "source": {
        "source": "github",
        "repo": "maquina-app/rails-claude-code"
      }
    }
  },
  "enabledPlugins": [
    "rails-simplifier@maquina"
  ]
}
```

---

## Resources

- [37signals Rails Patterns](https://gist.github.com/marckohlbrugge/d363fb90c89f71bd0c816d24d7642aca) — Collection of patterns from 37signals
- [Jorge Manrubia's Blog](https://world.hey.com/jorge) — Rails architecture insights
- [Rails Doctrine](https://rubyonrails.org/doctrine) — The philosophy behind Rails

---

## Next Steps

<div class="not-prose mt-8 grid grid-cols-1 gap-4 sm:grid-cols-2">
  <a href="https://github.com/maquina-app/rails-claude-code" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      GitHub Repository
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      View source code and contribute.
    </p>
  </a>

  <a href="/documentation/ai-tools/rails-mcp-server/" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      Rails MCP Server
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Enhance analysis with MCP tools.
    </p>
  </a>
</div>
