class Amoeba::Cloner

Attributes

new_object[R]
object_klass[R]
old_object[R]

Public Class Methods

new(object, options = {}) click to toggle source
# File lib/amoeba/cloner.rb, line 16
def initialize(object, options = {})
  @old_object = object
  @options    = options
  @object_klass = @old_object.class
  inherit_parent_settings
  @new_object = object.__send__(amoeba.dup_method)
end

Public Instance Methods

run() click to toggle source
# File lib/amoeba/cloner.rb, line 24
def run
  process_overrides
  apply if amoeba.enabled
  after_apply if amoeba.do_preproc
  @new_object
end

Private Instance Methods

after_apply() click to toggle source
# File lib/amoeba/cloner.rb, line 170
def after_apply
  process_null_fields
  process_coercions
  process_prefixes
  process_suffixes
  process_regexes
  process_customizations
end
apply() click to toggle source
# File lib/amoeba/cloner.rb, line 110
def apply
  apply_clones
  apply_associations
end
apply_associations() click to toggle source
# File lib/amoeba/cloner.rb, line 100
def apply_associations
  if amoeba.includes.present?
    follow_only_includes
  elsif amoeba.excludes.present?
    follow_all_except_excludes
  else
    follow_all
  end
end
apply_clones() click to toggle source
# File lib/amoeba/cloner.rb, line 58
def apply_clones
  amoeba.clones.each do |clone_field|
    exclude_clone_if_has_many_through(clone_field)
  end
end
exclude_clone_if_has_many_through(clone_field) click to toggle source
# File lib/amoeba/cloner.rb, line 64
def exclude_clone_if_has_many_through(clone_field)
  association = @object_klass.reflect_on_association(clone_field)

  # if this is a has many through and we're gonna deep
  # copy the child records, exclude the regular join
  # table from copying so we don't end up with the new
  # and old children on the copy
  return unless association.macro == :has_many ||
                association.is_a?(::ActiveRecord::Reflection::ThroughReflection)

  amoeba.exclude_association(association.options[:through])
end
follow_all() click to toggle source
# File lib/amoeba/cloner.rb, line 94
def follow_all
  @object_klass.reflections.each do |name, association|
    follow_association(name, association)
  end
end
follow_all_except_excludes() click to toggle source
# File lib/amoeba/cloner.rb, line 85
def follow_all_except_excludes
  @object_klass.reflections.each do |name, association|
    exclude = amoeba.excludes[name.to_sym]
    next if exclude && (exclude.blank? || @old_object.send(exclude[:if]))

    follow_association(name, association)
  end
end
follow_association(relation_name, association) click to toggle source
# File lib/amoeba/cloner.rb, line 115
def follow_association(relation_name, association)
  return unless amoeba.known_macros.include?(association.macro.to_sym)

  follow_klass = ::Amoeba::Macros.list[association.macro.to_sym]
  follow_klass&.new(self)&.follow(relation_name, association)
end
follow_only_includes() click to toggle source
# File lib/amoeba/cloner.rb, line 77
def follow_only_includes
  amoeba.includes.each do |include, options|
    next if options[:if] && !@old_object.send(options[:if])

    follow_association(include, @object_klass.reflect_on_association(include))
  end
end
inherit_parent_settings() click to toggle source
# File lib/amoeba/cloner.rb, line 51
def inherit_parent_settings
  return unless _parent_amoeba.inherit
  return unless %w[strict relaxed submissive].include?(parenting_style.to_s)

  __send__("inherit_#{parenting_style}_parent_settings".to_sym)
end
inherit_relaxed_parent_settings() click to toggle source
# File lib/amoeba/cloner.rb, line 41
def inherit_relaxed_parent_settings
  amoeba(&_parent_amoeba_settings)
end
inherit_strict_parent_settings() click to toggle source
# File lib/amoeba/cloner.rb, line 37
def inherit_strict_parent_settings
  fresh_amoeba(&_parent_amoeba_settings)
end
inherit_submissive_parent_settings() click to toggle source
# File lib/amoeba/cloner.rb, line 45
def inherit_submissive_parent_settings
  reset_amoeba(&_amoeba_settings)
  amoeba(&_parent_amoeba_settings)
  amoeba(&_amoeba_settings)
end
parenting_style() click to toggle source
# File lib/amoeba/cloner.rb, line 33
def parenting_style
  amoeba.upbringing || _parent_amoeba.parenting
end
process_coercions() click to toggle source
# File lib/amoeba/cloner.rb, line 135
def process_coercions
  # prepend any extra strings to indicate uniqueness of the new record(s)
  amoeba.coercions.each do |field, coercion|
    @new_object[field] = coercion.to_s
  end
end
process_customizations() click to toggle source
# File lib/amoeba/cloner.rb, line 163
def process_customizations
  # prepend any extra strings to indicate uniqueness of the new record(s)
  amoeba.customizations.each do |block|
    block.call(@old_object, @new_object)
  end
end
process_null_fields() click to toggle source
# File lib/amoeba/cloner.rb, line 128
def process_null_fields
  # nullify any fields the user has configured
  amoeba.null_fields.each do |field_key|
    @new_object[field_key] = nil
  end
end
process_overrides() click to toggle source
# File lib/amoeba/cloner.rb, line 122
def process_overrides
  amoeba.overrides.each do |block|
    block.call(@old_object, @new_object)
  end
end
process_prefixes() click to toggle source
# File lib/amoeba/cloner.rb, line 142
def process_prefixes
  # prepend any extra strings to indicate uniqueness of the new record(s)
  amoeba.prefixes.each do |field, prefix|
    @new_object[field] = "#{prefix}#{@new_object[field]}"
  end
end
process_regexes() click to toggle source
# File lib/amoeba/cloner.rb, line 156
def process_regexes
  # regex any fields that need changing
  amoeba.regexes.each do |field, action|
    @new_object[field].gsub!(action[:replace], action[:with])
  end
end
process_suffixes() click to toggle source
# File lib/amoeba/cloner.rb, line 149
def process_suffixes
  # postpend any extra strings to indicate uniqueness of the new record(s)
  amoeba.suffixes.each do |field, suffix|
    @new_object[field] = "#{@new_object[field]}#{suffix}"
  end
end