CtrlK
BlogDocsLog inGet started
Tessl Logo

ddd-rails-modeling

Use when modeling Domain-Driven Design concepts in a Ruby on Rails codebase. Covers Rails-first mapping of entities, aggregates, value objects, domain services, application services, repositories, and domain events without over-engineering or fighting Rails conventions.

88

Quality

85%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

SKILL.md
Quality
Evals
Security

DDD Rails Modeling

Use this skill when the domain concepts are clear enough that the next question is how to model them in Rails.

Core principle: Model real domain pressure, not textbook DDD vocabulary.

Quick Reference

ConceptRails-first default
EntityActiveRecord model when persisted identity matters
Value objectPlain Ruby object near the domain it supports
Aggregate rootThe main entry point that guards invariants
Domain servicePORO for business behavior that does not belong to one entity
Application serviceOrchestrator in app/services coordinating a use case
RepositoryUse only for a real boundary beyond normal ActiveRecord usage
Domain eventExplicit object only when multiple downstream consumers justify it

HARD-GATE

DO NOT introduce repositories, aggregates, or domain events just to sound "DDD".
DO NOT fight Rails defaults when a normal model or service expresses the domain clearly.
ALWAYS start from domain invariants, ownership, and lifecycle before choosing a pattern.

When to Use

  • A Rails feature has clear domain language but unclear modeling choices.
  • The user asks whether something should be a model, value object, service, repository, or event.
  • A bounded context is clear and needs tactical design in Rails.
  • Next step: Chain to generate-tasks for implementation planning, or to rails-tdd-slices once the first behavior to test is clear.

Modeling Order

  1. List domain concepts: Entities, values, policies, workflows, and events from the ubiquitous language.
  2. Identify invariants: Decide which object or boundary must keep each rule true.
  3. Choose the aggregate entry point: Name the object that should guard state transitions and consistency.
  4. Place behavior: Keep behavior on the entity/aggregate when cohesive; extract a domain service only when behavior spans multiple concepts cleanly.
  5. Pick Rails homes: Choose the simplest location that matches the boundary and repo conventions.
  6. Verify with tests: Hand off to rails-tdd-slices and rspec-best-practices before implementation.

Rails-First Mapping

NeedPreferAvoid by default
Persisted concept with identityActiveRecord modelExtra wrapper object with no added meaning
Small immutable calculation or policy valuePORO value objectShoving all logic into helpers or primitives
Use-case orchestrationApplication service in app/servicesFat controller or callback chains
Cross-entity business ruleDomain servicePicking an arbitrary model just to hold the code
Complex query / persistence abstractionRepository only if boundary is realCreating repositories for every query
Multi-consumer business signalExplicit domain eventCallback-driven hidden side effects

Suggested Rails Homes

Modeling choiceTypical home
Aggregate / entityapp/models/...
Application or domain serviceapp/services/...
Value objectapp/models/... or nearby PORO location used by the repo
Policy / rule objectapp/services/..., app/policies/..., or project convention
Domain event objectapp/events/... or project-specific namespace if the repo already uses events

Output Style

When using this skill, return:

  1. Domain concept
  2. Recommended modeling choice
  3. Suggested Rails home
  4. Invariant or ownership reason
  5. Patterns to avoid
  6. Next skill to chain

Examples

Good: Value Object

# Money or ReservationWindow carries behavior and invariants
# but does not need its own database identity.
  • Modeling choice: Value object
  • Suggested home: PORO near the domain it supports

Good: Application Service

# Orders::CreateOrder coordinates inventory, pricing, persistence,
# and follow-up side effects for one use case.
  • Modeling choice: Application service
  • Suggested home: app/services/orders/create_order.rb

Bad: Cargo-Cult DDD

# Bad move:
# Add repositories, command handlers, and domain events
# when a normal model + service already expresses the use case cleanly.

Common Mistakes

MistakeReality
Turning every concept into a serviceMany behaviors belong naturally on entities or value objects
Creating repositories for all reads and writesActiveRecord already gives a strong default persistence boundary
Treating aggregates as folder names onlyAggregates exist to protect invariants, not to look architectural
Adding domain events for one local callbackEvents should justify their coordination cost
Forgetting Rails conventions entirelyDDD should sharpen Rails design, not replace it wholesale

Red Flags

  • Pattern choice is justified only with "DDD says so"
  • The same invariant is enforced from several unrelated entry points
  • New abstractions increase indirection without clarifying ownership
  • Primitive obsession still exists, but modeling is focused on folders instead of concepts

Integration

SkillWhen to chain
ddd-ubiquitous-languageWhen the terms are not clear enough to model yet
ddd-boundaries-reviewWhen the modeling problem is really a context boundary problem
generate-tasksAfter the tactical design is clear and ready for implementation planning
rails-tdd-slicesWhen the next step is choosing the best first failing spec
rails-code-conventionsWhen validating the modeling choice against Rails simplicity and repo conventions
Repository
igmarin/rails-agent-skills
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.