All skills
jeffallan avatar

/rails-expert

@efebc44
by jeffallanjeffallan/claude-skills12k stars
1,124

Rails 7+ specialist that optimizes Active Record queries with includes/eager_load, implements Turbo Frames and Turbo Streams for partial page updates, configures Action Cable for WebSocket connections, sets up Sidekiq workers for background job processing, and writes comprehensive RSpec test suites. Use when building Rails 7+ web applications with Hotwire, real-time features, or background job processing. Invoke for Active Record optimization, Turbo Frames/Streams, Action Cable, Sidekiq, RSpec Rails.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/rails-expert

This session only. Nothing lands on disk.

referencesbackground-jobs.md

≈1.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Background Jobs with Sidekiq

Sidekiq Setup

# Gemfile
gem 'sidekiq'
gem 'sidekiq-cron' # Optional: scheduled jobs

# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: ENV['REDIS_URL'] || 'redis://localhost:6379/0' }
end

Sidekiq.configure_client do |config|
  config.redis = { url: ENV['REDIS_URL'] || 'redis://localhost:6379/0' }
end

# config/sidekiq.yml
:concurrency: 5
:queues:
  - critical
  - default
  - low

Basic Job Design

# app/jobs/email_sender_job.rb
class EmailSenderJob < ApplicationJob
  queue_as :default

  def perform(user_id, email_type)
    user = User.find(user_id)
    UserMailer.send(email_type, user).deliver_now
  end
end

# Usage
EmailSenderJob.perform_later(user.id, :welcome)

# Perform at specific time
EmailSenderJob.set(wait: 1.hour).perform_later(user.id, :reminder)
EmailSenderJob.set(wait_until: Date.tomorrow.noon).perform_later(user.id, :digest)

Queue Priority

class CriticalJob < ApplicationJob
  queue_as :critical

  def perform
    # High priority work
  end
end

class ReportGenerationJob < ApplicationJob
  queue_as :low

  def perform
    # Can wait
  end
end

Retry Strategy

class ImportJob < ApplicationJob
  # Retry up to 5 times with exponential backoff
  sidekiq_options retry: 5

  # Custom retry logic
  sidekiq_retry_in do |count, exception|
    case exception
    when NetworkError
      10 * (count + 1) # 10, 20, 30 seconds
    when RateLimitError
      1.hour
    else
      :default # Use Sidekiq's default exponential backoff
    end
  end

  def perform(data_url)
    # Import logic
  end
end

Error Handling

class ProcessPaymentJob < ApplicationJob
  sidekiq_options retry: 3

  # Called when job fails after all retries
  sidekiq_retries_exhausted do |msg, exception|
    Rails.logger.error("Payment job failed: #{msg}")

    # Notify admin
    AdminMailer.job_failed(msg, exception).deliver_now

    # Store failure record
    FailedPayment.create(
      user_id: msg['args'][0],
      error: exception.message
    )
  end

  def perform(user_id, amount)
    user = User.find(user_id)
    PaymentProcessor.charge(user, amount)
  rescue PaymentError => e
    # Log and re-raise to trigger retry
    Rails.logger.warn("Payment failed: #{e.message}")
    raise
  end
end

Batch Processing

class BulkEmailJob < ApplicationJob
  def perform(user_ids)
    # Process in batches to avoid memory issues
    user_ids.in_groups_of(100, false) do |batch|
      batch.each do |user_id|
        user = User.find(user_id)
        UserMailer.newsletter(user).deliver_now
      end
    end
  end
end

# Better: Use Sidekiq::Batch (requires sidekiq-pro)
class ParentJob < ApplicationJob
  def perform(user_ids)
    batch = Sidekiq::Batch.new
    batch.on(:success, self.class, 'user_ids' => user_ids)

    batch.jobs do
      user_ids.each do |user_id|
        ChildJob.perform_later(user_id)
      end
    end
  end

  def on_success(status, options)
    # All child jobs completed
    Rails.logger.info("Processed #{options['user_ids'].length} users")
  end
end

Scheduled Jobs

# Using sidekiq-cron
# config/initializers/sidekiq.rb
schedule_file = "config/schedule.yml"

if File.exist?(schedule_file) && Sidekiq.server?
  Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end

# config/schedule.yml
daily_report:
  cron: "0 6 * * *"
  class: "DailyReportJob"
  queue: default

cleanup_old_records:
  cron: "0 2 * * 0" # Sunday at 2am
  class: "CleanupJob"
  queue: low

Job Patterns

Idempotent jobs:

class ProcessOrderJob < ApplicationJob
  def perform(order_id)
    order = Order.find(order_id)

    # Check if already processed
    return if order.processed?

    # Process order
    order.process!
  end
end

Unique jobs (requires sidekiq-unique-jobs gem):

class GenerateReportJob < ApplicationJob
  sidekiq_options lock: :until_executed,
                   on_conflict: :log

  def perform(user_id, report_type)
    # Only one instance of this job per user+report_type
  end
end

Testing

# spec/jobs/email_sender_job_spec.rb
require 'rails_helper'

RSpec.describe EmailSenderJob, type: :job do
  let(:user) { create(:user) }

  describe "#perform" do
    it "sends welcome email" do
      expect {
        described_class.perform_now(user.id, :welcome)
      }.to change { ActionMailer::Base.deliveries.count }.by(1)
    end

    it "enqueues job" do
      expect {
        described_class.perform_later(user.id, :welcome)
      }.to have_enqueued_job(described_class)
        .with(user.id, :welcome)
        .on_queue("default")
    end
  end
end

# Test inline in development
# config/environments/test.rb
config.active_job.queue_adapter = :inline

Monitoring

# Check queue size
Sidekiq::Queue.new("default").size

# Check scheduled jobs
Sidekiq::ScheduledSet.new.size

# Check retry set
Sidekiq::RetrySet.new.size

# Check dead jobs
Sidekiq::DeadSet.new.size

# Clear queues (use with caution)
Sidekiq::Queue.new("default").clear

Performance Tips

  • Keep jobs small and focused
  • Pass IDs, not objects (serialize/deserialize issue)
  • Use appropriate queue priorities
  • Set realistic retry limits
  • Monitor queue depth and latency
  • Scale workers based on load
  • Use Redis persistence for job durability
  • Consider job uniqueness to prevent duplicates

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub16d

    The skill provides specialist guidance for Rails 7 development, including Active Record optimization, Hotwire integration, and API design. Automated security scans flagged the author's documentation URL and the skill manifest as malicious, likely due to standard development code snippets and GitHub Pages reputation. Manual analysis confirms these are legitimate vendor resources and development templates. The skill includes strong safety guidelines, such as mandatory SQL sanitization, to promote secure coding.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    6 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at efebc44. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 5 months ago
Other metadata
metadata
{
  "author": "https://github.com/Jeffallan",
  "version": "1.1.0",
  "domain": "backend",
  "triggers": "Rails, Ruby on Rails, Hotwire, Turbo Frames, Turbo Streams, Action Cable, Active Record, Sidekiq, RSpec Rails",
  "role": "specialist",
  "scope": "implementation",
  "output-format": "code",
  "related-skills": "fullstack-guardian, database-optimizer"
}

README badge

README badge for jeffallan/claude-skills/rails-expert