class MaterialSyncImporter Result = Struct.new(:material, :suppressed, :suppression, keyword_init: true) def self.import! attributes new(attributes).import! end def initialize attributes @attributes = attributes end def import! source = source_attributes key = normalized_source_key(source) raise ArgumentError, 'normalized_source_key is required for material sync' if key.blank? suppression = MaterialSyncSuppressionMatcher.match(**source) return Result.new(material: nil, suppressed: true, suppression:) if suppression material = Material .unscoped .find_or_initialize_by(normalized_source_key: key) material.assign_attributes(material_attributes.merge(source)) material.save! Result.new(material:, suppressed: false, suppression: nil) end private def source_attributes { source_kind: @attributes[:source_kind], source_uri: @attributes[:source_uri], source_path: @attributes[:source_path], source_file_id: @attributes[:source_file_id] } end def normalized_source_key source MaterialSyncSuppression.normalize_source_key(source_kind: source[:source_kind], source_uri: source[:source_uri], source_path: source[:source_path], source_file_id: source[:source_file_id]) end def material_attributes @attributes.except(:source_kind, :source_uri, :source_path, :source_file_id) end end