Class: Sequence
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Sequence
- Includes:
- Housekeeping, Shared::AlternateValues, Shared::Confidences, Shared::DataAttributes, Shared::Documentation, Shared::HasPapertrail, Shared::Identifiers, Shared::IsData, Shared::Notes, Shared::OriginRelationship, Shared::ProtocolRelationships, Shared::Tags
- Defined in:
- app/models/sequence.rb
Overview
A DNA, RNA, or Amino Acid, as defined by a string of letters. All other attributes are stored in related tables, the overal model is basically a graph with nodes having attributes.
Constant Summary collapse
- ALTERNATE_VALUES_FOR =
[:name].freeze
Instance Attribute Summary collapse
-
#describe_with ⇒ Object
Pass a Gene::Descriptor instance to clone that description to this sequence.
-
#name ⇒ String
The asserted name for this sequence, typically the target gene name like “CO1”.
-
#sequence ⇒ String
The letters representing the sequence.
-
#sequence_type ⇒ String
One of “DNA”, “RNA”, “AA”.
Class Method Summary collapse
-
.select_optimized(user_id, project_id, target = nil) ⇒ Hash
Otus optimized for user selection.
-
.used_recently(user_id, project_id, used_on = nil) ⇒ Scope
The max 10 most recently used otus, as ‘used_on`.
Instance Method Summary collapse
- #build_relationships ⇒ Object protected
- #normalize_sequence_type ⇒ Object protected
Methods included from Shared::IsData
#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_destroyable?, #is_editable?, #is_in_use?, #is_in_users_projects?, #metamorphosize, #similar
Methods included from Shared::HasPapertrail
#attribute_updated, #attribute_updater
Methods included from Shared::Tags
#reject_tags, #tag_with, #tagged?, #tagged_with?
Methods included from Shared::ProtocolRelationships
#protocolled?, #reject_protocols
Methods included from Shared::OriginRelationship
#new_objects, #old_objects, #reject_origin_relationships, #set_origin
Methods included from Shared::Notes
#concatenated_notes_string, #reject_notes
Methods included from Shared::Identifiers
#dwc_occurrence_id, #identified?, #next_by_identifier, #previous_by_identifier, #reject_identifiers, #uri, #uuid
Methods included from Shared::Documentation
#document_array=, #documented?, #reject_documentation, #reject_documents
Methods included from Shared::Confidences
Methods included from Shared::DataAttributes
#import_attributes, #internal_attributes, #keyword_value_hash, #reject_data_attributes
Methods included from Shared::AlternateValues
#all_values_for, #alternate_valued?
Methods included from Housekeeping
#has_polymorphic_relationship?
Methods inherited from ApplicationRecord
Instance Attribute Details
#describe_with ⇒ Object
Pass a Gene::Descriptor instance to clone that description to this sequence
44 45 46 |
# File 'app/models/sequence.rb', line 44 def describe_with @describe_with end |
#name ⇒ String
Returns the asserted name for this sequence, typically the target gene name like “CO1”. Important! The preferred mechanism for assinging this type of label to a sequence is assigning pertinent metadata (relationships to other sequences) and then inferrning that those sequences with particular metadata have a specific gene name (Descriptor::Gene#name).
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'app/models/sequence.rb', line 22 class Sequence < ApplicationRecord include Housekeeping include Shared::AlternateValues include Shared::DataAttributes include Shared::Confidences include Shared::Documentation include Shared::Identifiers include Shared::Notes include Shared::OriginRelationship include Shared::ProtocolRelationships include Shared::Tags include Shared::HasPapertrail include Shared::IsData is_origin_for 'Sequence' originates_from 'Extract', 'Specimen', 'Lot', 'RangedLot', 'Sequence' ALTERNATE_VALUES_FOR = [:name].freeze # Pass a Gene::Descriptor instance to clone that description to this sequence attr_accessor :describe_with has_many :sequence_relationships, foreign_key: :subject_sequence_id, inverse_of: :subject_sequence # this sequence describes others has_many :sequences, through: :sequence_relationships, source: :object_sequence has_many :related_sequence_relationships, class_name: 'SequenceRelationship', foreign_key: :object_sequence_id, inverse_of: :object_sequence # attributes of this sequence has_many :related_sequences, through: :related_sequence_relationships, source: :subject_sequence has_many :gene_attributes, inverse_of: :sequence # has_many :descriptors, through: :gene_attributes, inverse_of: :sequences, as: 'Descriptor::Gene' before_validation :build_relationships, if: -> {describe_with.present?} before_validation :normalize_sequence_type SequenceRelationship.descendants.each do |d| t = d.name.demodulize.tableize.singularize relationships = "#{t}_relationships".to_sym sequences = "#{t}_sequences".to_sym has_many relationships, class_name: d.name.to_s, foreign_key: :object_sequence_id, inverse_of: :object_sequence has_many sequences, class_name: 'Sequence', through: relationships, source: :subject_sequence, inverse_of: :sequences accepts_nested_attributes_for sequences accepts_nested_attributes_for relationships end validates_presence_of :sequence validates_inclusion_of :sequence_type, in: ['DNA', 'RNA', 'AA'] # @param used_on [String] required, one of `GeneAttribute` or `SequenceRelationship` # @return [Scope] # the max 10 most recently used otus, as `used_on` def self.used_recently(user_id, project_id, used_on = nil) return Sequence.none if used_on.nil? t = case used_on when 'GeneAttribute' GeneAttribute.arel_table when 'SequenceRelationship' SequenceRelationship.arel_table end p = Sequence.arel_table # i is a select manager i = t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['updated_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # i is a select manager i = case used_on when 'SequenceRelationship' t.project(t['object_sequence_id'], t['updated_at']).from(t) .where( t['updated_at'].gt(1.weeks.ago) ) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) else t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) end # z is a table alias z = i.as('recent_t') j = case used_on when 'SequenceRelationship' Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new( z['object_sequence_id'].eq(p['id']) )) else Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['sequence_id'].eq(p['id']))) end Sequence.joins(j).pluck(:sequence_id).uniq end # @params target [String] one of nil, 'SequenceRelationship', 'GeneAttribute' # @return [Hash] otus optimized for user selection def self.select_optimized(user_id, project_id, target = nil) r = used_recently(user_id, project_id, target) h = { recent: [], quick: [], pinboard: Sequence.pinned_by(user_id).where(project_id: project_id).to_a } if r.empty? h[:quick] = Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a else h[:recent] = Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a h[:quick] = (Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a + Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a).uniq end h end protected def build_relationships describe_with.gene_attributes.each do |ga| .build(subject_sequence: ga.sequence, type: ga.sequence_relationship_type) end end def normalize_sequence_type sequence_type.to_s.upcase! if sequence_type.present? end end |
#sequence ⇒ String
Returns the letters representing the sequence.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'app/models/sequence.rb', line 22 class Sequence < ApplicationRecord include Housekeeping include Shared::AlternateValues include Shared::DataAttributes include Shared::Confidences include Shared::Documentation include Shared::Identifiers include Shared::Notes include Shared::OriginRelationship include Shared::ProtocolRelationships include Shared::Tags include Shared::HasPapertrail include Shared::IsData is_origin_for 'Sequence' originates_from 'Extract', 'Specimen', 'Lot', 'RangedLot', 'Sequence' ALTERNATE_VALUES_FOR = [:name].freeze # Pass a Gene::Descriptor instance to clone that description to this sequence attr_accessor :describe_with has_many :sequence_relationships, foreign_key: :subject_sequence_id, inverse_of: :subject_sequence # this sequence describes others has_many :sequences, through: :sequence_relationships, source: :object_sequence has_many :related_sequence_relationships, class_name: 'SequenceRelationship', foreign_key: :object_sequence_id, inverse_of: :object_sequence # attributes of this sequence has_many :related_sequences, through: :related_sequence_relationships, source: :subject_sequence has_many :gene_attributes, inverse_of: :sequence # has_many :descriptors, through: :gene_attributes, inverse_of: :sequences, as: 'Descriptor::Gene' before_validation :build_relationships, if: -> {describe_with.present?} before_validation :normalize_sequence_type SequenceRelationship.descendants.each do |d| t = d.name.demodulize.tableize.singularize relationships = "#{t}_relationships".to_sym sequences = "#{t}_sequences".to_sym has_many relationships, class_name: d.name.to_s, foreign_key: :object_sequence_id, inverse_of: :object_sequence has_many sequences, class_name: 'Sequence', through: relationships, source: :subject_sequence, inverse_of: :sequences accepts_nested_attributes_for sequences accepts_nested_attributes_for relationships end validates_presence_of :sequence validates_inclusion_of :sequence_type, in: ['DNA', 'RNA', 'AA'] # @param used_on [String] required, one of `GeneAttribute` or `SequenceRelationship` # @return [Scope] # the max 10 most recently used otus, as `used_on` def self.used_recently(user_id, project_id, used_on = nil) return Sequence.none if used_on.nil? t = case used_on when 'GeneAttribute' GeneAttribute.arel_table when 'SequenceRelationship' SequenceRelationship.arel_table end p = Sequence.arel_table # i is a select manager i = t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['updated_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # i is a select manager i = case used_on when 'SequenceRelationship' t.project(t['object_sequence_id'], t['updated_at']).from(t) .where( t['updated_at'].gt(1.weeks.ago) ) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) else t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) end # z is a table alias z = i.as('recent_t') j = case used_on when 'SequenceRelationship' Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new( z['object_sequence_id'].eq(p['id']) )) else Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['sequence_id'].eq(p['id']))) end Sequence.joins(j).pluck(:sequence_id).uniq end # @params target [String] one of nil, 'SequenceRelationship', 'GeneAttribute' # @return [Hash] otus optimized for user selection def self.select_optimized(user_id, project_id, target = nil) r = used_recently(user_id, project_id, target) h = { recent: [], quick: [], pinboard: Sequence.pinned_by(user_id).where(project_id: project_id).to_a } if r.empty? h[:quick] = Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a else h[:recent] = Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a h[:quick] = (Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a + Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a).uniq end h end protected def build_relationships describe_with.gene_attributes.each do |ga| .build(subject_sequence: ga.sequence, type: ga.sequence_relationship_type) end end def normalize_sequence_type sequence_type.to_s.upcase! if sequence_type.present? end end |
#sequence_type ⇒ String
Returns one of “DNA”, “RNA”, “AA”.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'app/models/sequence.rb', line 22 class Sequence < ApplicationRecord include Housekeeping include Shared::AlternateValues include Shared::DataAttributes include Shared::Confidences include Shared::Documentation include Shared::Identifiers include Shared::Notes include Shared::OriginRelationship include Shared::ProtocolRelationships include Shared::Tags include Shared::HasPapertrail include Shared::IsData is_origin_for 'Sequence' originates_from 'Extract', 'Specimen', 'Lot', 'RangedLot', 'Sequence' ALTERNATE_VALUES_FOR = [:name].freeze # Pass a Gene::Descriptor instance to clone that description to this sequence attr_accessor :describe_with has_many :sequence_relationships, foreign_key: :subject_sequence_id, inverse_of: :subject_sequence # this sequence describes others has_many :sequences, through: :sequence_relationships, source: :object_sequence has_many :related_sequence_relationships, class_name: 'SequenceRelationship', foreign_key: :object_sequence_id, inverse_of: :object_sequence # attributes of this sequence has_many :related_sequences, through: :related_sequence_relationships, source: :subject_sequence has_many :gene_attributes, inverse_of: :sequence # has_many :descriptors, through: :gene_attributes, inverse_of: :sequences, as: 'Descriptor::Gene' before_validation :build_relationships, if: -> {describe_with.present?} before_validation :normalize_sequence_type SequenceRelationship.descendants.each do |d| t = d.name.demodulize.tableize.singularize relationships = "#{t}_relationships".to_sym sequences = "#{t}_sequences".to_sym has_many relationships, class_name: d.name.to_s, foreign_key: :object_sequence_id, inverse_of: :object_sequence has_many sequences, class_name: 'Sequence', through: relationships, source: :subject_sequence, inverse_of: :sequences accepts_nested_attributes_for sequences accepts_nested_attributes_for relationships end validates_presence_of :sequence validates_inclusion_of :sequence_type, in: ['DNA', 'RNA', 'AA'] # @param used_on [String] required, one of `GeneAttribute` or `SequenceRelationship` # @return [Scope] # the max 10 most recently used otus, as `used_on` def self.used_recently(user_id, project_id, used_on = nil) return Sequence.none if used_on.nil? t = case used_on when 'GeneAttribute' GeneAttribute.arel_table when 'SequenceRelationship' SequenceRelationship.arel_table end p = Sequence.arel_table # i is a select manager i = t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['updated_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # i is a select manager i = case used_on when 'SequenceRelationship' t.project(t['object_sequence_id'], t['updated_at']).from(t) .where( t['updated_at'].gt(1.weeks.ago) ) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) else t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) end # z is a table alias z = i.as('recent_t') j = case used_on when 'SequenceRelationship' Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new( z['object_sequence_id'].eq(p['id']) )) else Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['sequence_id'].eq(p['id']))) end Sequence.joins(j).pluck(:sequence_id).uniq end # @params target [String] one of nil, 'SequenceRelationship', 'GeneAttribute' # @return [Hash] otus optimized for user selection def self.select_optimized(user_id, project_id, target = nil) r = used_recently(user_id, project_id, target) h = { recent: [], quick: [], pinboard: Sequence.pinned_by(user_id).where(project_id: project_id).to_a } if r.empty? h[:quick] = Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a else h[:recent] = Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a h[:quick] = (Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a + Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a).uniq end h end protected def build_relationships describe_with.gene_attributes.each do |ga| .build(subject_sequence: ga.sequence, type: ga.sequence_relationship_type) end end def normalize_sequence_type sequence_type.to_s.upcase! if sequence_type.present? end end |
Class Method Details
.select_optimized(user_id, project_id, target = nil) ⇒ Hash
Returns otus optimized for user selection.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'app/models/sequence.rb', line 129 def self.select_optimized(user_id, project_id, target = nil) r = used_recently(user_id, project_id, target) h = { recent: [], quick: [], pinboard: Sequence.pinned_by(user_id).where(project_id: project_id).to_a } if r.empty? h[:quick] = Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a else h[:recent] = Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a h[:quick] = (Sequence.pinned_by(user_id).pinboard_inserted.where(project_id: project_id).to_a + Sequence.where('"sequences"."id" IN (?)', r.first(10) ).to_a).uniq end h end |
.used_recently(user_id, project_id, used_on = nil) ⇒ Scope
Returns the max 10 most recently used otus, as ‘used_on`.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'app/models/sequence.rb', line 76 def self.used_recently(user_id, project_id, used_on = nil) return Sequence.none if used_on.nil? t = case used_on when 'GeneAttribute' GeneAttribute.arel_table when 'SequenceRelationship' SequenceRelationship.arel_table end p = Sequence.arel_table # i is a select manager i = t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['updated_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at'].desc) # i is a select manager i = case used_on when 'SequenceRelationship' t.project(t['object_sequence_id'], t['updated_at']).from(t) .where( t['updated_at'].gt(1.weeks.ago) ) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) else t.project(t['sequence_id'], t['updated_at']).from(t) .where(t['updated_at'].gt( 1.weeks.ago )) .where(t['created_by_id'].eq(user_id)) .where(t['project_id'].eq(project_id)) .order(t['updated_at']) end # z is a table alias z = i.as('recent_t') j = case used_on when 'SequenceRelationship' Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new( z['object_sequence_id'].eq(p['id']) )) else Arel::Nodes::InnerJoin.new(z, Arel::Nodes::On.new(z['sequence_id'].eq(p['id']))) end Sequence.joins(j).pluck(:sequence_id).uniq end |
Instance Method Details
#build_relationships ⇒ Object (protected)
150 151 152 153 154 |
# File 'app/models/sequence.rb', line 150 def build_relationships describe_with.gene_attributes.each do |ga| .build(subject_sequence: ga.sequence, type: ga.sequence_relationship_type) end end |
#normalize_sequence_type ⇒ Object (protected)
156 157 158 |
# File 'app/models/sequence.rb', line 156 def normalize_sequence_type sequence_type.to_s.upcase! if sequence_type.present? end |