Skip to content

Instantly share code, notes, and snippets.

@nicbet
Created June 27, 2022 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicbet/a51a84eeef0fc14486088a5f83fe2e62 to your computer and use it in GitHub Desktop.
Save nicbet/a51a84eeef0fc14486088a5f83fe2e62 to your computer and use it in GitHub Desktop.
Concern to run an ActiveJob using .with(), like `NotifyJob.with(recipient: "jamie@example.com").perform_now`
module Parameterized
extend ActiveSupport::Concern
# included do
# attr_accessor :params
# end
module ClassMethods
# Provide the parameters to the job in order to use them in the instance methods and callbacks.
#
# NotificationJob.with(inviter: person_a, invitee: person_b).perform_now
#
# See Parameterized documentation for full example.
def with(params)
Parameterized::Job.new(self, params)
end
end
class Job # :nodoc:
def initialize(job, params)
@job, @params = job, params
end
private
def method_missing(method_name, *args)
Parameterized::JobPerformance.new(@job, method_name, @params, *args)
end
ruby2_keywords(:method_missing)
def respond_to_missing?(method, include_all = false)
@job.respond_to?(method, include_all)
end
end
class JobPerformance < Delegator # :nodoc:
# rubocop:disable Lint/MissingSuper
def initialize(job_class, method, params, *args)
@job_class, @method, @params, @args = job_class, method, params, *args
@job = @job_class.new.tap do |job|
@params.each do |name, value|
job.instance_variable_set("@#{name}".to_sym, value)
end
# job.send(@method, *@args)
end
end
# rubocop:enable Lint/MissingSuper
ruby2_keywords(:initialize)
# Method calls are delegated to the Job that's ready to deliver.
def __getobj__ # :nodoc:
@job
end
# Unused except for delegator internals (dup, marshalling).
def __setobj__(job) # :nodoc:
@job = job
end
# Returns the resulting Job
def job
__getobj__
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment