Use when creating or refactoring Active Job background jobs. Applies Rails 8 conventions, Solid Queue patterns, error handling, retry strategies, and job design best practices.
View on GitHubmajesticlabs-dev/majestic-marketplace
majestic-rails
January 24, 2026
Select agents to install to:
npx add-skill https://github.com/majesticlabs-dev/majestic-marketplace/blob/main/plugins/majestic-rails/skills/active-job-coder/SKILL.md -a claude-code --skill active-job-coderInstallation paths:
.claude/skills/active-job-coder/# Active Job Coder
You are a senior Rails developer specializing in background job architecture. Your goal is to create well-designed, maintainable Active Job classes following Rails 8 conventions.
See [resources/active-job/patterns.md](resources/active-job/patterns.md) for Continuable patterns, testing examples, and logging.
## Job Design Principles
### 1. Single Responsibility
```ruby
# Good: Focused job
class SendWelcomeEmailJob < ApplicationJob
queue_as :default
def perform(user)
UserMailer.welcome(user).deliver_now
end
end
```
### 2. Pass IDs, Not Objects
```ruby
# Good: Pass identifiers
class ProcessOrderJob < ApplicationJob
def perform(order_id)
order = Order.find(order_id)
# Process order
end
end
```
### 3. Queue Configuration
```ruby
class CriticalNotificationJob < ApplicationJob
queue_as :critical
queue_with_priority 1 # Lower = higher priority
end
class ReportGenerationJob < ApplicationJob
queue_as :low_priority
queue_with_priority 50
end
```
## Error Handling & Retry Strategies
```ruby
class ExternalApiJob < ApplicationJob
queue_as :default
retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 5
retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
discard_on ActiveJob::DeserializationError
def perform(record_id)
record = Record.find(record_id)
ExternalApi.sync(record)
end
end
```
### Custom Error Handling
```ruby
class ImportantJob < ApplicationJob
rescue_from StandardError do |exception|
Rails.logger.error("Job failed: #{exception.message}")
ErrorNotifier.notify(exception, job: self.class.name)
raise # Re-raise to trigger retry
end
end
```
## Concurrency Control (Solid Queue)
```ruby
class ProcessUserDataJob < ApplicationJob
limits_concurrency key: ->(user_id) { user_id }, duration: 15.minutes
def perform(user_id)
user = User.find(user_id)
# Process user data safely
end
end
class ContactActionJob < ApplicationJob
limits_concurren