class Cloned::Base

Attributes

strategy[RW]
copy[R]
destination[R]
options[R]
target[R]

Public Class Methods

new(target:, destination: nil, **options) click to toggle source
# File lib/cloned/base.rb, line 8
def initialize(target:, destination: nil, **options)
  @target = target
  @destination = destination
  @options = options
end

Public Instance Methods

make() click to toggle source
# File lib/cloned/base.rb, line 14
def make
  if skip_transaction?
    make_or_fail!
  else
    ActiveRecord::Base.transaction { make_or_fail! }
  end
  copy
end
valid?() click to toggle source
# File lib/cloned/base.rb, line 23
def valid?
  target.presence
end

Protected Instance Methods

force?() click to toggle source
# File lib/cloned/base.rb, line 33
def force?
  options[:force].presence
end
optional_after(clon) click to toggle source
# File lib/cloned/base.rb, line 41
def optional_after(clon)
  options[:after].call(clon) if options.key?(:after)
end
optional_before(clon) click to toggle source
# File lib/cloned/base.rb, line 37
def optional_before(clon)
  options[:before].call(clon) if options.key?(:before)
end
skip_transaction?() click to toggle source
# File lib/cloned/base.rb, line 29
def skip_transaction?
  options[:skip_transaction]
end

Private Instance Methods

after(clon) click to toggle source
# File lib/cloned/base.rb, line 85
def after(clon)
  optional_after(clon)
  declared_after(clon) if respond_to?(:declared_after)
end
before(clon) click to toggle source
# File lib/cloned/base.rb, line 80
def before(clon)
  optional_before(clon)
  declared_before(clon) if respond_to?(:declared_before)
end
clearing_attributes() click to toggle source
# File lib/cloned/base.rb, line 76
def clearing_attributes
  []
end
copy_association(target_association:, destination:, **options) click to toggle source
# File lib/cloned/base.rb, line 55
def copy_association(target_association:, destination:, **options)
  if target_association.respond_to?(:proxy_association)
    copier = strategy.find_copier(target_association.proxy_association.klass)
    target_association.each do |target_item|
      copier.new(target: target_item, destination: destination, **options.merge(skip_transaction: true)).make
    end
  else
    copier = strategy.find_copier(target_association.class)
    copier.new(target: target_association, destination: destination, **options.merge(skip_transaction: true)).make
  end
end
copy_associations(clon) click to toggle source
# File lib/cloned/base.rb, line 67
def copy_associations(clon)
  self.class.associations.each do |association_id, options|
    copy_association(
      target_association: target.public_send(association_id),
      destination: DestinationProxy.new(clon, association_id),
      **options)
  end
end
make_copy(target:, destination:) click to toggle source
# File lib/cloned/base.rb, line 106
def make_copy(target:, destination:)
  clon = prepare(target.dup)
  before(clon)
  destination.concat(clon) unless destination.nil?
  copy_associations(clon)
  after(clon)
  clon
end
make_or_fail!() click to toggle source
# File lib/cloned/base.rb, line 99
def make_or_fail!
  validate!
  return if options.key?(:if) && !options[:if].call(target)
  @copy = make_copy(target: target, destination: destination)
  @copy.save! if force?
end
prepare(clon) click to toggle source
# File lib/cloned/base.rb, line 90
def prepare(clon)
  clon.assign_attributes(Hash[clearing_attributes.map { |k| [k, nil] }])
  clon
end
validate!() click to toggle source
# File lib/cloned/base.rb, line 95
def validate!
  raise 'Cloning context not valid!' unless valid?
end