Module: Shared::IsDwcOccurrence

Overview

Shared code for data classes that can be indexed/serialized as DwcOccurrence records

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

DWC_DELIMITER =
Export::Dwca::DELIMITER
VIEW_EXCLUSIONS =
[
  :footprintWKT
].freeze

Instance Method Summary collapse

Instance Method Details

#dwc_occurrence_attribute_values(mode = :all) ⇒ Array

Returns an array of the values presently computed for this occurrence.

Returns:

  • (Array)

    an array of the values presently computed for this occurrence



150
151
152
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 150

def dwc_occurrence_attribute_values(mode = :all)
  [id, dwc_occurrence.id] + self.class.dwc_attribute_vector(mode)[2..-1].collect{|a| a.name}.collect{|f| dwc_occurrence.send(f) }
end

#dwc_occurrence_attributes(taxonworks_fields = true) ⇒ Object

!! This is expensive, it recomputes values for every field. !! See dwc_occurrence

Returns:

  • Hash of field: value



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 126

def dwc_occurrence_attributes(taxonworks_fields = true)
  a = {}
  self.class::DWC_OCCURRENCE_MAP.each do |k,v|
    a[k] = send(v)
  end

  a[:occurrenceID] = dwc_occurrence_id
  a[:basisOfRecord] = dwc_occurrence_basis

  if taxonworks_fields
    a[:otu_id] = dwc_otu_id
    a[:project_id] = project_id

    # TODO: semantics of these may need to be revisited, particularly updated_by_id
    a[:created_by_id] = created_by_id
    a[:updated_by_id] = updated_by_id
    # !! Do not set updated_at here !!
  end

  a
end

#dwc_occurrence_basisObject

Moved here from DwcOccurrence#basis since that method is only called in before_validate, which never gets called on the dwc_occurrence_attributes path here that happens when something like adding a new BiocurationClass triggers a background job set_dwc_occurrence call to update dwc_occurrence.

Returns:

  • String the Darwin Core basisOfRecord value for this occurrence



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 87

def dwc_occurrence_basis
  case self.class.base_class.name
  when 'CollectionObject'
    is_fossil? ? 'FossilSpecimen' : 'PreservedSpecimen'
  when 'AssertedDistribution'
    # Used to fork b/b Source::Human and Source::Bibtex:
    case source&.type || sources.order(cached_nomenclature_date: :DESC).first&.type
    when 'Source::Bibtex'
      'MaterialCitation'
    when 'Source::Human'
      'HumanObservation'
    else # Not recommended at this point
      'Occurrence'
    end
  when 'FieldOccurrence'
    machine_output? ? 'MachineObservation' : 'HumanObservation'
  else
    'Undefined'
  end
end

#dwc_occurrence_idObject



77
78
79
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 77

def dwc_occurrence_id
  dwc_occurrence&.occurrence_identifier&.cached
end

#dwc_otu_idInteger?

Returns TaxonWorks OTU id included on the denormalized DwcOccurrence row.

Returns:

  • (Integer, nil)

    TaxonWorks OTU id included on the denormalized DwcOccurrence row.



110
111
112
113
114
115
116
117
118
119
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 110

def dwc_otu_id
  case self.class.base_class.name
  when 'CollectionObject', 'FieldOccurrence'
    current_otu&.id
  when 'AssertedDistribution'
    otu&.id
  else
    raise NotImplementedError, "Unhandled dwc_otu_id for #{self.class.base_class.name}"
  end
end

#get_dwc_occurrenceDwcOccurrence

Returns does not rebuild if already built.

Returns:



156
157
158
159
160
161
162
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 156

def get_dwc_occurrence
  if dwc_occurrence_persisted?
    dwc_occurrence
  else
    set_dwc_occurrence
  end
end

#set_dwc_occurrenceDwcOccurrence

Returns !! always touches the database.

Returns:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/concerns/shared/is_dwc_occurrence.rb', line 52

def set_dwc_occurrence
  retried = false
  begin
    if dwc_occurrence_persisted?
      dwc_occurrence.generate_uuid_if_required # TODO: at some point when synchronized make this optional
      dwc_occurrence.update_columns(
        dwc_occurrence_attributes.merge(
          rebuild_set: nil,
          updated_at: Time.zone.now)
      )
    else
      create_dwc_occurrence!(dwc_occurrence_attributes)
    end
  rescue ActiveRecord::ActiveRecordError
    unless retried
      retried = true
      dwc_occurrence&.reload
      retry
    else
      raise
    end
  end
  dwc_occurrence
end