diff --git a/app/models/hyrax/change_set.rb b/app/models/hyrax/change_set.rb index 92c20736c5..444e1ffe1d 100644 --- a/app/models/hyrax/change_set.rb +++ b/app/models/hyrax/change_set.rb @@ -45,5 +45,12 @@ class ChangeSet < Valkyrie::ChangeSet def self.for(resource) Hyrax::ChangeSet(resource.class).new(resource) end + + def clean_id_fields_before_sync + id_fields = fields.keys.select { |k| k.include?('_id') } + multiple_id_fields_with_empties = id_fields.select { |f| fields[f].is_a?(Array) && fields[f].any?(&:empty?) } + + multiple_id_fields_with_empties.each { |f| fields[f] = fields[f].reject(&:empty?) } + end end end diff --git a/lib/hyrax/transactions/steps/save.rb b/lib/hyrax/transactions/steps/save.rb index cd5bf8bc45..9c8605ec3c 100644 --- a/lib/hyrax/transactions/steps/save.rb +++ b/lib/hyrax/transactions/steps/save.rb @@ -35,6 +35,7 @@ def call(change_set, user: nil) valid_future_date?(change_set.lease, 'lease_expiration_date') if change_set.respond_to?(:lease) && change_set.lease valid_future_date?(change_set.embargo, 'embargo_release_date') if change_set.respond_to?(:embargo) && change_set.embargo new_collections = changed_collection_membership(change_set) + change_set.clean_id_fields_before_sync unsaved = change_set.sync save_lease_or_embargo(unsaved) diff --git a/spec/models/hyrax/change_set_spec.rb b/spec/models/hyrax/change_set_spec.rb index 2d67aa4ca1..aa279d69ea 100644 --- a/spec/models/hyrax/change_set_spec.rb +++ b/spec/models/hyrax/change_set_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Hyrax::ChangeSet do subject(:change_set) { described_class.for(resource) } - let(:resource) { build(:hyrax_work) } + let(:resource) { build(:hyrax_work, :with_default_admin_set) } let(:titles) { ['comet in moominland', 'finn family moomintroll'] } it_behaves_like 'a Hyrax::ChangeSet' @@ -34,6 +34,21 @@ end end + describe '#clean_id_fields_before_sync' do + # NOTE: A pair-tree'ed Fedora storage scheme requires the elimiation of any + # empty string values within a multivalued id attribute. If it passes along + # to a parser that takes any value present in an array and converts it into + # a Valkyrie::ID instance, Valkyrie's persister will attempt to pairtree that value. + it 'will eliminate empty string values from a change set' do + change_set.member_of_collection_ids = [""] + + expect { change_set.clean_id_fields_before_sync } + .to change { change_set.member_of_collection_ids } + .from([""]) + .to([]) + end + end + describe '#sync' do it 'applies changeset attributes' do change_set.title = titles