rails-antipattern-anemic-domain-model
Installation
SKILL.md
Antipattern: Anemic Domain Model
The smell
- Models containing only validations, associations, and scopes — no verbs
app/services/full of*Service/*UseCaseclasses that orchestrate model attribute changes- "Where does X happen?" → "search
services/" - Tests stub the services rather than exercising the models
Why it hurts
- Behavior is hard to discover — readers have to know the service exists
- Conditional dispatch creeps into services because models can't answer questions about themselves
- Every new verb is a new class with
#call, plus a spec, plus wiring - Encourages procedural style; weakens domain reasoning
The fix
- Put behavior on the model. A
Postshould know how to publish itself - Extract a concern if the behavior has its own cluster of methods
- Extract a PORO named as a noun (
PostPublication) — but the entry point stays on the model - This is core to the 37signals/DHH style:
post.publish, notPublishPostService.call(post)