lib/calagator/duplicate_checking.rb in calagator-1.1.0 vs lib/calagator/duplicate_checking.rb in calagator-2.0.0.pre.0

- old
+ new

@@ -1,13 +1,15 @@ +# frozen_string_literal: true + # = DuplicateChecking # # This mixin provides a way for ActiveRecord classes to find and squash duplicates. # # Example: # # # Define your class -# class Thing < ActiveRecord::Base +# class Thing < ApplicationRecord # # Load the mixin into your class # include DuplicateChecking # # # Declare attributes that should be ignored during duplicate checks # duplicate_checking_ignores_attributes :random_value @@ -48,24 +50,25 @@ def duplicate? duplicate_of.present? end alias marked_as_duplicate? duplicate? - alias slave? duplicate? - def master? - !slave? + def primary? + !duplicate? end - # Return the ultimate master for a record, which may be the record itself. - def progenitor + # Return the ultimate primary for a record, which may be the record itself. + def originator parent = self seen = Set.new loop do - return parent if parent.master? - raise DuplicateCheckingError, "Loop detected in duplicates chain at #{parent.class}##{parent.id}" if seen.include?(parent) + return parent if parent.primary? + if seen.include?(parent) + raise DuplicateCheckingError, "Loop detected in duplicates chain at #{parent.class}##{parent.id}" + end seen << parent parent = parent.duplicate_of end end @@ -85,11 +88,11 @@ def self.extended(klass) klass.instance_eval do cattr_accessor(:_duplicate_checking_ignores_attributes) { Set.new } cattr_accessor(:_duplicate_squashing_ignores_associations) { Set.new } cattr_accessor(:_duplicate_finding_scope) { -> { all } } - cattr_accessor(:_after_squashing_duplicates) { ->(master) {} } + cattr_accessor(:_after_squashing_duplicates) { ->(primary) {} } belongs_to :duplicate_of, class_name: name, foreign_key: DUPLICATE_MARK_COLUMN has_many :duplicates, class_name: name, foreign_key: DUPLICATE_MARK_COLUMN scope :marked_duplicates, -> { where("#{table_name}.#{DUPLICATE_MARK_COLUMN} IS NOT NULL") } @@ -97,17 +100,21 @@ end end # Return set of attributes that should be ignored for duplicate checking def duplicate_checking_ignores_attributes(*args) - _duplicate_checking_ignores_attributes.merge(args.map(&:to_sym)) unless args.empty? + unless args.empty? + _duplicate_checking_ignores_attributes.merge(args.map(&:to_sym)) + end DUPLICATE_CHECKING_IGNORES_ATTRIBUTES + _duplicate_checking_ignores_attributes end # Return set of associations that will be ignored during duplicate squashing def duplicate_squashing_ignores_associations(*args) - _duplicate_squashing_ignores_associations.merge(args.map(&:to_sym)) unless args.empty? + unless args.empty? + _duplicate_squashing_ignores_associations.merge(args.map(&:to_sym)) + end _duplicate_squashing_ignores_associations end def duplicate_finding_scope(*args) self._duplicate_finding_scope = args.first unless args.empty? @@ -128,13 +135,13 @@ # Squash duplicates. Options accept ActiveRecord instances or IDs. # # Options: # :duplicates => ActiveRecord instance(s) to mark as duplicates - # :master => ActiveRecord instance to use as master - def squash(master, duplicates) - DuplicateSquasher.new(master, duplicates, name.downcase).squash.tap do |squasher| - after_squashing_duplicates.call(master) unless squasher.failure + # :primary => ActiveRecord instance to use as the primary record + def squash(primary, duplicates) + DuplicateSquasher.new(primary, duplicates, name.downcase).squash.tap do |squasher| + after_squashing_duplicates.call(primary) unless squasher.failure end end end end