Module: DeepCloning
- Extended by:
- ActiveSupport::Concern
- Defined in:
- app/models/concerns/deep_cloning.rb
Instance Method Summary collapse
-
#dup_with_deep_cloning(options = {}) ⇒ Object
clones an ActiveRecord model.
Instance Method Details
#dup_with_deep_cloning(options = {}) ⇒ Object
clones an ActiveRecord model. if passed the :include option, it will deep clone the given associations if passed the :except option, it won’t clone the given attributes
Usage:
Cloning a model without an attribute
pirate.clone except: :name
Cloning a model without multiple attributes
pirate.clone except: [:name, :nick_name]
Cloning one single association
pirate.clone include: :mateys
Cloning multiple associations
pirate.clone include: [:mateys, :treasures]
Cloning really deep
pirate.clone include: :gold_pieces
Cloning really deep with multiple associations
pirate.clone include: [:mateys, :gold_pieces]
Cloning multiple associations - but only the join table entries without cloning the associated objects themselves
pirate.clone include_association: [:matey_ids, :treasure_ids]
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 |
# File 'app/models/concerns/deep_cloning.rb', line 52 def dup_with_deep_cloning( = {}) kopy = dup_without_deep_cloning if [:except] Array([:except]).each do |attribute| kopy.write_attribute(attribute, attributes_from_column_definition[attribute.to_s]) end end if [:include_association] Array([:include_association]).each do |association_attribute| kopy.send("#{association_attribute}=", self.send("#{association_attribute}")) end end if [:include] Array([:include]).each do |association, deep_associations| if (association.kind_of? Hash) deep_associations = association[association.keys.first] association = association.keys.first end opts = deep_associations.blank? ? {} : { include: deep_associations } association_reflection = self.class.reflect_on_association(association) cloned_object = case association_reflection.macro when :belongs_to, :has_one self.send(association) && self.send(association).dup(opts) when :has_many, :has_and_belongs_to_many fk = association_reflection.[:foreign_key]# || self.class.to_s.underscore self.send(association).collect do |obj| cloned_obj = obj.dup(opts) cloned_obj.send("#{fk}=", kopy.id) unless fk.blank? cloned_obj end end kopy.send("#{association}=", cloned_object) end end return kopy end |