From superpowers
Use when creating or modifying Rails controllers, adding actions, setting up authorization, configuring routes, modeling state changes as resources, or handling Turbo responses
How this skill is triggered — by the user, by Claude, or both
Slash command
/superpowers:rails-controller-conventionsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Controllers are thin request handlers. They authorize, delegate to models, and respond — nothing more.
Controllers are thin request handlers. They authorize, delegate to models, and respond — nothing more.
authorize. No exceptionsrails-model-conventions)resource :closure not post :close. Create enables, destroy disablesEvery controller action MUST call authorize to enforce Pundit policies.
def create
@article = Article.new(article_params)
authorize @article # BEFORE performing the action
@article.save!
redirect_to @article
end
def index
authorize Article # Class, not instance
@articles = policy_scope(Article)
end
[:companies, resource] for namespaced policiesindex/new: authorize the class (no instance yet)# WRONG - reaching into associations
@bookmark = current_user.academy_bookmarks.find_by(academy: @academy)
# RIGHT - ask the object
@bookmark = current_user.bookmark_for(@academy)
See rails-model-conventions for the full pattern and model-side implementation.
State changes are CRUD on a nested resource, not custom actions. See rails-model-conventions for the concern side.
resources :cards do
resource :closure, only: %i[create destroy]
end
class ClosuresController < ApplicationController
def create
authorize @card, :close?
@card.close
# respond with turbo_stream
end
def destroy
authorize @card, :reopen?
@card.reopen
# respond with turbo_stream
end
end
Authorize against the parent record using intent-named policy methods. No state logic in the controller.
| Do | Don't |
|---|---|
resource :closure | post :close, :reopen |
authorize @resource in every action | Skip authorization |
user.bookmarked?(academy) | user.bookmarks.exists?(...) |
| Model methods for state | Inline association queries |
| Turbo Streams | JSON responses |
| 7 RESTful actions | Custom action proliferation |
authorizeRemember: Controllers authorize and delegate. Everything else belongs in models.
npx claudepluginhub pabloscolpino/superpowers-railsCreates 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.