Module: DataMapper::DeepCloning
- Defined in:
- lib/dm-deep_cloning.rb,
lib/data_mapper/deep_cloning/utilities.rb
Defined Under Namespace
Modules: Utilities
Constant Summary collapse
- DEFAULT_MODE =
:new
Instance Method Summary collapse
Instance Method Details
#deep_clone(*args) ⇒ Object
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 |
# File 'lib/dm-deep_cloning.rb', line 26 def deep_clone(*args) mode = args.shift if [:new, :create].include?(args.first) mode ||= DEFAULT_MODE clone_relations = {} args.each do |arg| case arg when Hash Utilities::Hash.recursive_merge!(clone_relations, arg) when Array arg.each do |el| clone_relations[el] = {} end when Symbol clone_relations[arg] = {} else raise ArgumentError, "deep_clone only accepts Symbols, Hashes or Arrays" end end attrs = self.attributes.reject{ |(k, v)| self.class.properties[k].key? || k.to_s =~ /^(updated|created)_(at|on)$/ } clone_relations.keys.each do |relationship_name| relationship = self.class.relationships[relationship_name] case relationship when DataMapper::Associations::OneToMany::Relationship, DataMapper::Associations::ManyToMany::Relationship attrs[relationship.name] = self.send(relationship.name).to_a.map do || # Q: Why `to_a`???? # A: This is used to indirectly disable `eager_load` in the `attributes` method called in the following recursive call. # Q: Aha!!! But why??? # A: It simply doesn't work with STI. # Q: f***! # A: Yea! Took me 3 hours. .deep_clone(mode, clone_relations[relationship.name]) end if attrs[relationship.name].empty? # Delete the atrribute if no objects need to be assigned to the relation. # dm-core seems to have a problem with Foo.new(:bars => []). Sadly # this was not reproduceable in the specs. attrs.delete(relationship.name) end when DataMapper::Associations::ManyToOne::Relationship attrs[relationship.name] = self.send(relationship.name).deep_clone(mode, clone_relations[relationship.name]) else raise "Deep cloning failed: Unknown relationship '#{relationship_name}' in '#{self.class}'" end end self.class.send(mode, attrs) end |