Module: ActiveRecord::Base::DeepCloneable
- Included in:
- ActiveRecord::Base
- Defined in:
- lib/deep_cloneable.rb
Defined Under Namespace
Classes: AssociationNotFoundException
Instance Method Summary collapse
-
#deep_clone(*args, &block) ⇒ Object
Deep dups an ActiveRecord model.
Instance Method Details
#deep_clone(*args, &block) ⇒ Object
Deep dups an ActiveRecord model. See README.rdoc
5 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 |
# File 'lib/deep_cloneable.rb', line 5 def deep_clone *args, &block = args[0] || {} dict = [:dictionary] dict ||= {} if .delete(:use_dictionary) kopy = unless dict dup() else find_in_dict_or_dup(dict) end block.call(self, kopy) if block deep_exceptions = {} if [:except] exceptions = [:except].nil? ? [] : [[:except]].flatten exceptions.each do |attribute| kopy.send(:write_attribute, attribute, self.class.column_defaults.dup[attribute.to_s]) unless attribute.kind_of?(Hash) end deep_exceptions = exceptions.select{|e| e.kind_of?(Hash) }.inject({}){|m,h| m.merge(h) } end deep_onlinesses = {} if [:only] onlinesses = [:only].nil? ? [] : [[:only]].flatten object_attrs = kopy.attributes.keys.collect{ |s| s.to_sym } exceptions = object_attrs - onlinesses exceptions.each do |attribute| kopy.send(:write_attribute, attribute, self.class.column_defaults.dup[attribute.to_s]) unless attribute.kind_of?(Hash) end deep_onlinesses = onlinesses.select{|e| e.kind_of?(Hash) }.inject({}){|m,h| m.merge(h) } end if [:include] Array([:include]).each do |association, conditions_or_deep_associations| conditions = {} if association.kind_of? Hash conditions_or_deep_associations = association[association.keys.first] association = association.keys.first end if conditions_or_deep_associations.kind_of?(Hash) 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] end = conditions_or_deep_associations.blank? ? {} : {:include => conditions_or_deep_associations} .merge!(:except => deep_exceptions[association]) if deep_exceptions[association] .merge!(:only => deep_onlinesses[association]) if deep_onlinesses[association] .merge!(:dictionary => dict) if dict association_reflection = self.class.reflect_on_association(association) raise AssociationNotFoundException.new("#{self.class}##{association}") if association_reflection.nil? if [:validate] == false kopy.instance_eval do # Force :validate => false on all saves. def perform_validations(={}) [:validate] = false super() end end end 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) end end return kopy end |