writing-affordances

Extract PORO wrappers grouping 3+ related Rails model methods under a domain noun.

3|Updated Dec 25, 2025
One-click install
npx skills add https://github.com/ZempTime/zemptime-marketplace --skill writing-affordances
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: writing-affordances
Source: https://github.com/ZempTime/zemptime-marketplace/tree/main/vanilla-rails/skills/writing-affordances
Command: npx skills add https://github.com/ZempTime/zemptime-marketplace --skill writing-affordances

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Refactor fat Rails models by extracting PORO wrappers that group 3+ operations around a noun/concept, enabling a focused, reusable API.

Core Features & Use Cases

  • Affordance: cluster 3+ related methods under a single noun to expose a clean API.
  • PORO-based: extract operations into a plain Ruby object (PORO) for testability and reuse.
  • Entry Point Options: provide an explicit entry via a Concern or a direct PORO class, keeping the parent model lean.
  • Use Case: convert entropy_* prefixes into card.entropy.* affordances for clearer code.

Quick Start

  1. Identify a fat model with 3+ methods sharing a prefix (e.g., entropy_).
  2. Extract a PORO wrapper named after the noun (e.g., Entropy) and wire an entry method on the parent (e.g., entropy) that returns the PORO instance.
  3. Use the new affordance at call sites like card.entropy.auto_clean_at and card.entropy.days_before_reminder.

Frequently Asked Questions about writing-affordances

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I refactor fat Rails models with too many methods sharing a prefix?

Refactor fat Rails models by extracting PORO wrappers that group 3+ related methods under a domain noun. This creates a focused affordance API, keeping the parent model lean and converting clustered prefixes into clean calls like card.entropy.auto_clean_at.

What is an affordance pattern in Rails and when should I use it?

An affordance is a PORO wrapper that clusters 3+ methods coordinating multiple associations around a single noun. Use this pattern when methods share a prefix and form a cohesive API, ensuring focused domain logic and improved testability.

Can I use a Rails concern to wire up a PORO affordance class?

Yes, you can use an optional Rails concern to provide infrastructure and an explicit entry method for the PORO affordance class. The concern returns the PORO instance, keeping the parent model lean while exposing the domain noun API.

What is the best way to extract domain logic from a fat model into a PORO?

The best way to extract domain logic is identifying 3+ methods sharing a prefix, creating a PORO named after the concept, and wiring an entry method on the parent model. This affordance approach ensures reusable, testable operations separated from the fat model.

When should I not use a PORO affordance to refactor fat models?

You should not use a PORO affordance when fewer than 3 methods share a prefix or when the methods do not coordinate multiple associations to form a cohesive API. The pattern requires enough related operations to justify extracting a dedicated domain noun wrapper.