From 4efaf8dd10bd88166c2e9ab485521ccd81a1bf28 Mon Sep 17 00:00:00 2001 From: Julie Allinson Date: Mon, 15 Apr 2019 15:26:52 +0000 Subject: [PATCH] Fix for #1505 --- app/models/concerns/hyrax/basic_metadata.rb | 2 +- app/services/hyrax/works/migration_service.rb | 33 +++++++++++++++++++ lib/tasks/migrate.rake | 5 +++ .../hyrax/works/migration_service_spec.rb | 21 ++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 app/services/hyrax/works/migration_service.rb create mode 100644 spec/services/hyrax/works/migration_service_spec.rb diff --git a/app/models/concerns/hyrax/basic_metadata.rb b/app/models/concerns/hyrax/basic_metadata.rb index 179ead0798..76588f39eb 100644 --- a/app/models/concerns/hyrax/basic_metadata.rb +++ b/app/models/concerns/hyrax/basic_metadata.rb @@ -16,7 +16,7 @@ module BasicMetadata property :contributor, predicate: ::RDF::Vocab::DC11.contributor property :description, predicate: ::RDF::Vocab::DC11.description property :abstract, predicate: ::RDF::Vocab::DC.abstract - property :keyword, predicate: ::RDF::Vocab::DC11.relation + property :keyword, predicate: ::RDF::Vocab::SCHEMA.keywords # Used for a license property :license, predicate: ::RDF::Vocab::DC.rights diff --git a/app/services/hyrax/works/migration_service.rb b/app/services/hyrax/works/migration_service.rb new file mode 100644 index 0000000000..ee8a6bac45 --- /dev/null +++ b/app/services/hyrax/works/migration_service.rb @@ -0,0 +1,33 @@ +module Hyrax + module Works + class MigrationService + # @api public + # + # Migrate data stored in FCrepo from one predicate to another + # The main use case is where the predicate used for a specific property is changed. + # Data already stored in Fedora under the original predicate needs to be transfered + # and the original data cleaned up. + def self.migrate_predicate(predicate_from, predicate_to, works_to_update = ActiveFedora::Base.all) + migrated = 0 + Rails.logger.info "*** Migrating #{predicate_from} to #{predicate_to} in #{works_to_update.count} works" + works_to_update.each do |work| + next unless work.ldp_source.content.include?(predicate_from.to_s) + migrate_data(predicate_from, predicate_to, work) + migrated += 1 + end + Rails.logger.info "--- Migration Complete (#{migrated} migrated)" + end + + # @api private + # + # Migrate data + def self.migrate_data(predicate_from, predicate_to, work) + orm = Ldp::Orm.new(work.ldp_source) + orm.value(predicate_from).each { |val| orm.graph.insert([orm.resource.subject_uri, predicate_to, val.to_s]) } + orm.graph.delete([orm.resource.subject_uri, predicate_from, nil]) + orm.save + Rails.logger.info " Data migrated from #{predicate_from} to #{predicate_to} - id: #{work.id}" + end + end + end +end diff --git a/lib/tasks/migrate.rake b/lib/tasks/migrate.rake index 50a0997818..00af5ed12e 100644 --- a/lib/tasks/migrate.rake +++ b/lib/tasks/migrate.rake @@ -34,5 +34,10 @@ namespace :hyrax do # added in Hyrax 2.1.0 Hyrax::Collections::MigrationService.migrate_all_collections end + + # Migrate any orphan fedora data from the first to the second predicate + task migrate_keyword_predicate: :environment do + Hyrax::Works::MigrationService.migrate_predicate(::RDF::Vocab::DC11.relation, ::RDF::Vocab::SCHEMA.keywords) + end end end diff --git a/spec/services/hyrax/works/migration_service_spec.rb b/spec/services/hyrax/works/migration_service_spec.rb new file mode 100644 index 0000000000..7f19831a94 --- /dev/null +++ b/spec/services/hyrax/works/migration_service_spec.rb @@ -0,0 +1,21 @@ +# rubocop:disable RSpec/InstanceVariable +RSpec.describe Hyrax::Works::MigrationService, clean_repo: true do + let(:predicate_from) { ::RDF::Vocab::DC11.description } + let(:predicate_to) { ::RDF::Vocab::SCHEMA.description } + + describe "#migrate_predicate" do + it "uses DC description by default" do + @work = GenericWork.create(title: ["War and Peace"], description: ["war", "peace"]) + expect(@work.ldp_source.content).to include("http://purl.org/dc/elements/1.1/description") + end + + it "updates to use SCHEMA description" do + @work = GenericWork.create(title: ["War and Peace"], description: ["war", "peace"]) + described_class.migrate_predicate(predicate_from, predicate_to) + @work.reload + expect(@work.ldp_source.content).to include("http://schema.org/description") + expect(@work.ldp_source.content).not_to include("http://purl.org/dc/elements/1.1/description") + end + end +end +# rubocop:enable RSpec/InstanceVariable