Skip to content

Instantly share code, notes, and snippets.

@artofhuman
Last active September 23, 2016 13:04
Show Gist options
  • Save artofhuman/466727fd834ca26276779c2af0c321ea to your computer and use it in GitHub Desktop.
Save artofhuman/466727fd834ca26276779c2af0c321ea to your computer and use it in GitHub Desktop.
require 'pry'
require 'apress/clearance'
require 'apress/orders'
require 'active_record'
require 'active_support'
require 'combustion'
require 'interactor'
require 'tsort'
DO_NOT_REPLY = 'qq'
DO_NOT_REPLY_RETURN_PATH = 'qwert'
APP_NAME = HOST = 'test.dev'
CONF = abcs = YAML.load(ERB.new(File.read(File.expand_path("../spec/internal/config/database.yml", __FILE__))).result)
Combustion::Database.drop_database(abcs['test_orders'])
Combustion::Database.create_database(abcs['test_orders'])
Combustion.initialize! :active_record
class MergeService
extend ActiveModel::Callbacks
define_model_callbacks :merge, only: :around
class Operation
attr_reader :klass, :name
def initialize(name, klass, options)
@name, @klass, @options = name, klass, options
end
def before
@options[:before]
end
def after
@options[:after]
end
def call
@klass.call
end
end
class Collection < Array
include TSort
alias :tsort_each_node :each
def tsort_each_child(operation, &block)
select { |i| i.before == operation.name || i.name == operation.after }.each(&block)
end
end
def self.add(name, klass, opts = {})
opts[:after] ||= operations.last.name unless operations.empty? || operations.find { |i| i.name == opts[:before] }
operation = Operation.new(name, klass, opts)
if operation.klass.respond_to?(:connection)
around_merge operation.klass
operation.klass.class_eval do
def self.around_merge(_)
connection.transaction { yield }
end
end
end
@operations ||= Collection.new
@operations << operation
end
def self.operations
@operations || Collection.new
end
def call
::User.transaction do
run_callbacks :merge do
self.class.operations.tsort_each do |o|
o.call
end
end
end
end
end
class UserOperation
def self.call
p 'user call'
User.create!(email: '[email protected]', name: 'test', password: 'qwerty', password_confirmation: 'qwerty')
end
end
class OrderOperation
def self.connection
Apress::Orders::Order.connection
end
def self.call
p 'orders call'
folder = Apress::Orders::Folder.new(name: 'test', slug: 'test', company_id: 1)
order = Apress::Orders::Order.new(
company_id: 1,
user_id: 1,
folder_id: folder.id,
company_main_region_id: 1,
packet_id: 1,
order_type: Product.to_s
)
order.save(validate: false)
end
end
class AnotherOrderOperation
def self.connection
Apress::Orders::Order.connection
end
def self.call
p 'orders call'
folder = Apress::Orders::Folder.new(name: 'test', slug: 'test', company_id: 1)
order = Apress::Orders::Order.new(
company_id: 1,
user_id: 1,
folder_id: folder.id,
company_main_region_id: 1,
packet_id: 1,
order_type: Product.to_s
)
order.save(validate: false)
end
end
MergeService.add(:users, UserOperation)
MergeService.add(:orders_1, OrderOperation)
MergeService.add(:orders_2, AnotherOrderOperation, before: :users)
begin
MergeService.new.call
ensure
p User.last
p Apress::Orders::Order.last
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment