layered-rails

Layered Rails Architecture

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "layered-rails" with this command: npx skills add majesticlabs-dev/majestic-marketplace/majesticlabs-dev-majestic-marketplace-layered-rails

Layered Rails Architecture

Audience: Rails developers working on applications that have outgrown single-file patterns. Goal: Know which layer code belongs in, when to extract, and which existing skill handles the implementation.

Four-Layer Architecture

Presentation → Application → Domain → Infrastructure (HTTP/UI) (Orchestration) (Business) (Persistence/APIs)

Core rule: Lower layers MUST NOT depend on higher layers. Data flows top-to-bottom only.

Layer Responsibilities

Layer Owns Does NOT Own

Presentation HTTP concerns, params, rendering, channels, mailers Business logic, direct DB queries

Application Orchestration across models, authorization, form validation Persistence details, rendering

Domain Business rules, validations, associations, value objects HTTP context, request objects, Current.*

Infrastructure ActiveRecord, external APIs, file storage, caching Business rules, presentation

Common Layer Violations

Violation Why It's Wrong Fix

Current.user in model Domain depends on presentation context Pass user as explicit parameter

request param in service Application depends on presentation Extract needed values before calling service

Pricing calc in controller Business logic in presentation Move to model method or service

All logic in services, anemic models Domain layer is hollow Keep domain logic in models; services orchestrate

Model sends emails directly Domain depends on infrastructure side-effects Use callbacks only for data transforms; extract delivery

The Specification Test

Diagnostic for misplaced code:

  • List every responsibility the object handles

  • For each, ask: "Does this belong to this layer's primary concern?"

  • If NO → extract to the appropriate layer

Example: A User model that handles authentication, avatar processing, notification preferences, and activity logging.

  • Authentication → Domain (keep)

  • Avatar processing → Infrastructure (extract to service/job)

  • Notification preferences → Domain (keep as concern)

  • Activity logging → Infrastructure (extract to observer/event)

See references/extraction-signals.md for the full methodology.

Callback Scoring

Rate each callback 1-5. Extract anything scoring 1-2.

Score Type Example Action

5 Transformer before_validation :normalize_email

Keep

4 Normalizer before_save :strip_whitespace

Keep

4 Utility after_create :update_counter_cache

Keep

2 Observer after_save :notify_admin

Consider extracting

1 Operation after_create :send_welcome_email, :provision_account

Extract

Rule of thumb: If removing the callback would break the model's own data integrity → keep. If it triggers external side-effects → extract.

Pattern Selection

"Where should this code go?"

Situation Pattern Layer Skill

Complex multi-model form Form Object Presentation —

Request param filtering Filter Object Presentation —

View-specific formatting Presenter / ViewComponent Presentation viewcomponent-coder

Authorization rules Policy Object Application action-policy-coder

Business operation (one-time) Service / Interaction Application active-interaction-coder

Multi-model orchestration Service Object Application active-interaction-coder

State lifecycle management State Machine Domain aasm-coder

Complex reusable query Query Object Domain —

Immutable concept (Money, DateRange) Value Object Domain —

Shared model behavior Concern Domain —

Typed configuration Config Object Infrastructure anyway-config-coder

Domain events / audit trail Event Sourcing Infrastructure event-sourcing-coder

JSON-backed attributes Store Model Domain store-model-coder

Decision Tree

Is it about HTTP/params/rendering? YES → Presentation layer Multi-model form? → Form Object Filtering params? → Filter Object Formatting for view? → Presenter or ViewComponent NO ↓

Is it authorization? YES → Policy Object (action-policy-coder) NO ↓

Does it orchestrate multiple models/services? YES → Application layer One-time operation? → Service/Interaction (active-interaction-coder) Needs typed inputs? → ActiveInteraction (active-interaction-coder) NO ↓

Is it a business rule about a single model? YES → Domain layer (keep in model or concern) Has state transitions? → AASM (aasm-coder) Reusable query? → Query Object Immutable value? → Value Object NO ↓

Is it about persistence/external APIs/caching? YES → Infrastructure layer

Services as Waiting Rooms

app/services/ is a temporary staging area, not a permanent home.

  • Services that survive should eventually reveal the real abstraction they represent

  • If a service wraps a single model operation → it probably belongs in the model

  • If a service coordinates 3+ models → it's a legitimate orchestrator

  • If a service grows complex → look for Form Object, Policy, or Query Object hiding inside

Smell test: If app/services/ has 50+ files and no subdirectories, the waiting room has become permanent storage.

Extraction Signals

When to extract code from existing locations:

Signal Threshold Action

Method length

15 lines Extract method or object

External API call in model Any Extract to service/gateway

God object High churn × high complexity Decompose (see references/extraction-signals.md)

Spec exceeds layer concern Specification test fails Extract to appropriate layer

Callback score 1-2/5 Extract to service or event handler

Duplicated query logic 2+ locations Extract Query Object

Current.* in model Any usage Pass as explicit parameter

See references/extraction-signals.md for the complete methodology.

Model Organization

Recommended ordering within model files:

class Order < ApplicationRecord

1. Extensions/DSL (has_secure_password, acts_as_*)

2. Associations

3. Enums

4. Normalizations

5. Validations

6. Scopes

7. Callbacks (transformers/normalizers only — score 4-5)

8. Delegations

9. Public methods

10. Private methods

end

When Layered vs DHH Style

This skill complements dhh-coder , not replaces it.

Situation Use

Small/medium app, standard CRUD dhh-coder — keep it simple

Complex domain, multiple bounded contexts layered-rails — add structure

Authorization beyond simple checks action-policy-coder via layered guidance

Fat model with 500+ lines layered-rails extraction signals

Standard controller actions dhh-coder — 7 REST actions

Multi-step business operation active-interaction-coder via layered guidance

Default to simplicity. Reach for layered patterns only when complexity demands it.

Success Checklist

  • No reverse dependencies (lower layers don't reference higher)

  • Models don't access Current attributes

  • Services don't accept request/controller objects

  • Controllers contain only HTTP concerns

  • Domain logic lives in models, not leaked into services

  • All callbacks score 4+ (or extracted)

  • Concerns group by behavior, not by artifact type

  • Each abstraction belongs to exactly one layer

Cross-References

Need Skill

Authorization policies action-policy-coder

Typed business operations active-interaction-coder

State machines aasm-coder

Operations + state routing business-logic-coder

ViewComponents viewcomponent-coder

Typed configuration anyway-config-coder

Event sourcing / audit event-sourcing-coder

JSON attributes store-model-coder

Refactoring execution rails-refactorer

DHH-style simplicity dhh-coder

Pattern catalog details references/pattern-catalog.md

Extraction methodology references/extraction-signals.md

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

google-ads-strategy

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

viral-content

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

market-research

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

free-tool-arsenal

No summary provided by upstream source.

Repository SourceNeeds Review