class Sequel::Plugins::DeepDup::DeepDupper
Attributes
associations[R]
instance[R]
omit_records[R]
Public Class Methods
new(instance, opts = {})
click to toggle source
# File lib/sequel_deep_dup.rb, line 10 def initialize instance, opts = {} @instance = instance @associations = opts[:associations] @omit_records = opts[:omit_records] || [] end
Public Instance Methods
dup()
click to toggle source
# File lib/sequel_deep_dup.rb, line 16 def dup copy = shallow_dup.extend(InstanceHooks::InstanceMethods) omit_records << instance dup_associations(instance, copy, associations) copy end
dup_associations(instance, copy, includes = nil)
click to toggle source
# File lib/sequel_deep_dup.rb, line 30 def dup_associations instance, copy, includes = nil includes &&= normalize_graph(includes) associations = instance.class.associations if includes (includes.keys - associations).each do |assoc| raise(Error, "no association named #{assoc} for #{instance}") end end associations.each do |name| next unless refl = instance.class.association_reflection(name) [*instance.send(name)].compact.each do |rec| if includes next unless includes.has_key?( refl_name = refl[:name] ) instantiate_associated copy, refl, rec, includes[refl_name] else next copy.values.delete(refl[:key]) if refl[:type] == :many_to_one instantiate_associated(copy, refl, rec, nil) end end end end
normalize_graph(*enum)
click to toggle source
# File lib/sequel_deep_dup.rb, line 54 def normalize_graph(*enum) enum.inject({}) do |hash, assoc| case assoc when Symbol then hash[assoc] = {} when Hash then assoc.each { |k, v| hash[k] = normalize_graph(v) } else hash.merge!(normalize_graph(*assoc) || next) end hash end end
shallow_dup()
click to toggle source
# File lib/sequel_deep_dup.rb, line 23 def shallow_dup klass = instance.class attributes = instance.to_hash.dup [*klass.primary_key].each { |attr| attributes.delete(attr) } klass.new attributes end
Private Instance Methods
instantiate_associated(copy, reflection, record, associations)
click to toggle source
# File lib/sequel_deep_dup.rb, line 66 def instantiate_associated copy, reflection, record, associations return if omit_records.detect { |to_omit| record.pk == to_omit.pk && record.class == to_omit.class } unless reflection[:type] == :many_to_many record = DeepDupper.new( record, :omit_records => omit_records, :associations => associations ).dup end if reflection.returns_array? copy.send(reflection[:name]) << record copy.after_save_hook{ copy.send(reflection.add_method, record) } else copy.associations[reflection[:name]] = record copy.instance_variable_set :@set_associated_object_if_same, true if reflection[:type] == :many_to_one copy.before_save_hook { copy.send reflection.setter_method, record.save } else copy.after_save_hook{ copy.send(reflection.setter_method, record) } end end end