Class: RailsDeepCopy::Duplicate

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_deep_copy.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object_to_duplicate, options = {}) ⇒ Duplicate

Returns a new instance of Duplicate.



6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/rails_deep_copy.rb', line 6

def initialize(object_to_duplicate, options = {})
  @object_to_duplicate = object_to_duplicate
  @new_object = @object_to_duplicate.dup
  @changes = options[:changes] || {}
  @associations_to_build = options[:associations] || default_associations
  @associations_to_avoid = options[:exclude_associations] || []
  @skip_validations = options[:skip_validations] || true
  @id_hash = options[:id_hash] || {}
  @changes.merge!(@id_hash)
  @duplicated_objects = options.fetch(:duplicated_objects, [])
  setup_associations
end

Instance Attribute Details

#associationsObject

Returns the value of attribute associations.



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

def associations
  @associations
end

#id_hashObject

Returns the value of attribute id_hash.



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

def id_hash
  @id_hash
end

Class Method Details

.create(object_to_duplicate, options = {}) ⇒ Object



19
20
21
# File 'lib/rails_deep_copy.rb', line 19

def self.create(object_to_duplicate, options = {})
  Duplicate.new(object_to_duplicate, options).execute
end

Instance Method Details

#all_associationsObject



27
28
29
30
31
32
33
34
35
# File 'lib/rails_deep_copy.rb', line 27

def all_associations
  associations = @object_to_duplicate.class.reflect_on_all_associations
  return associations unless @associations_to_build.any? || @associations_to_avoid.any?
  if @associations_to_build.any?
    associations.find_all{|association| @associations_to_build.include?(association.name)}
  else
    associations.find_all{|association| !@associations_to_avoid.include?(association.name)}
  end
end

#default_associationsObject



23
24
25
# File 'lib/rails_deep_copy.rb', line 23

def default_associations
  @new_object.class::DUPLICABLE_ASSOCIATIONS rescue []
end

#duplicable_associationsObject



37
38
39
40
41
42
43
44
45
# File 'lib/rails_deep_copy.rb', line 37

def duplicable_associations
  # duplicable association types: :has_one, :has_one :through, :has_many
  # not duplicable: :has_many :through, :belongs_to
  all_associations.find_all do |association|
    should_keep = [:has_many, :has_one].include?(association.macro)
    should_keep = false if association.macro == :has_many && association.options.keys.include?(:through)
    should_keep
  end
end

#executeObject



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/rails_deep_copy.rb', line 88

def execute
  implement_new_object_differences
  @new_object.save(:validate => validate?) && update_id_hash
  @duplicated_objects << @new_object
  associations.each do |association|
    objects = [@object_to_duplicate.send(association.name)].flatten.compact
    objects.each do |obj|
      # recursively create child objects and assign IDs
      Duplicate.create(obj, id_hash: id_hash, duplicated_objects: @duplicated_objects)
    end
  end
  # done with children - remove ID from ID hash
  remove_id_from_id_hash
  @duplicated_objects.first
end

#implement_new_object_differencesObject



64
65
66
67
68
69
70
# File 'lib/rails_deep_copy.rb', line 64

def implement_new_object_differences
  defaults = @new_object.class::DUPLICABLE_DEFAULTS rescue false
  hash = defaults ? defaults.merge(@changes) : @changes
  hash.each do |attribute, value|
    @new_object.send("#{attribute}=", value) if @new_object.attributes.include?(attribute.to_s)
  end
end

#new_object_id_fieldObject



72
73
74
# File 'lib/rails_deep_copy.rb', line 72

def new_object_id_field
  "#{@new_object.class.name.underscore}_id".to_sym
end

#remove_id_from_id_hashObject



84
85
86
# File 'lib/rails_deep_copy.rb', line 84

def remove_id_from_id_hash
  @id_hash.delete(new_object_id_field)
end

#setup_associationsObject



59
60
61
62
# File 'lib/rails_deep_copy.rb', line 59

def setup_associations
  @associations = duplicable_associations
  sort_through_associations
end

#sort_through_associationsObject



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rails_deep_copy.rb', line 47

def sort_through_associations
  through_associations = []
  # associations with :through should be last in iteration to make sure IDs are set appropriately
  associations.each do |association|
    if association.options.keys.include?(:through)
      through_associations << association
      @associations.delete(association)
    end
  end
  @associations = (@associations << through_associations).flatten
end

#update_id_hashObject



80
81
82
# File 'lib/rails_deep_copy.rb', line 80

def update_id_hash
  @id_hash[new_object_id_field] = @new_object.id
end

#validate?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/rails_deep_copy.rb', line 76

def validate?
  !@skip_validations
end