Back to Skills

vanilla-rails-naming

verified

Use when naming classes, methods, routes in vanilla Rails codebases - fixes concern verb/noun confusion, bang method misuse, custom action anti-patterns

View on GitHub

Marketplace

zemptime-marketplace

ZempTime/zemptime-marketplace

Plugin

vanilla-rails

Repository

ZempTime/zemptime-marketplace
1stars

vanilla-rails/skills/naming/SKILL.md

Last Verified

January 20, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/ZempTime/zemptime-marketplace/blob/main/vanilla-rails/skills/naming/SKILL.md -a claude-code --skill vanilla-rails-naming

Installation paths:

Claude
.claude/skills/vanilla-rails-naming/
Powered by add-skill CLI

Instructions

# Vanilla Rails Naming

37signals naming patterns from production Basecamp codebases (Fizzy, HEY, Basecamp).

**Scope:** These are 37signals-specific conventions. They differ from generic Rails guides and may contradict advice from other sources. When in doubt, follow these patterns for vanilla Rails codebases.

## Core Pattern: State as Resource

State changes (pin, close, assign) become **resources**, not actions:

```ruby
# ❌ WRONG - Custom actions
resources :cards do
  member do
    post :pin
    post :close
  end
end

# ✓ RIGHT - Singular resources
resources :cards do
  resource :pin      # POST=create, DELETE=destroy
  resource :closure  # POST=close, DELETE=reopen
end
```

This creates the naming cascade:
- Concern: `Closeable` (adjective)
- Model: `Closure` (noun)
- Controller: `ClosuresController` (plural of noun)
- Routes: `resource :closure` (singular)

## Quick Reference

| Type | Pattern | Example | ❌ Wrong |
|------|---------|---------|----------|
| **Concern** | Adjective (-able/-ible ONLY) | `Pinnable`, `Closeable`, `Assignable` | `Pinning`, `Pinnish`, `Pinlike`, `PinManager` |
| **State Model** | Noun | `Pin`, `Closure`, `Assignment` | `CardPin`, `CloseRecord` |
| **State Method** | Plain verb (no !) | `card.close`, `card.pin` | `card.close!`, `card.pin!` |
| **Async Enqueue** | `*_later` | `notify_watchers_later` | `notify_watchers_async` |
| **Sync Execute** | Plain or `*_now` | `notify_watchers` or `notify_watchers_now` | - |
| **Controller** | Plural noun | `PinsController`, `ClosuresController` | `PinController` (singular) |
| **Routes** | `resource` (singular) | `resource :closure` | `post :close` |

## Common Violations

### ❌ Violation 1: Verb/Noun Concerns
**Rationalization:** "It describes the behavior being added"

```ruby
# ❌ WRONG - Verb/noun/other adjective forms
module Card::Pinning      # verb -ing
module Card::PinManager   # Manager/Handler/Logic
module Card::Pinnish      # wrong adjective form

# ✓ RIGHT - Adjective with -able/-ibl

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
6587 chars

Issues Found:

  • name_directory_mismatch