Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ def after_transfer!
# are metadata values
# @param child_well_location [String] the location of the child well associated with the request
def create_or_update_request_metadata(request, request_metadata, child_well_location)
# Fetch all existing metadata for this request
existing_metadata_by_key = fetch_existing_metadata(request.id)

request_metadata.each do |metadata_key, metadata_value|
existing_metadata_v2 = find_existing_metadata(metadata_key, request.id)
existing_metadata = existing_metadata_by_key[metadata_key]

if existing_metadata_v2.present?
update_existing_metadata(existing_metadata_v2, metadata_value, metadata_key, child_well_location)
if existing_metadata.present?
update_existing_metadata(existing_metadata, metadata_value, metadata_key, child_well_location)
else
create_new_metadata(metadata_key, metadata_value, request, child_well_location)
end
Expand Down Expand Up @@ -186,28 +189,27 @@ def well_filter
@well_filter ||= WellFilterAllowingPartials.new(creator: self, request_state: 'pending')
end

# Finds and returns the first existing metadata that matches the provided key and request ID.
# If no matching metadata is found, it returns nil.
# Fetches all existing metadata for a request returns a hash keyed by metadata key.
#
# @param metadata_key [String] the key of the metadata to find
# @param request_id [Integer] the ID of the request associated with the metadata
# @return [Sequencescape::Api::V2::PolyMetadatum, nil] the found metadata or nil if no matching metadata is found
def find_existing_metadata(metadata_key, request_id)
Sequencescape::Api::V2::PolyMetadatum.find(key: metadata_key, metadatable_id: request_id).first
# @return [Hash<String, Sequencescape::Api::V2::PolyMetadatum>] hash of metadata keyed by metadata key
def fetch_existing_metadata(request_id)
Sequencescape::Api::V2::PolyMetadatum.find(metadatable_id: request_id,
metadatable_type: 'Request').index_by(&:key)
end

# Updates the value of an existing metadata if it's different from the provided value.
# If the metadata fails to update, it raises a StandardError with a descriptive message.
#
# @param existing_metadata_v2 [Sequencescape::Api::V2::Metadatum] the existing metadata to update
# @param existing_metadata [Sequencescape::Api::V2::Metadatum] the existing metadata to update
# @param metadata_value [String] the new value for the metadata
# @param metadata_key [String] the key of the metadata
# @param child_well_location [String] the location of the child well associated with the request
# @raise [StandardError] if the existing metadata fails to update
def update_existing_metadata(existing_metadata_v2, metadata_value, metadata_key, child_well_location)
return if existing_metadata_v2.value == metadata_value
def update_existing_metadata(existing_metadata, metadata_value, metadata_key, child_well_location)
return if existing_metadata.value == metadata_value

return if existing_metadata_v2.update(value: metadata_value)
return if existing_metadata.update(value: metadata_value)

raise StandardError,
"Existing metadata for request (key: #{metadata_key}, value: #{metadata_value}) " \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1461,15 +1461,12 @@
before do
allow(pm_pcr_cycles).to receive(:update).and_return(true)

stub_polymetadata(pm_original_plate_barcode, loop_2_request.id)
stub_polymetadata(pm_original_well_id, loop_2_request.id)
stub_polymetadata(pm_concentration_nm, loop_2_request.id)
stub_polymetadata(pm_input_amount_available, loop_2_request.id)
stub_polymetadata(pm_input_amount_desired, loop_2_request.id)
stub_polymetadata(pm_sample_volume, loop_2_request.id)
stub_polymetadata(pm_diluent_volume, loop_2_request.id)
stub_polymetadata(pm_pcr_cycles, loop_2_request.id)
stub_polymetadata(pm_hyb_panel, loop_2_request.id)
stub_polymetadata(
[pm_original_plate_barcode, pm_original_well_id, pm_concentration_nm, pm_input_amount_available,
pm_input_amount_desired, pm_sample_volume, pm_diluent_volume, pm_pcr_cycles, pm_hyb_panel],
loop_2_request.id,
'Request'
)
end

it 'makes the expected method calls when creating the child plate' do
Expand Down Expand Up @@ -1548,11 +1545,20 @@
end

it 'updates existing metadata when it exists' do
request_metadata['key1'] = 'new_value1'
allow(Sequencescape::Api::V2::PolyMetadatum).to receive(:find).and_return([existing_metadata_1])
expect(existing_metadata_1).to receive(:update).once.and_return(true)
subject.create_or_update_request_metadata(request, request_metadata, child_well_location)
end

it 'does not update existing metadata when the value is the same' do
allow(Sequencescape::Api::V2::PolyMetadatum).to receive(:find).and_return([existing_metadata_1,
existing_metadata_2])
expect(existing_metadata_1).not_to receive(:update)
expect(existing_metadata_2).not_to receive(:update)
subject.create_or_update_request_metadata(request, request_metadata, child_well_location)
end

it 'raises an error when new metadata fails to save' do
allow(new_metadata_1).to receive(:save).and_return(false)
expect do
Expand All @@ -1561,6 +1567,7 @@
end

it 'raises an error when existing metadata fails to update' do
request_metadata['key1'] = 'new_value1'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how this was passing before as there is a check to ensure update is only called if there is a new value.

allow(Sequencescape::Api::V2::PolyMetadatum).to receive(:find).and_return([existing_metadata_1])
allow(existing_metadata_1).to receive(:update).and_return(false)
expect do
Expand Down
6 changes: 3 additions & 3 deletions spec/support/api_url_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,9 @@ def stub_plate(plate, stub_search: true, custom_query: nil, custom_includes: nil
stub_labware(plate)
end

def stub_polymetadata(polymetadata, metadatable_id)
arguments = [{ key: polymetadata.key, metadatable_id: metadatable_id }]
allow(Sequencescape::Api::V2::PolyMetadatum).to receive(:find).with(*arguments).and_return([polymetadata])
def stub_polymetadata(polymetadata, metadatable_id, metadatable_type)
arguments = [{ metadatable_id:, metadatable_type: }]
allow(Sequencescape::Api::V2::PolyMetadatum).to receive(:find).with(*arguments).and_return(polymetadata)
end

def stub_project(project)
Expand Down
Loading