1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
- class Sequencer
- class Unit
- module Import
- module Common
- module Model
- module Associations
- class Assign < Sequencer::Unit::Base
- include ::Sequencer::Unit::Import::Common::Model::Mixin::HandleFailure
- uses :instance, :associations, :action, :dry_run
- provides :action
- def process
- return if dry_run
- return if instance.blank?
- return if associations.blank? && log_associations_error
- register_changes
- instance.assign_attributes(associations)
- rescue => e
- handle_failure(e)
- end
- private
- # always returns true
- def log_associations_error
- return true if %i[skipped failed deactivated].include?(action)
- logger.error { 'associations cannot be nil' } if associations.nil?
- true
- end
- def register_changes
- return if !(action == :unchanged && changes.any?)
- logger.debug { "Changed instance associations: #{changes.inspect}" }
- state.provide(:action, :updated)
- end
- # Why not just use instance.changes?
- # Because it doesn't include associations
- # stored on OTHER TABLES (has-one, has-many, HABTM)
- def changes
- @changes ||= unfiltered_changes.reject { |_attribute, values| no_diff?(values) }
- end
- def unfiltered_changes
- attrs = associations.keys
- before = attrs.map { |attribute| instance.send(attribute) }
- after = associations.values
- attrs.zip(before.zip(after)).to_h.with_indifferent_access
- end
- def no_diff?(values)
- values.map!(&:sort) if values.all? { |val| val.respond_to?(:sort) }
- values.map!(&:presence) # [nil, []] -> [nil, nil]
- values.uniq.length == 1
- end
- end
- end
- end
- end
- end
- end
- end
|