- Home
- Skills
- Kaakati
- Rails Enterprise Dev
- Service Object Patterns
service-object-patterns_skill
- Shell
6
GitHub Stars
1
Bundled Files
2 months ago
Catalog Refreshed
4 months ago
First Indexed
Readme & install
Copy the install command, review bundled files from the catalogue, and read any extended description pulled from the listing source.
Installation
Preview and clipboard use veilstrat where the catalogue uses aiagentskills.
npx veilstrat add skill kaakati/rails-enterprise-dev --skill service-object-patterns- SKILL.md7.1 KB
Overview
This skill is a complete guide to implementing Service Objects in Ruby on Rails applications. It provides patterns, directory layout, a base service class, ServiceResult handling, and checklist items to build predictable, testable business logic. Use it to refactor fat controllers/models and to design clear service interfaces for multi-step or external-facing operations.
How this skill works
The skill explains where to place business logic using a decision tree and prescribes a canonical app/services/ directory layout with namespaced managers. It supplies a minimal ApplicationService base, a recommended .call-only public interface, transaction handling for multi-step operations, and a ServiceResult wrapper to avoid leaking ActiveRecord or external errors. It also covers error strategies, dependency injection, and controller integration.
When to use it
- When business logic spans multiple models or responsibilities
- When an operation involves multiple steps or side effects that need transactions
- When orchestrating external APIs with retries and error handling
- When refactoring fat controllers or models to improve testability
- When designing a clear, single-entry public interface for application operations
Best practices
- Expose only .call as the public API; keep internals private
- Inject dependencies via constructor parameters rather than globals
- Wrap multi-step side effects in ActiveRecord transactions for all-or-nothing behavior
- Return a ServiceResult (success/failure) instead of raw framework exceptions
- Validate inputs early and fail fast with clear error messages
- Handle external API failures with retries/backoff and convert to ServiceResult
Example use cases
- OrdersManager::CreateOrder — build order, charge payment, reserve inventory in a transaction
- TasksManager::AssignCarrier — validate assignment, call shipping API, update task status
- BillingManager::ProcessPayment — call payment gateway with retries and wrap outcome
- NotificationsManager::SendSms — enqueue job and return result without leaking errors
- Integrations::Shipping::CreateLabel — isolate external API logic and circuit-breaker handling
FAQ
Prefer ServiceResult for operations that can fail so callers get a consistent success/failure interface. For simple commands that always succeed, returning a domain object is acceptable.
Where do I put simple CRUD logic?
Keep straightforward single-model CRUD in the model or controller. Use a Service Object when logic spans models, has multiple steps, or needs orchestration.