diff --git a/app/models/bulkrax/csv_entry.rb b/app/models/bulkrax/csv_entry.rb index 32595143..e290fa0e 100644 --- a/app/models/bulkrax/csv_entry.rb +++ b/app/models/bulkrax/csv_entry.rb @@ -88,9 +88,10 @@ def self.data_for_entry(data, _source_id, parser) # model has to be separated so that it doesn't get mistranslated by to_h raw_data = data.to_h raw_data[:model] = data[:model] if data[:model].present? - # If the collection field mapping is not 'collection', add 'collection' - the parser needs it - # TODO: change to :parents - raw_data[:parents] = raw_data[parent_field(parser).to_sym] if raw_data.keys.include?(parent_field(parser).to_sym) && parent_field(parser) != 'parents' + # If the parents/children field mapping uses a custom column name, alias it to the standard key + # so downstream code can find it regardless of what the CSV column is named. + raw_data[:parents] = raw_data[parser.related_parents_raw_mapping.to_sym] if parser.related_parents_raw_mapping.present? && raw_data.key?(parser.related_parents_raw_mapping.to_sym) && parser.related_parents_raw_mapping != 'parents' + raw_data[:children] = raw_data[parser.related_children_raw_mapping.to_sym] if parser.related_children_raw_mapping.present? && raw_data.key?(parser.related_children_raw_mapping.to_sym) && parser.related_children_raw_mapping != 'children' return raw_data end diff --git a/app/models/bulkrax/entry.rb b/app/models/bulkrax/entry.rb index 29f09f3c..180afd34 100644 --- a/app/models/bulkrax/entry.rb +++ b/app/models/bulkrax/entry.rb @@ -93,6 +93,10 @@ def self.parent_field(parser) parser.related_parents_parsed_mapping end + def self.child_field(parser) + parser.related_children_parsed_mapping + end + def build return if type.nil? self.save if self.new_record? # must be saved for statuses diff --git a/spec/models/bulkrax/csv_entry_spec.rb b/spec/models/bulkrax/csv_entry_spec.rb index 5611794a..5a2ba22c 100644 --- a/spec/models/bulkrax/csv_entry_spec.rb +++ b/spec/models/bulkrax/csv_entry_spec.rb @@ -38,6 +38,58 @@ module Bulkrax end end + describe '.data_for_entry' do + let(:importer) { FactoryBot.create(:bulkrax_importer_csv, :with_relationships_mappings) } + let(:parser) { importer.parser } + + # Simulate a CSV::Row with a custom-named column mapped to 'parents'/'children' + def make_row(hash) + headers = hash.keys + CSV::Row.new(headers, hash.values_at(*headers)) + end + + context 'when the parents column uses the default name "parents"' do + it 'does not alias raw_data[:parents] (already correct key)' do + row = make_row({ source_identifier: '1', title: 'test', parents: 'parent_1' }) + result = described_class.data_for_entry(row, nil, parser) + expect(result[:parents]).to eq('parent_1') + end + end + + context 'when the parents column uses a custom name matching the field mapping' do + it 'aliases the custom column to raw_data[:parents]' do + row = make_row({ source_identifier: '1', title: 'test', parents_column: 'parent_1' }) + result = described_class.data_for_entry(row, nil, parser) + expect(result[:parents]).to eq('parent_1') + end + end + + context 'when the children column uses the default name "children"' do + it 'does not alias raw_data[:children] (already correct key)' do + row = make_row({ source_identifier: '1', title: 'test', children: 'child_1' }) + result = described_class.data_for_entry(row, nil, parser) + expect(result[:children]).to eq('child_1') + end + end + + context 'when the children column uses a custom name matching the field mapping' do + it 'aliases the custom column to raw_data[:children]' do + row = make_row({ source_identifier: '1', title: 'test', children_column: 'child_1' }) + result = described_class.data_for_entry(row, nil, parser) + expect(result[:children]).to eq('child_1') + end + end + + context 'when both parents and children use custom column names' do + it 'aliases both to their standard keys' do + row = make_row({ source_identifier: '1', title: 'test', parents_column: 'parent_1', children_column: 'child_1' }) + result = described_class.data_for_entry(row, nil, parser) + expect(result[:parents]).to eq('parent_1') + expect(result[:children]).to eq('child_1') + end + end + end + context 'AttributeBuilderMethod.for' do # Why is this spec here? Because we have a LOT of before blocks that are saying stubbing and # allowing different things. When I had this method in a more logical place, it was getting