diff --git a/app/models/bulkrax/csv_collection_entry.rb b/app/models/bulkrax/csv_collection_entry.rb index ea6df6325..cc113c5f0 100644 --- a/app/models/bulkrax/csv_collection_entry.rb +++ b/app/models/bulkrax/csv_collection_entry.rb @@ -2,9 +2,7 @@ module Bulkrax class CsvCollectionEntry < CsvEntry - def factory_class - Collection - end + self.default_work_type = "Collection" # Use identifier set by CsvParser#unique_collection_identifier, which falls back # on the Collection's first title if record[source_identifier] is not present diff --git a/app/models/bulkrax/entry.rb b/app/models/bulkrax/entry.rb index be087de0d..551ccfc6c 100644 --- a/app/models/bulkrax/entry.rb +++ b/app/models/bulkrax/entry.rb @@ -8,6 +8,8 @@ class OAIError < RuntimeError; end class Entry < ApplicationRecord include Bulkrax::HasMatchers include Bulkrax::ImportBehavior + self.class_attribute :default_work_type, default: Bulkrax.default_work_type + include Bulkrax::ExportBehavior include Bulkrax::StatusInfo include Bulkrax::HasLocalProcessing diff --git a/app/models/bulkrax/oai_set_entry.rb b/app/models/bulkrax/oai_set_entry.rb index 9555ebd91..11e3740bb 100644 --- a/app/models/bulkrax/oai_set_entry.rb +++ b/app/models/bulkrax/oai_set_entry.rb @@ -2,9 +2,7 @@ module Bulkrax class OaiSetEntry < OaiEntry - def factory_class - Collection - end + self.default_work_type = "Collection" def build_metadata self.parsed_metadata = self.raw_metadata diff --git a/app/models/bulkrax/rdf_collection_entry.rb b/app/models/bulkrax/rdf_collection_entry.rb index ce3149209..bf4bded54 100644 --- a/app/models/bulkrax/rdf_collection_entry.rb +++ b/app/models/bulkrax/rdf_collection_entry.rb @@ -2,6 +2,7 @@ module Bulkrax class RdfCollectionEntry < RdfEntry + self.default_work_type = "Collection" def record @record ||= self.raw_metadata end @@ -11,9 +12,5 @@ def build_metadata add_local return self.parsed_metadata end - - def factory_class - Collection - end end end diff --git a/app/models/concerns/bulkrax/file_set_entry_behavior.rb b/app/models/concerns/bulkrax/file_set_entry_behavior.rb index 1cf94a08a..883df9de2 100644 --- a/app/models/concerns/bulkrax/file_set_entry_behavior.rb +++ b/app/models/concerns/bulkrax/file_set_entry_behavior.rb @@ -2,8 +2,10 @@ module Bulkrax module FileSetEntryBehavior - def factory_class - ::FileSet + extend ActiveSupport::Concern + + included do + self.default_work_type = "::FileSet" end def file_reference diff --git a/app/models/concerns/bulkrax/import_behavior.rb b/app/models/concerns/bulkrax/import_behavior.rb index eea56afac..6e2f3c2d4 100644 --- a/app/models/concerns/bulkrax/import_behavior.rb +++ b/app/models/concerns/bulkrax/import_behavior.rb @@ -189,22 +189,10 @@ def factory end def factory_class - fc = if self.parsed_metadata&.[]('model').present? - self.parsed_metadata&.[]('model').is_a?(Array) ? self.parsed_metadata&.[]('model')&.first : self.parsed_metadata&.[]('model') - elsif self.mapping&.[]('work_type').present? - self.parsed_metadata&.[]('work_type').is_a?(Array) ? self.parsed_metadata&.[]('work_type')&.first : self.parsed_metadata&.[]('work_type') - else - Bulkrax.default_work_type - end - - # return the name of the collection or work - fc.tr!(' ', '_') - fc.downcase! if fc.match?(/[-_]/) - fc.camelcase.constantize - rescue NameError - nil - rescue - Bulkrax.default_work_type.constantize + # ATTENTION: Do not memoize this here; tests should catch the problem, but through out the + # lifecycle of parsing a CSV row or what not, we end up having different factory classes based + # on the encountered metadata. + FactoryClassFinder.find(entry: self) end end end diff --git a/app/services/bulkrax/factory_class_finder.rb b/app/services/bulkrax/factory_class_finder.rb new file mode 100644 index 000000000..bd85f8cdb --- /dev/null +++ b/app/services/bulkrax/factory_class_finder.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Bulkrax + class FactoryClassFinder + ## + # @param entry [Bulkrax::Entry] + # @return [Class] + def self.find(entry:) + new(entry: entry).find + end + + def initialize(entry:) + @entry = entry + end + attr_reader :entry + + ## + # @return [Class] when we are able to derive the class based on the {#name}. + # @return [Nil] when we encounter errors with constantizing the {#name}. + # @see #name + def find + # TODO: We have a string, now we want to consider how we coerce. Let's say we have Work and + # WorkResource in our upstream application. Work extends ActiveFedora::Base and is legacy. + # And WorkResource extends Valkyrie::Resource and is where we want to be moving. We may want + # to coerce the "Work" name into "WorkResource" + name.constantize + rescue NameError + nil + rescue + entry.default_work_type.constantize + end + + ## + # @api private + # @return [String] + def name + fc = if entry.parsed_metadata&.[]('model').present? + Array.wrap(entry.parsed_metadata['model']).first + elsif entry.importerexporter&.mapping&.[]('work_type').present? + # Because of delegation's nil guard, we're reaching rather far into the implementation + # details. + Array.wrap(entry.parsed_metadata['work_type']).first + else + # The string might be frozen, so lets duplicate + entry.default_work_type.dup + end + + # Let's coerce this into the right shape. + fc.tr!(' ', '_') + fc.downcase! if fc.match?(/[-_]/) + fc.camelcase + rescue + entry.default_work_type + end + end +end diff --git a/lib/bulkrax.rb b/lib/bulkrax.rb index b5a898370..3c4c08a0f 100644 --- a/lib/bulkrax.rb +++ b/lib/bulkrax.rb @@ -40,8 +40,6 @@ class Configuration attr_accessor :fill_in_blank_source_identifiers ## - # Configure which persistence adapter you'd prefer to favor. - # # @param adapter [Class] attr_writer :persistence_adapter diff --git a/spec/models/bulkrax/csv_file_set_entry_spec.rb b/spec/models/bulkrax/csv_file_set_entry_spec.rb index 70a6f5680..a7d4523b7 100644 --- a/spec/models/bulkrax/csv_file_set_entry_spec.rb +++ b/spec/models/bulkrax/csv_file_set_entry_spec.rb @@ -6,6 +6,11 @@ module Bulkrax RSpec.describe CsvFileSetEntry, type: :model do subject(:entry) { described_class.new } + describe '#default_work_type' do + subject { entry.default_work_type } + it { is_expected.to eq("::FileSet") } + end + describe '#file_reference' do context 'when parsed_metadata includes the "file" property' do before do diff --git a/spec/models/bulkrax/rdf_file_set_entry_spec.rb b/spec/models/bulkrax/rdf_file_set_entry_spec.rb new file mode 100644 index 000000000..319e55635 --- /dev/null +++ b/spec/models/bulkrax/rdf_file_set_entry_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +module Bulkrax + RSpec.describe RdfFileSetEntry, type: :model do + describe '#default_work_type' do + subject { described_class.new.default_work_type } + it { is_expected.to eq("::FileSet") } + end + + describe '#factory_class' do + subject { described_class.new.factory_class } + it { is_expected.to eq(::FileSet) } + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 01f7c9744..2a874101f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'dry/monads' + # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause