Skip to content

Commit 9e85e50

Browse files
authored
Support importing compound metadata (#1207)
Add name:/row_key: option for object field maps Add support for `name:` (alias `row_key:`) in field mappings with an `object:` key. This allows the mapping to specify the key under which the value will be written inside the object row, independently of the globally unique mapping key.
1 parent 9b598b4 commit 9e85e50

3 files changed

Lines changed: 64 additions & 1 deletion

File tree

app/models/concerns/bulkrax/has_matchers.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,20 @@ def set_parsed_data(name, value)
9595
def set_parsed_object_data(object_multiple, object_name, name, index, value)
9696
target_key = parsed_object_target_key(object_name)
9797
target = object_target_for(target_key, object_name, object_multiple, index)
98-
assign_object_value(target, name, value)
98+
assign_object_value(target, object_row_key(name), value)
99+
end
100+
101+
# The key a value is written under inside an `object:` row. Defaults to the
102+
# mapping key, but a mapping may set `name:` (alias `row_key:`) to use a
103+
# different in-row key. This lets two mappings with distinct (globally
104+
# unique) keys both write the same in-row key into different objects — e.g.
105+
# a `title` sub-property shared by two compounds, each needing a unique
106+
# top-level mapping key but the same `title` key inside its row.
107+
def object_row_key(name)
108+
cfg = mapping[name]
109+
return name unless cfg.is_a?(Hash)
110+
111+
cfg['name'] || cfg[:name] || cfg['row_key'] || cfg[:row_key] || name
99112
end
100113

101114
# Resolve the hash slot that `name` should be written into, initializing

spec/models/bulkrax/csv_entry_spec.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,47 @@ class ::Avocado < Work
670670
end
671671
end
672672

673+
# Compound metadata is a Valkyrie-only feature: the in-row `name:` option
674+
# supports compounds whose sub-property keys collide across parents
675+
# (e.g. a `title` shared by two compounds). Exercise it against a Valkyrie
676+
# resource whose schema declares `type: hash, multiple: true` parents.
677+
context 'when a mapping declares name: to set the in-row key (Valkyrie compound)' do
678+
# `name:` (alias `row_key:`) decouples the in-row key from the globally
679+
# unique mapping key, so two mappings with distinct keys can write the
680+
# same in-row key into different compounds.
681+
let(:importer) do
682+
FactoryBot.create(:bulkrax_importer_csv, field_mapping: {
683+
'compound_one_title' => { from: ['compound_one_title'], object: 'compound_one', nested_attributes: true, name: 'title' },
684+
'compound_two_title' => { from: ['compound_two_title'], object: 'compound_two', nested_attributes: true, name: 'title' }
685+
})
686+
end
687+
688+
around do |example|
689+
previous = Bulkrax.object_factory
690+
Bulkrax.object_factory = Bulkrax::ValkyrieObjectFactory
691+
example.run
692+
Bulkrax.object_factory = previous
693+
end
694+
695+
before do
696+
allow(subject).to receive(:factory_class).and_return(WorkResource)
697+
allow(subject).to receive(:raw_metadata).and_return(
698+
'source_identifier' => '2',
699+
'title' => 'some title',
700+
'compound_one_title_1' => 'Title A',
701+
'compound_two_title_1' => 'Title B'
702+
)
703+
end
704+
705+
it 'writes each value under the configured in-row key, independently per compound' do
706+
metadata = subject.build_metadata
707+
expect(metadata['compound_one_attributes']['0']['title']).to eq('Title A')
708+
expect(metadata['compound_two_attributes']['0']['title']).to eq('Title B')
709+
# The unique mapping key is not used as the in-row key.
710+
expect(metadata['compound_one_attributes']['0']).not_to have_key('compound_one_title')
711+
end
712+
end
713+
673714
context 'with object fields not prefixed and properties with multiple values' do
674715
let(:importer) do
675716
FactoryBot.create(:bulkrax_importer_csv, field_mapping: {

spec/test_app/config/metadata/work_resource.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ attributes:
99
required: false
1010
primary: false
1111
multiple: false
12+
# Two compound (Array<Hash>) parents used to exercise the `name:` (row_key)
13+
# field-mapping option on a Valkyrie resource: a shared in-row key (`title`)
14+
# written into different compounds from distinct, globally unique mapping keys.
15+
compound_one:
16+
type: hash
17+
multiple: true
18+
compound_two:
19+
type: hash
20+
multiple: true

0 commit comments

Comments
 (0)