Skip to content

Commit

Permalink
Merge pull request #716 from sanger/develop
Browse files Browse the repository at this point in the history
Merging develop to master
  • Loading branch information
seenanair authored Jan 17, 2025
2 parents 9444327 + efee450 commit 39d58f3
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .release-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.23.0
1.24.0
66 changes: 34 additions & 32 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actionpack (7.0.8.5)
actionview (= 7.0.8.5)
activesupport (= 7.0.8.5)
actionpack (7.0.8.7)
actionview (= 7.0.8.7)
activesupport (= 7.0.8.7)
rack (~> 2.0, >= 2.2.4)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (7.0.8.5)
activesupport (= 7.0.8.5)
actionview (7.0.8.7)
activesupport (= 7.0.8.7)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activemodel (7.0.8.5)
activesupport (= 7.0.8.5)
activerecord (7.0.8.5)
activemodel (= 7.0.8.5)
activesupport (= 7.0.8.5)
activesupport (7.0.8.5)
activemodel (7.0.8.7)
activesupport (= 7.0.8.7)
activerecord (7.0.8.7)
activemodel (= 7.0.8.7)
activesupport (= 7.0.8.7)
activesupport (7.0.8.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
Expand All @@ -44,7 +44,7 @@ GEM
crass (1.0.6)
diff-lcs (1.5.1)
docile (1.4.0)
erubi (1.13.0)
erubi (1.13.1)
factory_bot (6.5.0)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.4)
Expand Down Expand Up @@ -73,23 +73,23 @@ GEM
hashie (5.0.0)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
json (2.8.2)
json (2.9.1)
language_server-protocol (3.17.0.3)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.23.1)
loofah (2.24.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
lumberjack (1.2.10)
method_source (1.1.0)
mini_portile2 (2.8.8)
minitest (5.25.2)
minitest (5.25.4)
msgpack (1.7.2)
multi_json (1.15.0)
mysql2 (0.5.6)
nenv (0.3.0)
nokogiri (1.16.7)
nokogiri (1.18.1)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
notiffany (0.1.3)
Expand All @@ -99,23 +99,23 @@ GEM
parser (3.3.6.0)
ast (~> 2.4.1)
racc
pry (0.15.0)
pry (0.15.2)
coderay (~> 1.1)
method_source (~> 1.0)
racc (1.8.1)
rack (2.2.10)
rack-test (2.1.0)
rack-test (2.2.0)
rack (>= 1.3)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.0)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.0.8.5)
actionpack (= 7.0.8.5)
activesupport (= 7.0.8.5)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
railties (7.0.8.7)
actionpack (= 7.0.8.7)
activesupport (= 7.0.8.7)
method_source
rake (>= 12.2)
thor (~> 1.0)
Expand All @@ -126,7 +126,7 @@ GEM
rb-inotify (0.11.1)
ffi (~> 1.0)
rbtree (0.4.6)
regexp_parser (2.9.2)
regexp_parser (2.10.0)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
Expand All @@ -148,22 +148,22 @@ GEM
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.1)
rubocop (1.68.0)
rubocop (1.69.2)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.4, < 3.0)
rubocop-ast (>= 1.32.2, < 2.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.36.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.36.1)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.37.0)
parser (>= 3.3.1.0)
rubocop-performance (1.23.0)
rubocop-performance (1.23.1)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rails (2.27.0)
rubocop-rails (2.28.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.52.0, < 2.0)
Expand All @@ -190,7 +190,9 @@ GEM
thor (1.3.2)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.6.0)
unicode-display_width (3.1.3)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
zeitwerk (2.7.1)

PLATFORMS
Expand Down
2 changes: 1 addition & 1 deletion app/models/aliquot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This model is used to store aliquot data
class Aliquot < ApplicationRecord
include ResourceTools
include SingularResourceTools
include SingularResourceVersionedTools

def self.base_resource_key
'aliquot_uuid'
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20241211144506_add_hu_m_fre_code_to_sample.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddHuMFreCodeToSample < ActiveRecord::Migration[7.0]
def change
add_column :sample, :huMFre_code, :string, limit: 16
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_12_03_134455) do
ActiveRecord::Schema[7.0].define(version: 2024_12_11_144506) do
create_table "aliquot", charset: "utf8mb3", collation: "utf8mb3_unicode_ci", force: :cascade do |t|
t.string "id_lims", null: false, comment: "The LIMS system that the aliquot was created in"
t.string "aliquot_uuid", null: false, comment: "The UUID of the aliquot in the LIMS system"
Expand Down Expand Up @@ -366,6 +366,7 @@
t.string "gc_content"
t.string "dna_source"
t.string "priority_level", comment: "Priority level eg Medium, High etc"
t.string "huMFre_code", limit: 16
t.index ["accession_number"], name: "sample_accession_number_index"
t.index ["id_lims", "id_sample_lims"], name: "index_sample_on_id_lims_and_id_sample_lims", unique: true
t.index ["id_lims"], name: "index_sample_on_id_lims"
Expand Down
51 changes: 51 additions & 0 deletions lib/singular_resource_versioned_tools.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

# This module is used to store the latest version of a record and manage versioned records.
# It provides methods to check if a record is the latest and if any attributes have changed,
# and to create or update records accordingly. This ensures an audit trail of updates by
# creating new records when necessary.
module SingularResourceVersionedTools
extend ActiveSupport::Concern

EXCLUDED_ATTRIBUTES = %w[id created_at updated_at last_updated recorded_at].freeze

# Checks if the attributes of the given record have changed and if the given record is more recent.
# If both conditions are met, returns true. Otherwise, returns false.
#
# @param other [ActiveRecord::Base] The record to compare with.
# @return [Boolean] Returns true if the given record is the latest and has changed, false otherwise.
#
# Note: This method is used to ensure that only the most recent and changed records are processed,
# maintaining an audit trail of updates.
def latest?(other)
attributes_changed?(other) && (other.last_updated > last_updated)
end

# Compares the attributes of the current record with the given record, excluding 'id', 'created_at', and 'updated_at'.
#
# @param other [ActiveRecord::Base] The record to compare with.
# @return [Boolean] Returns true if the attributes have changed, false otherwise.
def attributes_changed?(other)
attributes.except(*EXCLUDED_ATTRIBUTES) != other.attributes.except(*EXCLUDED_ATTRIBUTES)
end

# This module is used to create or update a record
module ClassMethods
# Creates a record based on the given attributes.
# If an existing record with the same base resource key is found, it checks if the new record is the latest
# and if any attributes have changed. If both conditions are met, it creates a new record to maintain an audit trail.
#
# @param attributes [Hash] The attributes of the record to create or update which is an instance of Aliquot::JsonHandler.
# @return [ActiveRecord::Base] Returns the created record.
def create_or_update(attributes)
new_record = new(attributes.to_hash)

existing_record = for_lims(attributes.id_lims).with_id(attributes[base_resource_key]).order(last_updated: :desc)
.first
return unless existing_record.nil? || existing_record.latest?(new_record)

create!(attributes.to_hash)
end
private :create_or_update
end
end
40 changes: 22 additions & 18 deletions spec/models/aliquot_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,30 @@
require 'spec_helper'

describe Aliquot do
context 'aliquot' do
let(:example_lims) { 'example' }
let(:example_lims) { 'example' }
let(:attribute_to_change) { 'volume' }
let(:new_value) { 10.0 }

let(:json) do
{ 'id_lims' => 'example',
'aliquot_type' => 'DNA',
'volume' => 5.43,
'concentration' => 2.34,
'insert_size' => 100,
'aliquot_uuid' => '000000-0000-0000-0000-0000000002',
'source_type' => 'library',
'source_barcode' => 'PR-rna-00000001_H12',
'sample_name' => 'aliquot-sample',
'used_by_type' => 'pool',
'used_by_barcode' => 'pool-barcode',
'last_updated' => '2012-03-11 10:20:08',
'recorded_at' => '2012-03-11 10:20:08',
'created_at' => '2012-03-11 10:20:08' }
end
let(:json) do
{ 'id_lims' => 'example',
'aliquot_type' => 'DNA',
'volume' => 5.43,
'concentration' => 2.34,
'insert_size' => 100,
'aliquot_uuid' => '000000-0000-0000-0000-0000000002',
'source_type' => 'library',
'source_barcode' => 'PR-rna-00000001_H12',
'sample_name' => 'aliquot-sample',
'used_by_type' => 'pool',
'used_by_barcode' => 'pool-barcode',
'last_updated' => '2012-03-11 10:20:08',
'recorded_at' => '2012-03-11 10:20:08',
'created_at' => '2012-03-11 10:20:08' }
end

it_behaves_like 'a singular resource versioned'

context 'aliquot' do
it 'saves the correct resource' do
expect(described_class.create_or_update_from_json(json, example_lims)).to be_truthy
end
Expand Down
Loading

0 comments on commit 39d58f3

Please sign in to comment.