Learn-skills.dev rails-service-patterns
Rails service object patterns and business logic organization. Automatically invoked when working with service objects, extracting business logic, implementing command/query patterns, or organizing app/services. Triggers on "service object", "service", "business logic", "workflow", "orchestration", "command pattern", "query object", "form object", "interactor", "result object".
install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/ag0os/rails-dev-plugin/rails-service-patterns" ~/.claude/skills/neversight-learn-skills-dev-rails-service-patterns && rm -rf "$T"
manifest:
data/skills-md/ag0os/rails-dev-plugin/rails-service-patterns/SKILL.mdsource content
Rails Service Object Patterns
Patterns for extracting and organizing business logic in Rails applications.
When This Skill Applies
- Extracting complex logic from controllers/models into service objects
- Implementing command/query separation patterns
- Handling multi-step business processes
- Designing result objects and error handling
- Organizing the app/services directory
Core Principles
Single Responsibility
Each service should do one thing well:
- Name services with verb + noun:
,CreateOrder
,SendEmailProcessPayment - Keep services focused and composable
- One public method (typically
orcall
)perform
Dependency Injection
Make services testable and flexible:
class NotificationService def initialize(mailer: UserMailer, sms_client: TwilioClient.new) @mailer = mailer @sms_client = sms_client end end
Service Patterns
See patterns.md for detailed implementations of:
- Basic Service Pattern
- Result Object Pattern
- Form Objects
- Query Objects
- Policy Objects
Quick Reference
| Pattern | When to Use |
|---|---|
| Basic Service | Simple operations with transaction handling |
| Result Object | When callers need success/failure + data/error |
| Form Object | Complex forms spanning multiple models |
| Query Object | Complex ActiveRecord queries |
| Policy Object | Authorization logic (Pundit-style) |
Testing Services
RSpec.describe CreateOrder do let(:user) { create(:user) } let(:service) { described_class.new(user, cart_items) } describe '#call' do it 'creates an order' do expect { service.call }.to change { Order.count }.by(1) end context 'when payment fails' do before { allow(PaymentProcessor).to receive(:charge).and_raise(PaymentError) } it 'rolls back the transaction' do expect { service.call }.not_to change { Order.count } end end end end
Related Documentation
- patterns.md - Detailed service patterns with examples