lib/clowne/adapters/base.rb
# frozen_string_literal: true
require "clowne/adapters/registry"
require "clowne/resolvers/init_as"
require "clowne/resolvers/nullify"
require "clowne/resolvers/finalize"
require "clowne/resolvers/after_persist"
require "clowne/resolvers/after_clone"
module Clowne
module Adapters
# ORM-independant adapter (just calls #dup).
# Works with nullify/finalize.
class Base
include Clowne::Adapters::Registry::Container
class << self
# Duplicate record and remember record <-> clone relationship in operation
# Can be overrided in special adapter
# +record+:: Instance of record (ActiveRecord or Sequel)
def dup_record(record)
record.dup.tap do |clone|
operation = operation_class.current
operation.add_mapping(record, clone)
end
end
# Operation class which using for cloning
# Can be overrided in special adapter
def operation_class
Clowne::Utils::Operation
end
end
# Using a plan make full duplicate of record
# +source+:: Instance of cloned object (ex: User.new(posts: posts))
# +plan+:: Array of Declarations
# +params+:: Custom params hash
def clone(source, plan, params: {})
declarations = plan.declarations
init_record = init_record(self.class.dup_record(source))
declarations.inject(init_record) do |record, (type, declaration)|
resolver_for(type).call(source, record, declaration, params: params, adapter: self)
end
end
def init_record(record)
# Override in custom adapters
record
end
end
end
end
Clowne::Adapters::Base.register_resolver(
:init_as,
Clowne::Resolvers::InitAs,
prepend: true
)
Clowne::Adapters::Base.register_resolver(
:nullify,
Clowne::Resolvers::Nullify
)
Clowne::Adapters::Base.register_resolver(
:finalize, Clowne::Resolvers::Finalize,
after: :nullify
)
Clowne::Adapters::Base.register_resolver(
:after_clone, Clowne::Resolvers::AfterClone,
after: :finalize
)
Clowne::Adapters::Base.register_resolver(
:after_persist, Clowne::Resolvers::AfterPersist,
after: :after_clone
)