From 67563d64fbdc758f9da970529625ff67cb359d68 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Mon, 30 Mar 2026 16:35:08 -0400 Subject: [PATCH 1/2] Add failing spec for relationship bugs Relationships with Children column do not work. --- spec/models/bulkrax/csv_entry_spec.rb | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/spec/models/bulkrax/csv_entry_spec.rb b/spec/models/bulkrax/csv_entry_spec.rb index 5611794a0..5a2ba22ce 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 From 756d4dbd5db161cef090987c32569a9e4d2ae678 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Mon, 30 Mar 2026 16:38:28 -0400 Subject: [PATCH 2/2] Fix relationship bugs with parent/children Two bugs were introduced during the refactor of relationship field mapping in PRs #371 and #438 that cause relationships defined via the parents and children columns in CSV imports to be silently dropped. Bug 1: children custom column aliasing was deleted and never re-implemented Bug 2: parents custom column aliasing condition is always false --- app/models/bulkrax/csv_entry.rb | 7 ++++--- app/models/bulkrax/entry.rb | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/models/bulkrax/csv_entry.rb b/app/models/bulkrax/csv_entry.rb index 325951432..e290fa0e0 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 29f09f3cc..180afd345 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