Skip to content

Commit

Permalink
Merge pull request #4426 from sanger/Y24-190-fix-api-v2-transfers
Browse files Browse the repository at this point in the history
Y24-190: Fix API v2 transfers
  • Loading branch information
sdjmchattie authored Oct 18, 2024
2 parents 46b3976 + 3b99e65 commit 6dbedb7
Show file tree
Hide file tree
Showing 54 changed files with 691 additions and 877 deletions.
13 changes: 6 additions & 7 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ Lint/UselessAssignment:
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
Metrics/AbcSize:
Exclude:
- 'app/controllers/api/v2/transfers/transfers_controller.rb'
- 'app/controllers/api/v2/transfers_controller.rb'
- 'app/jobs/export_pool_xp_to_traction_job.rb'
- 'app/sample_manifest_excel/sample_manifest_excel/manifest_type_list.rb'

Expand Down Expand Up @@ -717,7 +717,7 @@ RSpec/ExampleLength:
- 'spec/requests/api/v2/shared_examples/api_key_authenticatable.rb'
- 'spec/requests/api/v2/tag_layout_templates_spec.rb'
- 'spec/requests/api/v2/tag_layouts_spec.rb'
- 'spec/requests/api/v2/transfers/transfers_spec.rb'
- 'spec/requests/api/v2/transfers_spec.rb'
- 'spec/requests/api/v2/tube_purposes_spec.rb'
- 'spec/requests/api/v2/users_spec.rb'
- 'spec/requests/api/v2/volume_update_spec.rb'
Expand All @@ -736,7 +736,6 @@ RSpec/ExampleLength:
- 'spec/resources/api/v2/sample_metadata_resource_spec.rb'
- 'spec/resources/api/v2/submission_resource_spec.rb'
- 'spec/resources/api/v2/tag_group_resource_spec.rb'
- 'spec/resources/api/v2/transfers/transfer_resource_spec.rb'
- 'spec/resources/api/v2/tube_rack_resource_spec.rb'
- 'spec/resources/api/v2/tube_resource_spec.rb'
- 'spec/sample_manifest_excel/configuration_spec.rb'
Expand Down Expand Up @@ -1085,7 +1084,7 @@ RSpec/MultipleExpectations:
- 'spec/requests/api/v2/transfer_request_collections_spec.rb'
- 'spec/requests/api/v2/transfer_requests_spec.rb'
- 'spec/requests/api/v2/transfer_templates_spec.rb'
- 'spec/requests/api/v2/transfers/transfers_spec.rb'
- 'spec/requests/api/v2/transfers_spec.rb'
- 'spec/requests/api/v2/tube_purposes_spec.rb'
- 'spec/requests/api/v2/tube_racks_spec.rb'
- 'spec/requests/api/v2/tubes_spec.rb'
Expand Down Expand Up @@ -1271,7 +1270,7 @@ RSpec/MultipleMemoizedHelpers:
- 'spec/requests/api/v2/state_changes_spec.rb'
- 'spec/requests/api/v2/tag_layouts_spec.rb'
- 'spec/requests/api/v2/transfer_request_collections_spec.rb'
- 'spec/requests/api/v2/transfers/transfers_spec.rb'
- 'spec/requests/api/v2/transfers_spec.rb'
- 'spec/requests/api/v2/tube_from_tube_creations_spec.rb'
- 'spec/requests/api/v2/wells_spec.rb'
- 'spec/requests/plate_picks_request_spec.rb'
Expand Down Expand Up @@ -1434,7 +1433,7 @@ RSpec/NestedGroups:
- 'spec/requests/api/v2/state_changes_spec.rb'
- 'spec/requests/api/v2/tag_layouts_spec.rb'
- 'spec/requests/api/v2/transfer_request_collections_spec.rb'
- 'spec/requests/api/v2/transfers/transfers_spec.rb'
- 'spec/requests/api/v2/transfers_spec.rb'
- 'spec/requests/api/v2/tube_from_tube_creations_spec.rb'
- 'spec/requests/api/v2/users_spec.rb'
- 'spec/sample_manifest_excel/upload/processor_spec.rb'
Expand Down Expand Up @@ -2424,7 +2423,7 @@ Style/StringConcatenation:
Style/SuperArguments:
Exclude:
- 'app/api/model_extensions/order.rb'
- 'app/controllers/api/v2/transfers/transfers_controller.rb'
- 'app/controllers/api/v2/transfers_controller.rb'
- 'app/models/broadcast_event/plate_cherrypicked.rb'
- 'app/models/pipeline.rb'
- 'app/models/plate_purpose/additional_input.rb'
Expand Down
75 changes: 0 additions & 75 deletions app/controllers/api/v2/transfers/transfers_controller.rb

This file was deleted.

33 changes: 33 additions & 0 deletions app/controllers/api/v2/transfers_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module Api
module V2
# Provides a JSON API controller for Transfers.
# See: http://jsonapi-resources.com/ for JSONAPI::Resource documentation.
class TransfersController < JSONAPI::ResourceController
# By default JSONAPI::ResourceController provides most of the standard behaviour.
# However in this case we want to redirect create and update operations to the correct polymorphic type.

def process_operations(operations)
# We need to determine the polymorphic type of the transfer to create based on any template provided.
operations.each do |operation|
# Neither data nor attributes are guaranteed among the operation options.
attributes = operation.options.fetch(:data, {}).fetch(:attributes, {})

# Skip the operation if it does not contain a transfer template.
next unless attributes.key?(:transfer_template_uuid)

# Get the transfer template and use it to update the context and attributes.
template = TransferTemplate.with_uuid(attributes[:transfer_template_uuid]).first
operation.options[:context][:polymorphic_type] = template.transfer_class_name
attributes[:transfers] = template.transfers if template.transfers.present?

# Remove the UUID of the transfer template from the attributes.
attributes.delete(:transfer_template_uuid)
end

super(operations)
end
end
end
end
12 changes: 12 additions & 0 deletions app/models/transfer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,15 @@ def should_well_not_be_transferred?(well)
well.nil? or well.aliquots.empty? or well.failed? or well.cancelled?
end
end

# Required for the descendants method to work when eager loading is off in test
require_dependency 'transfer/between_plate_and_tubes'
require_dependency 'transfer/between_plates_by_submission'
require_dependency 'transfer/between_plates'
require_dependency 'transfer/between_specific_tubes'
require_dependency 'transfer/between_tubes_by_submission'
require_dependency 'transfer/from_plate_to_specific_tubes_by_pool'
require_dependency 'transfer/from_plate_to_specific_tubes'
require_dependency 'transfer/from_plate_to_tube_by_multiplex'
require_dependency 'transfer/from_plate_to_tube_by_submission'
require_dependency 'transfer/from_plate_to_tube'
14 changes: 7 additions & 7 deletions app/resources/api/v2/aliquot_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ class AliquotResource < BaseResource
has_one :library

# Attributes
attribute :tag_oligo, readonly: true
attribute :tag_index, readonly: true
attribute :tag2_oligo, readonly: true
attribute :tag2_index, readonly: true
attribute :suboptimal, readonly: true
attribute :library_type, readonly: true
attribute :insert_size_to, readonly: true
attribute :tag_oligo, write_once: true
attribute :tag_index, write_once: true
attribute :tag2_oligo, write_once: true
attribute :tag2_index, write_once: true
attribute :suboptimal, write_once: true
attribute :library_type, write_once: true
attribute :insert_size_to, write_once: true

# Filters

Expand Down
15 changes: 2 additions & 13 deletions app/resources/api/v2/bait_library_layout_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class BaitLibraryLayoutResource < BaseResource
# @param value [String] The UUID of the plate for this bait library layout.
# @return [Void]
# @see #plate
attribute :plate_uuid
attribute :plate_uuid, writeonly: true

def plate_uuid=(value)
@model.plate = Plate.with_uuid(value).first
Expand All @@ -35,7 +35,7 @@ def plate_uuid=(value)
# @param value [String] The UUID of the user who created this bait library layout.
# @return [Void]
# @see #user
attribute :user_uuid
attribute :user_uuid, writeonly: true

def user_uuid=(value)
@model.user = User.with_uuid(value).first
Expand Down Expand Up @@ -64,17 +64,6 @@ def user_uuid=(value)
# @return [PlateResource] The plate for this bait library layout.
# @note This relationship is required.
has_one :plate

def self.creatable_fields(context)
# The layout is generated by the system.
# The UUID is set by the system.
super - %i[layout uuid]
end

def fetchable_fields
# UUIDs for relationships are not fetchable. They should be accessed via the relationship itself.
super - %i[plate_uuid user_uuid]
end
end
end
end
2 changes: 1 addition & 1 deletion app/resources/api/v2/barcode_printer_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class BarcodePrinterResource < BaseResource

# @!attribute [r] name
# @return [String] the name of the barcode printer.
attribute :name
attribute :name, readonly: true

# @!attribute [r] uuid
# @return [String] the UUID of the barcode printer.
Expand Down
21 changes: 15 additions & 6 deletions app/resources/api/v2/base_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,27 @@ class BaseResource < JSONAPI::Resource
Plate.descendants.each { |subclass| model_hint model: subclass, resource: :plate }
Tube.descendants.each { |subclass| model_hint model: subclass, resource: :tube }
Request.descendants.each { |subclass| model_hint model: subclass, resource: :request }
Transfer.descendants.each { |subclass| model_hint model: subclass, resource: :transfer }

# This extension allows the readonly property to be used on attributes/relationships
# prior to the 0.10 upgrade. This avoids the need to override updatable_fields on
# every resource. Readonly does not work on attributes in 0.9 by default
# These extensions allow the use of readonly, write_once and writeonly properties.
# readonly - The attribute/relationship can be read but not written to.
# write_once - The attribute/relationship can be written to once on creation but not updated.
# writeonly - The attribute/relationship can be written to but not read.
# This avoids the need to override self.creatable_fields, self.updatable_fields and fetchable_fields on every
# resource.
# readonly does not work on attributes in JSONAPI:Resources 0.9 by default.
# This can be removed as soon as we update to 0.10, which is currently only in alpha
def self.updatable_fields(context)

def self.creatable_fields(context)
super - _attributes.select { |_attr, options| options[:readonly] }.keys -
_relationships.select { |_rel_key, rel| rel.options[:readonly] }.keys
end

# This extension allows the writeonly property to be used on attributes/relationships.
# This avoids the need to override fetchable_fields on every resource.
def self.updatable_fields(context)
super - _attributes.select { |_attr, options| options[:readonly] || options[:write_once] }.keys -
_relationships.select { |_rel_key, rel| rel.options[:readonly] || rel.options[:write_once] }.keys
end

def fetchable_fields
super - self.class._attributes.select { |_attr, options| options[:writeonly] }.keys -
self.class._relationships.select { |_rel_key, rel| rel.options[:writeonly] }.keys
Expand Down
4 changes: 2 additions & 2 deletions app/resources/api/v2/comment_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class CommentResource < BaseResource
has_one :commentable, polymorphic: true

# Attributes
attribute :title, readonly: true
attribute :description, readonly: true
attribute :title, write_once: true
attribute :description, write_once: true
attribute :created_at, readonly: true
attribute :updated_at, readonly: true

Expand Down
20 changes: 3 additions & 17 deletions app/resources/api/v2/custom_metadatum_collection_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,19 @@ class CustomMetadatumCollectionResource < BaseResource

# @!attribute [r] uuid
# @return [String] The UUID of the collection.
attribute :uuid
attribute :uuid, readonly: true

# @!attribute [rw] user_id
# @return [Int] The ID of the user who created this collection. Can only and must be set on creation.
attribute :user_id
attribute :user_id, write_once: true

# @!attribute [rw] asset_id
# @return [Int] The ID of the labware the metadata corresponds to. Can only and must be set on creation.
attribute :asset_id
attribute :asset_id, write_once: true

# @!attribute [rw] metadata
# @return [Hash] All metadata in this collection.
attribute :metadata

###
# Allowable fields (defining read/write permissions for POST and PATCH)
###

# @return [Array<Symbol>] Fields that can be created in a POST request.
def self.creatable_fields(context)
super - %i[uuid]
end

# @return [Array<Symbol>] Fields that can be updated in a PATCH request.
def self.updatable_fields(context)
super - %i[uuid user_id asset_id] # PATCH should only update metadata
end
end
end
end
2 changes: 1 addition & 1 deletion app/resources/api/v2/lot_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class LotResource < BaseResource

# Attributes
attribute :uuid, readonly: true
attribute :lot_number, readonly: true
attribute :lot_number, write_once: true

# Filters

Expand Down
6 changes: 3 additions & 3 deletions app/resources/api/v2/lot_type_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ class LotTypeResource < BaseResource
default_includes :uuid_object

# Associations:
has_one :target_purpose, readonly: true, class_name: 'Purpose'
has_one :target_purpose, write_once: true, class_name: 'Purpose'

# Attributes
attribute :uuid, readonly: true
attribute :name, readonly: true
attribute :template_type, readonly: true
attribute :name, write_once: true
attribute :template_type, write_once: true

# Filters

Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v2/order_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class OrderResource < BaseResource

# Attributes
attribute :uuid, readonly: true
attribute :request_options, readonly: true
attribute :request_options, write_once: true

# Filters

Expand Down
4 changes: 2 additions & 2 deletions app/resources/api/v2/pick_list_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class PickListResource < BaseResource
# Attributes
attribute :created_at, readonly: true
attribute :updated_at, readonly: true
attribute :state, readonly: true
attribute :links, readonly: true
attribute :state, write_once: true
attribute :links, write_once: true

attribute :pick_attributes
attribute :labware_pick_attributes, writeonly: true
Expand Down
Loading

0 comments on commit 6dbedb7

Please sign in to comment.