Module: Laters::Concern

Extended by:
ActiveSupport::Concern
Includes:
ActiveModel::Callbacks
Defined in:
lib/laters/concern.rb

Overview

Main concern that provides asynchronous execution of ActiveRecord model methods

This module adds the ability to defer execution of an instance method to a background job by calling a method with the ‘_later` suffix.

Examples:

class User < ActiveRecord::Base
  include Laters::Concern

  def send_welcome_email
    # Some long running task
  end
end

# Basic usage (executes in background)
user.send_welcome_email_later

# With scheduling options
user.send_welcome_email_later(wait: 5.minutes)
user.send_welcome_email_later(wait_until: 1.day.from_now)

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, **kwargs, &block) ⇒ ActiveJob::Base (private)

Handles method calls with _later suffix by enqueueing background jobs

Parameters:

  • method (Symbol)

    The method being called

  • args (Array)

    Arguments to pass to the method

  • kwargs (Hash)

    Keyword arguments to pass to the method Special kwargs for job scheduling are extracted: @option kwargs [Integer] :wait Time in seconds to wait before executing @option kwargs [Time] :wait_until Specific time to execute the job @option kwargs [Integer] :priority Priority for the job

  • block (Proc)

    Block to pass to the method (unused)

Returns:

  • (ActiveJob::Base)

    The enqueued job

Raises:

  • (NoMethodError)

    If the method doesn’t exist



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/laters/concern.rb', line 66

def method_missing(method, *args, **kwargs, &block)
  if (method_to_call = deferrable_method_name(method))
    # Extract ActiveJob options if they exist in kwargs
    job_options = { queue: self.class.job_queue || :default }
    
    # Move scheduling options from kwargs to job_options
    job_options[:wait] = kwargs.delete(:wait) if kwargs.key?(:wait)
    job_options[:wait_until] = kwargs.delete(:wait_until) if kwargs.key?(:wait_until)
    job_options[:priority] = kwargs.delete(:priority) if kwargs.key?(:priority)
    
    # Set all options at once
    InstanceMethodJob
      .set(job_options)
      .perform_later(self, method_to_call, *args, **kwargs)
  else
    super
  end
end