Skills

Job Patterns

Implements shallow background jobs with _later/_now conventions using Solid Queue.

Install

npx skills add ThibautBaissac/rails_ai_agents --skill job-patterns -g -a claude-code -y
Category
Business
Updated
5mo ago
License
MIT
Context cost
Mediumabout 1,528 tokens
Runs scripts
No, instructions only

What it does

Implements shallow background jobs with _later/_now conventions using Solid Queue. Use when adding background processing, async operations, scheduled tasks, or when user mentions jobs, queues, workers, or background processing. WHEN NOT: Business logic implementation (use model-patterns), controller work (use crud-patterns), or mailer delivery (use mailer-patterns).

Job Patterns (37signals)

Jobs orchestrate. Models do the work. Background jobs are thin wrappers around model methods.

Project knowledge

Tech Stack: Rails 8.2 (edge), Solid Queue, ActiveJob Pattern: Thin jobs call model methods; models have _later/_now pairs

Commands:

bin/rails generate job NotifyRecipients        # Generate job
bundle exec rake solid_queue:start             # Run worker
bin/rails runner "puts SolidQueue::Job.count"  # Check queue
bin/rails runner "SolidQueue::Job.destroy_all" # Clear jobs

Why shallow jobs

  • Business logic stays in models (testable, reusable)
  • Jobs are simple orchestrators
  • Easy to run sync or async
  • Can call methods directly in tests
  • Clearer separation of concerns

Why _later/_now convention

  • Clear which version is async
  • Default method can be sync (explicit async)
  • Easy to switch between sync/async
  • Testable (call _now in tests)

Core pattern: shallow job

The job receives a model and calls its _now method. The _now suffix is conventional but not required -- some jobs call the plain method name (e.g., notifiable.notify_recipients).

# app/jobs/notify_recipients_job.rb
class NotifyRecipientsJob < ApplicationJob
  queue_as :default

  def perform(notifiable)
    notifiable.notify_recipients_now
  end
end

The model defines both _later and _now methods:

# In model or concern
def notify_recipients_later
  NotifyRecipientsJob.perform_later(self)
end

def notify_recipients_now
  recipients.each do |recipient|
    next if recipient == creator
    Notification.create!(recipient: recipient, notifiable: self, action: notification_action)
  end
end

# Default to sync
def notify_recipients
  notify_recipients_now
end

# Trigger async from callbacks
after_create_commit :notify_recipients_later

Job patterns

Notification job

class NotifyRecipientsJob < ApplicationJob
  queue_as :default
Read the whole SKILL.md on GitHub

More in Business