Module: DeepCloneable::DeepClone
- Defined in:
- lib/deep_cloneable/deep_clone.rb
Instance Method Summary collapse
-
#deep_clone(*args) {|_self, kopy| ... } ⇒ Object
Deep dups an ActiveRecord model.
Instance Method Details
#deep_clone(*args) {|_self, kopy| ... } ⇒ Object
Deep dups an ActiveRecord model. See README.rdoc
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/deep_cloneable/deep_clone.rb', line 6 def deep_clone(*args, &block) = args[0] || {} dictionary = [:dictionary] dictionary ||= {} if [:use_dictionary] kopy = if dictionary find_in_dictionary_or_dup(dictionary) else dup end [:preprocessor].call(self, kopy) if .key?(:preprocessor) deep_exceptions = {} if [:except] exceptions = Array.wrap([:except]) exceptions.each do |attribute| dup_default_attribute_value_to(kopy, attribute, self) unless attribute.is_a?(Hash) end deep_exceptions = exceptions.select { |e| e.is_a?(Hash) }.inject({}) { |m, h| m.merge(h) } end deep_onlinesses = {} if [:only] onlinesses = Array.wrap([:only]) object_attrs = kopy.attributes.keys.collect(&:to_sym) exceptions = object_attrs - onlinesses exceptions.each do |attribute| dup_default_attribute_value_to(kopy, attribute, self) unless attribute.is_a?(Hash) end deep_onlinesses = onlinesses.select { |e| e.is_a?(Hash) }.inject({}) { |m, h| m.merge(h) } end kopy.instance_eval { extend ::DeepCloneable::SkipValidations } if [:validate] == false if [:include] normalized_includes_list([:include]).each do |association, conditions_or_deep_associations| conditions = {} if association.is_a? Hash conditions_or_deep_associations = association[association.keys.first] association = association.keys.first end case conditions_or_deep_associations when Hash conditions_or_deep_associations = conditions_or_deep_associations.dup conditions[:if] = conditions_or_deep_associations.delete(:if) if conditions_or_deep_associations[:if] conditions[:unless] = conditions_or_deep_associations.delete(:unless) if conditions_or_deep_associations[:unless] when Array conditions_or_deep_associations = conditions_or_deep_associations.map { |entry| entry.is_a?(Hash) ? entry.dup : entry } conditions_or_deep_associations.each_with_index do |entry, index| if entry.is_a?(Hash) conditions[:if] = entry.delete(:if) if entry[:if] conditions[:unless] = entry.delete(:unless) if entry[:unless] end conditions_or_deep_associations.delete_at(index) if entry.empty? end end = {} [:include] = conditions_or_deep_associations if conditions_or_deep_associations.present? [:except] = deep_exceptions[association] if deep_exceptions[association] [:only] = deep_onlinesses[association] if deep_onlinesses[association] [:dictionary] = dictionary if dictionary [:skip_missing_associations, :validate, :preprocessor, :postprocessor].each do |option| [option] = [option] if .key?(option) end if (association_reflection = self.class.reflect_on_association(association)) association_type = association_reflection.macro association_type = "#{association_type}_through" if association_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) duped_object = send( "dup_#{association_type}_association", { :reflection => association_reflection, :association => association, :copy => kopy, :conditions => conditions, :dup_options => }, &block ) kopy.send("#{association}=", duped_object) elsif ![:skip_missing_associations] raise ::DeepCloneable::AssociationNotFoundException, "#{self.class}##{association}" end end end yield(self, kopy) if block [:postprocessor].call(self, kopy) if .key?(:postprocessor) kopy end |