Sha256: 0633582edd68b57023b8c228649d253103a18bb993c3df8bb8766f99cecf06e2

Contents?: true

Size: 1.63 KB

Versions: 3

Compression:

Stored size: 1.63 KB

Contents

module Merger
  class Merge
    attr_reader :keep, :duplicates, :options
  
    def initialize(*records)
      @options = records.extract_options!
      @options[:destroy] = true unless @options.has_key?(:destroy)
      records = records.flatten.uniq
      @keep = options[:keep] || records.sort_by(&:id).first
      @duplicates = records - [@keep]
    end
  
    def ignored_associations
      return @ignored if @ignored
      @ignored = Array(options[:skip_association])
      keep.class.reflect_on_all_associations.each do |association|
        @ignored << association.through_reflection.name if association.through_reflection
      end
      @ignored
    end

    def associations!
      keep.class.reflect_on_all_associations.each do |association|
        duplicates.each do |record|
          next if ignored_associations.include?(association.name)
          case association.macro
          when :has_many, :has_and_belongs_to_many
            name = "#{association.name.to_s.singularize}_ids"
            keep.send("#{name}=", keep.send(name) | record.send(name))
          when :belongs_to, :has_one
            keep.send("#{association.name}=", record.send(association.name)) if keep.send("#{association.name}").nil?
          end
        end
      end
    end
    
    def merge!
      keep.class.transaction do
        duplicates.each {|duplicate| duplicate.send(:before_merge, keep) if duplicate.respond_to?(:before_merge) }
        associations!
        duplicates.each {|duplicate| duplicate.send(:after_merge, keep) if duplicate.respond_to?(:after_merge) }
        
        duplicates.each(&:destroy) if options[:destroy]
      end
    end
  
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
merger-0.1.2 lib/merger/merge.rb
merger-0.1.1 lib/merger/merge.rb
merger-0.1.0 lib/merger/merge.rb