Skip to content

Instantly share code, notes, and snippets.

@AstraL
Last active November 17, 2021 10:08
Show Gist options
  • Save AstraL/7e37a1e64564af048f363d6a1211123a to your computer and use it in GitHub Desktop.
Save AstraL/7e37a1e64564af048f363d6a1211123a to your computer and use it in GitHub Desktop.
require "active_job"
require "active_model"
class Flake < ActiveJob::Base
alias ActiveJob::Core#initialize before it is overwritten by ActiveModel::Model
alias active_job_initialize initialize
include ::ActiveModel::Model
include FlakeHelper
def self.execute(args = {})
new(args).execute
end
def self.execute_later(args = {})
options = {}
options[:wait] = args.delete(:wait) if args.key?(:wait)
# initialize ActiveJob::Core only when Flake is enqueued to prevent conflics with ActiveModel::Model
flake = new
flake.send(:active_job_initialize, args)
if queue_adapter.class.name.demodulize == "InlineAdapter"
flake.enqueue
else
flake.enqueue(options)
end
end
singleton_class.send(:alias_method, :perform_later, :execute_later)
def perform(args = {})
args.each { |key, value| instance_variable_set(:"@#{key}", value) }
execute
end
def execute(*)
raise NotImplementedError, "no `execute` method defined for #{self.class}"
end
def on_success(&callback)
@success = callback
self
end
def on_failure(&callback)
@failure = callback
self
end
private
def with_valid_params(&block)
if block_given? && valid?
ApplicationRecord.transaction(&block)
else
failure(errors)
end
end
def success(*args)
if args.size == 1 && args.first.respond_to?(:errors) && args.first.errors.present?
failure(args.first.errors)
else
@success ||= default_success
@success.call(*args)
args.first
end
end
def failure(*args)
@failure ||= default_failure
@failure.call(*args)
false
end
def default_success
proc { true }
end
def default_failure
proc do |args|
obj = args || self
raise(Flake::Error, obj.errors) if obj.respond_to?(:errors)
raise(Flake::Error, obj.errors) if obj.is_a?(ActiveModel::Errors)
raise(Flake::Error, obj.inspect)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment