Module: DeepCloning

Defined in:
lib/deep_cloning.rb

Overview

DeepCloning

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

:nodoc:



4
5
6
# File 'lib/deep_cloning.rb', line 4

def self.included(base) #:nodoc:
  base.alias_method_chain :dup, :deep_cloning
end

Instance Method Details

#dup_with_deep_cloning(options = {}) ⇒ Object

dups an ActiveRecord model. if passed the :include option, it will deep dup the given associations if passed the :except option, it won’t dup the given attributes

Usage:

Cloning a model without an attribute

pirate.dup :except => :name

Cloning a model without multiple attributes

pirate.dup :except => [:name, :nick_name]

Cloning one single association

pirate.dup :include => :mateys

Cloning multiple associations

pirate.dup :include => [:mateys, :treasures]

Cloning really deep

pirate.dup :include => {:treasures => :gold_pieces}

Cloning really deep with multiple associations

pirate.dup :include => [:mateys, {:treasures => :gold_pieces}]


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/deep_cloning.rb', line 31

def dup_with_deep_cloning options = {}
  kopy = dup_without_deep_cloning()
  
  if options[:except]
    Array(options[:except]).each do |attribute|
      kopy.send("#{attribute}=", self.class.column_defaults[attribute.to_s])
    end
  end
  
  if options[:include]
    Array(options[:include]).each do |association, deep_associations|
      if (association.kind_of? Hash)
        deep_associations = association[association.keys.first]
        association = association.keys.first
      end
      opts = deep_associations.blank? ? {} : {:include => deep_associations}
      cloned_object = case self.class.reflect_on_association(association).macro
                      when :belongs_to, :has_one
                        self.send(association) && self.send(association).dup(opts)
                      when :has_many, :has_and_belongs_to_many
                        self.send(association).collect { |obj| obj.dup(opts) }
                      end
      kopy.send("#{association}=", cloned_object)
    end
  end

  return kopy
end