Skip to content

Instantly share code, notes, and snippets.

@zapo
Last active August 29, 2015 13:58

Revisions

  1. zapo revised this gist Apr 8, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion dupable.rb
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,7 @@ def duplicate
    end

    # copy all has_many through target by copying collection_ids... only needed to populate throught association targets and pass some children presence validations
    # rails is too dump to inspect association models and deduce through association targets
    # rails is too dumb to inspect association models and deduce through association targets
    #
    self.class.reflect_on_all_associations(:has_many).select { |a| a.through_reflection.present? }.each do |assoc|
    duplicate.send(:"#{assoc.name.to_s.singularize}_ids=", self.send(:"#{assoc.name.to_s.singularize.to_sym}_ids"))
  2. zapo created this gist Apr 8, 2014.
    42 changes: 42 additions & 0 deletions dupable.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    module Concerns
    module Dupable
    def duplicate
    # copy self with attributes only, includes belongs_to associations
    duplicate = self.dup

    # copy all has_many associations...
    # reject through target associations, we only want to duplicate the association models

    self.class.reflect_on_all_associations(:has_many).select { |a| a.through_reflection.nil? }.each do |assoc|
    duplicate.send(:"#{assoc.name}=", self.send(assoc.name.to_sym).map { |item|
    item = item.respond_to?(:duplicate) ? item.duplicate : item.dup

    # delete foreign_key
    item.send(:"#{assoc.foreign_key}=", nil)

    # populate inverse assoc if present
    if assoc.inverse_of.present?
    item.send(:"#{assoc.inverse_of.name}=", duplicate)
    end

    item
    })
    end

    # copy all has_many through target by copying collection_ids... only needed to populate throught association targets and pass some children presence validations
    # rails is too dump to inspect association models and deduce through association targets
    #
    self.class.reflect_on_all_associations(:has_many).select { |a| a.through_reflection.present? }.each do |assoc|
    duplicate.send(:"#{assoc.name.to_s.singularize}_ids=", self.send(:"#{assoc.name.to_s.singularize.to_sym}_ids"))
    end

    # copy all has_one associations
    self.class.reflect_on_all_associations(:has_one).each do |assoc|
    item = self.send(assoc.name.to_sym)
    duplicate.send(:"#{assoc.name}=", item.respond_to?(:duplicate) ? item.duplicate : item.dup) if !item.nil?
    end

    duplicate
    end
    end
    end