Class: PlatePurpose
- Inherits:
-
Purpose
- Object
- ActiveRecord::Base
- ApplicationRecord
- Purpose
- PlatePurpose
- Defined in:
- app/models/plate_purpose.rb
Overview
JG: Generally I have been trying to eliminate as much of the purpose specific behaviour as possible, and have pushed the business logic outwards towards the pipeline applications themselves. This is to try and reduce the overall complexity or Sequencescape models, reduce coupling between Sequencescape and its clients, and to make behaviour of individual plates more predictable. This is intended to increase the flexibility and adaptability of the pipelines.
The standard Purpose class for plates. This defines the standard behaviour, and is the class used for the majority of PlatePurposes.
The Purpose of a piece of Labware describes its role in the lab. While most labware will retain a single purpose through their life cycle, it is possible for purpose to be changed. Ideally this should be performed with a PlateConversion to ensure proper tracking.
Historically Purpose has modified the behaviour of its corresponding Labware, with a number of methods, such as Plate#state delegating to Plate#plate_purpose. While this is still occasionally required, it tends to result in quite brittle, unflexible behaviour. More recently we have been trying to push these differences in business logic outwards. In this new approach the Pipeline handles differences in behaviour, and the purpose acts merely as a tag, which can be used to inform the pipeline how it may wish to proceed. This approach makes Labware far more interchangeable.
Information about which purpose classes are used, and their last activity can be generated by running: bundle exec rake report:purposes
in the appropriate environment. (Probably production)
Direct Known Subclasses
DilutionPlatePurpose, AdditionalInput, InitialPurpose, Input, QcableLibraryPlatePurpose, QcablePlatePurpose
Defined Under Namespace
Classes: AdditionalInput, InitialPurpose, Input
Class Method Summary collapse
Instance Method Summary collapse
- #asset_shape ⇒ Object
- #attached?(_plate) ⇒ Boolean
- #cherrypick_completed(plate) ⇒ Object
- #cherrypick_in_rows? ⇒ Boolean
- #child_plate_purposes ⇒ Object
- #create!(*args, &block) ⇒ Object
-
#input_plate=(is_input) ⇒ Object
Set the class to PlatePurpose::Input is set to true.
- #plate_height ⇒ Object
- #plate_width ⇒ Object
-
#pool_wells(wells) ⇒ Object
rubocop:todo Metrics/MethodLength.
- #size ⇒ Object
- #source_wells_for(stock_wells) ⇒ Object
-
#state_of(plate) ⇒ Object
The state of a plate is based on the transfer requests.
Methods included from Api::PlatePurposeIo::Extensions
Methods included from Purpose::Relationship::Associations
Methods inherited from Purpose
#barcode_type, #prefix=, #set_default_barcode_prefix, #source_plate, #source_plates, #source_purpose_name=, #target_class
Methods included from Uuid::Uuidable
included, #unsaved_uuid!, #uuid
Methods included from SharedBehaviour::Named
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
Class Method Details
.stock_plate_purpose ⇒ Object
90 91 92 93 94 95 96 |
# File 'app/models/plate_purpose.rb', line 90 def self.stock_plate_purpose PlatePurpose.create_with( stock_plate: true, cherrypickable_target: true, type: 'PlatePurpose::Input' ).find_or_create_by!(name: 'Stock Plate') end |
Instance Method Details
#asset_shape ⇒ Object
33 34 35 |
# File 'app/models/plate_purpose.rb', line 33 def asset_shape super || AssetShape.default end |
#attached?(_plate) ⇒ Boolean
124 125 126 |
# File 'app/models/plate_purpose.rb', line 124 def attached?(_plate) true end |
#cherrypick_completed(plate) ⇒ Object
40 41 42 |
# File 'app/models/plate_purpose.rb', line 40 def cherrypick_completed(plate) messenger_creators.each { |creator| creator.create!(plate) } end |
#cherrypick_in_rows? ⇒ Boolean
120 121 122 |
# File 'app/models/plate_purpose.rb', line 120 def cherrypick_in_rows? cherrypick_direction == 'row' end |
#child_plate_purposes ⇒ Object
128 129 130 |
# File 'app/models/plate_purpose.rb', line 128 def child_plate_purposes child_purposes.where_is_a(PlatePurpose) end |
#create!(*args, &block) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'app/models/plate_purpose.rb', line 102 def create!(*args, &block) attributes = args. do_not_create_wells = args.first.present? attributes[:size] ||= size attributes[:purpose] = self # Delete these attributes if they exist as create! with barcode param is being deprecated in rails 6.1 # Removed sanger_barcode attribute as its now generated by plate.create_with_barcode! # # 2022-04-20 10:04 - These attributes (barcode) are needed when the test creates a plate with a specific # barcode (and we dont want to access Baracoda in that case) attributes.delete(:barcode) attributes.delete(:barcode_prefix) target_class .(attributes, &block) .tap { |plate| plate.wells.construct! unless do_not_create_wells } end |
#input_plate=(is_input) ⇒ Object
Set the class to PlatePurpose::Input is set to true. Allows creation of the input plate purposes through the API without directly exposing our class names. Note: This could be moved to the V2 API resource when V1 is removed.
63 64 65 |
# File 'app/models/plate_purpose.rb', line 63 def input_plate=(is_input) self.type = 'PlatePurpose::Input' if is_input end |
#plate_height ⇒ Object
44 45 46 |
# File 'app/models/plate_purpose.rb', line 44 def plate_height asset_shape.plate_height(size) end |
#plate_width ⇒ Object
48 49 50 |
# File 'app/models/plate_purpose.rb', line 48 def plate_width asset_shape.plate_width(size) end |
#pool_wells(wells) ⇒ Object
rubocop:todo Metrics/MethodLength
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'app/models/plate_purpose.rb', line 67 def pool_wells(wells) # rubocop:todo Metrics/MethodLength _pool_wells(wells) .joins( # rubocop:todo Layout/LineLength 'LEFT OUTER JOIN uuids AS pool_uuids ON pool_uuids.resource_type="Submission" AND pool_uuids.resource_id=submission_id' # rubocop:enable Layout/LineLength ) .select('pool_uuids.external_id AS pool_uuid') .readonly(false) .tap do |wells_with_pool| if wells_with_pool.group_by(&:id).any? { |_, multiple_pools| multiple_pools.uniq.size > 1 } raise StandardError, 'Cannot deal with a well in multiple pools' end end end |
#size ⇒ Object
98 99 100 |
# File 'app/models/plate_purpose.rb', line 98 def size super || 96 end |
#source_wells_for(stock_wells) ⇒ Object
132 133 134 |
# File 'app/models/plate_purpose.rb', line 132 def source_wells_for(stock_wells) stock_wells end |
#state_of(plate) ⇒ Object
The state of a plate is based on the transfer requests.
53 54 55 |
# File 'app/models/plate_purpose.rb', line 53 def state_of(plate) plate.state_from(plate.transfer_requests) end |