Stats
Actions
Tags
From superpowers
Use when creating or modifying Draper decorators in app/decorators
How this skill is triggered — by the user, by Claude, or both
Slash command
/superpowers:rails-decorator-conventionsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Conventions for Draper decorators in this project.
Conventions for Draper decorators in this project.
Automatically activates when working on:
app/decorators/**/*.rbUse this skill when:
Draper::Decorator - All decorators use Draperdelegate_all - Forward all model methods transparentlyh. - Use h.link_to, h.number_to_currency, etc.# app/decorators/bond_decorator.rb
class BondDecorator < Draper::Decorator
delegate_all
# Currency formatting
def formatted_amount
h.number_to_currency(amount)
end
# Status badge with Bootstrap classes
def status_badge
h.content_tag(:span, status.titleize, class: "badge badge-#{status_color}")
end
# Date formatting
def effective_date_display
effective_date.strftime("%B %d, %Y")
end
# Conditional display
def expiration_warning
return unless expires_soon?
h.content_tag(:span, "Expiring soon", class: "text-danger")
end
private
def status_color
case status
when "approved" then "success"
when "pending" then "warning"
when "declined" then "danger"
else "secondary"
end
end
end
def formatted_premium
h.number_to_currency(premium)
end
def status_badge
h.content_tag(:span, status.titleize, class: "badge badge-#{status_css_class}")
end
def created_display
created_at.strftime("%B %d, %Y")
end
def updated_ago
h.time_ago_in_words(updated_at) + " ago"
end
def cancellation_notice
return unless cancelled?
h.content_tag(:div, "This bond has been cancelled", class: "alert alert-danger")
end
# Controller - single record
@bond = Bond.find(params[:id]).decorate
# Controller - collection
@bonds = Bond.where(status: "active").decorate
# View (Haml)
%h2= @bond.status_badge
%p= @bond.formatted_amount
# View (ERB)
<h2><%= @bond.status_badge %></h2>
<p><%= @bond.formatted_amount %></p>
| Logic | Where | Example |
|---|---|---|
| Domain/business | Model | bond.approved?, bond.cancel! |
| Model-specific display | Decorator | bond.decorate.formatted_amount |
| Generic view utility | Helper | yes_no(value), external_link(url) |
Test decorators in spec/decorators/:
# spec/decorators/bond_decorator_spec.rb
RSpec.describe BondDecorator do
let(:bond) { create(:bond, amount: 50000, status: "approved").decorate }
describe "#formatted_amount" do
it "formats as currency" do
expect(bond.formatted_amount).to eq("$50,000.00")
end
end
describe "#status_badge" do
it "returns a success badge for approved bonds" do
expect(bond.status_badge).to include("badge-success")
expect(bond.status_badge).to include("Approved")
end
end
end
| Do | Don't |
|---|---|
delegate_all | Cherry-pick delegations |
h.number_to_currency(amount) | Format in view template |
| Presentation logic only | Business logic in decorator |
Test in spec/decorators/ | Skip decorator tests |
| Decorate in controller | Decorate in view |
delegate_all - Always delegate so all model methods remain accessibleh. prefix - View helpers must be accessed via h.npx claudepluginhub craigtreptow/superpowersCreates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.