Class: TransferRequestCollection

Inherits:
ApplicationRecord show all
Includes:
Uuid::Uuidable
Defined in:
app/models/transfer_request_collection.rb

Overview

A transfer request collection provides a means of bulk creating transfer requests between arbitrary sources and destinations. Used to provide a means of bulk creating transfer requests via the API

Defined Under Namespace

Classes: UuidCache

Instance Method Summary collapse

Methods included from Uuid::Uuidable

included, #unsaved_uuid!, #uuid

Methods inherited from ApplicationRecord

alias_association, convert_labware_to_receptacle_for, find_by_id_or_name, find_by_id_or_name!

Methods included from Squishify

extended

Instance Method Details

#extract_asset_ids(args) ⇒ Object

Args is an array of transfer request parameters (in hash format) We extract any referenced asset and target asset ids into an array.



109
110
111
112
113
114
115
# File 'app/models/transfer_request_collection.rb', line 109

def extract_asset_ids(args)
  args.each_with_object([]) do |param, asset_ids|
    param.stringify_keys!
    asset_ids << param['asset_id'] if param['asset_id']
    asset_ids << param['target_asset_id'] if param['target_asset_id']
  end
end

#transfer_requests_attributes=(args) ⇒ Object

These are optimizations to reduce the number of queries that need to be performed while the transfer takes place. Transfer requests rely both on the aliquots in an assets, and the transfer requests into the asset (used to track state). Here we eager load all necessary assets and associated records, and pass them to the transfer requests directly.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'app/models/transfer_request_collection.rb', line 91

def transfer_requests_attributes=(args) # rubocop:todo Metrics/MethodLength
  asset_ids = extract_asset_ids(args)
  asset_cache =
    Receptacle
      .includes(:aliquots, :transfer_requests_as_target, requests: :request_metadata, labware: :purpose)
      .find(asset_ids)
      .index_by(&:id)
  optimized_parameters =
    args.map do |param|
      param['asset'] ||= asset_cache[param.delete('asset_id')]
      param['target_asset'] ||= asset_cache[param.delete('target_asset_id')]
      param
    end
  super(optimized_parameters)
end

#transfer_requests_io=(parameters) ⇒ Object

The api is terrible at handling nested has_many relationships This caches all our UUIDs in one query, and extracts the ids rubocop:todo Metrics/MethodLength



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'app/models/transfer_request_collection.rb', line 60

def transfer_requests_io=(parameters) # rubocop:todo Metrics/AbcSize
  uuid_cache = UuidCache.new(parameters)

  updated_attributes =
    parameters.map do |parameter|
      if parameter['source_asset'].is_a?(String)
        parameter['asset_id'] = uuid_cache.find(Receptacle, parameter.delete('source_asset'))
      end
      parameter['asset'] = parameter.delete('source_asset') if parameter['source_asset'].present?
      if parameter['target_asset'].is_a?(String)
        parameter['target_asset_id'] = uuid_cache.find(Receptacle, parameter.delete('target_asset'))
      end
      if parameter['submission'].is_a?(String)
        parameter['submission_id'] = uuid_cache.find(Submission, parameter.delete('submission'))
      end
      if parameter['outer_request'].is_a?(String)
        parameter['outer_request_id'] = uuid_cache.find(Request, parameter.delete('outer_request'))
      end
      parameter
    end

  self.transfer_requests_attributes = updated_attributes
end