Class: FieldOccurrence

Overview

A FieldOccurrence is

* A TaxonDetermination
* Done in the field (As defined by the CollectingEvent)

It is differentiated from a CollectionObject by:

* No physical individual is brought back to a physical collection.
* It requires a TaxonDetermination be present
* It is not Containable (or Loanable, etc.)

Defined Under Namespace

Modules: DwcExtensions

Constant Summary

Constants included from Shared::IsDwcOccurrence

Shared::IsDwcOccurrence::DWC_DELIMITER, Shared::IsDwcOccurrence::VIEW_EXCLUSIONS

Constants included from SoftValidation

SoftValidation::ANCESTORS_WITH_SOFT_VALIDATIONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Shared::IsDwcOccurrence

#dwc_occurrence_attribute_values, #dwc_occurrence_attributes, #dwc_occurrence_id, #get_dwc_occurrence, #set_dwc_occurrence

Methods included from Shared::BiologicalExtensions

#missing_determination, #name_at_rank_string, #reject_otus, #reject_taxon_determinations

Methods included from DwcExtensions

#api_image_link, #dwc_associated_media, #dwc_associated_taxa, #dwc_caste, #dwc_catalog_number, #dwc_class, #dwc_collection_code, #dwc_coordinate_uncertainty_in_meters, #dwc_country, #dwc_county, #dwc_date_identified, #dwc_day, #dwc_decimal_latitude, #dwc_decimal_longitude, #dwc_end_day_of_year, #dwc_event_date, #dwc_event_remarks, #dwc_event_time, #dwc_family, #dwc_field_number, #dwc_footprint_wkt, #dwc_genus, #dwc_geodetic_datum, #dwc_georeference_protocol, #dwc_georeference_remarks, #dwc_georeference_sources, #dwc_georeferenced_by, #dwc_georeferenced_date, #dwc_higher_classification, #dwc_identification_remarks, #dwc_identified_by, #dwc_identified_by_id, #dwc_individual_count, #dwc_infraspecific_epithet, #dwc_institution_code, #dwc_institution_id, #dwc_internal_attribute_for, #dwc_kingdom, #dwc_life_stage, #dwc_locality, #dwc_maximum_depth_in_meters, #dwc_maximum_elevation_in_meters, #dwc_minimum_depth_in_meters, #dwc_minimum_elevation_in_meters, #dwc_month, #dwc_nomenclatural_code, #dwc_occurrence_remarks, #dwc_occurrence_status, #dwc_order, #dwc_other_catalog_numbers, #dwc_phylum, #dwc_preparations, #dwc_previous_identifications, #dwc_recorded_by, #dwc_recorded_by_id, #dwc_sampling_protocol, #dwc_scientific_name, #dwc_sex, #dwc_specific_epithet, #dwc_start_day_of_year, #dwc_state_province, #dwc_subfamily, #dwc_subtribe, #dwc_superfamily, #dwc_taxon_name_authorship, #dwc_taxon_rank, #dwc_tribe, #dwc_type_status, #dwc_verbatim_coordinates, #dwc_verbatim_depth, #dwc_verbatim_elevation, #dwc_verbatim_event_date, #dwc_verbatim_habitat, #dwc_verbatim_label, #dwc_verbatim_latitude, #dwc_verbatim_locality, #dwc_verbatim_longitude, #dwc_verbatim_srs, #dwc_water_body, #dwc_year, #is_fossil?, #set_georeference_attributes

Methods included from SoftValidation

#clear_soft_validations, #fix_for, #fix_soft_validations, #soft_fixed?, #soft_valid?, #soft_validate, #soft_validated?, #soft_validations, #soft_validators

Methods included from Shared::QueryBatchUpdate

#query_update

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::ProtocolRelationships

#protocolled?, #reject_protocols

Methods included from Shared::Confidences

#reject_confidences

Methods included from Shared::OriginRelationship

#new_objects, #old_objects, #reject_origin_relationships, #set_origin

Methods included from Shared::Depictions

#has_depictions?, #image_array=, #reject_depictions, #reject_images

Methods included from Shared::Tags

#reject_tags, #tag_with, #tagged?, #tagged_with?

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::DataAttributes

#import_attributes, #internal_attributes, #keyword_value_hash, #reject_data_attributes

Methods included from Shared::Citations

#cited?, #mark_citations_for_destruction, #nomenclature_date, #origin_citation_source_id, #reject_citations, #requires_citation?, #sources_by_topic_id

Methods included from Housekeeping

#has_polymorphic_relationship?

Methods inherited from ApplicationRecord

transaction_with_retry

Instance Attribute Details

#is_absentBoolean

Returns a positive negative, when true then there exists an assertion that the taxon was not observed given the effort of the CollectingEvent. Inessence a confirmation/checksum of total=0 assertions. Total must be zero here.

Returns:

  • (Boolean)

    a positive negative, when true then there exists an assertion that the taxon was not observed given the effort of the CollectingEvent. Inessence a confirmation/checksum of total=0 assertions. Total must be zero here.



19
20
21
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
# File 'app/models/field_occurrence.rb', line 19

class FieldOccurrence < ApplicationRecord
  include GlobalID::Identification
  include Housekeeping

  include Shared::Citations
  include Shared::DataAttributes
  include Shared::Identifiers
  include Shared::Notes
  include Shared::Tags
  include Shared::Depictions

  include Shared::OriginRelationship
  include Shared::Confidences
  include Shared::ProtocolRelationships
  include Shared::HasPapertrail
  include Shared::Observations
  include Shared::IsData
  include Shared::QueryBatchUpdate
  include SoftValidation

  # At present must be before IsDwcOccurence
  include FieldOccurrence::DwcExtensions
  include Shared::Taxonomy

  include Shared::BiologicalExtensions
  include Shared::IsDwcOccurrence

  is_origin_for 'Specimen', 'Lot', 'Extract', 'AssertedDistribution', 'Sequence'

  belongs_to :collecting_event, inverse_of: :field_occurrences
  belongs_to :ranged_lot_category, inverse_of: :ranged_lots

  has_many :georeferences, through: :collecting_event
  has_many :geographic_items, through: :georeferences

  # Hmmm- semantics here?
  # Should be observers?
  has_many :collectors, through: :collecting_event

  validates_presence_of :collecting_event

  validate :new_records_include_taxon_determination
  validate :check_that_either_total_or_ranged_lot_category_id_is_present
  validate :check_that_both_of_category_and_total_are_not_present
  validate :total_zero_when_absent

  accepts_nested_attributes_for :collecting_event, allow_destroy: true, reject_if: :reject_collecting_event

  def requires_taxon_determination?
    true
  end

  private

  def total_zero_when_absent
    errors.add(:total, 'Must be zero when absent.') if (total != 0) && is_absent
  end

  def check_that_both_of_category_and_total_are_not_present
    errors.add(:ranged_lot_category_id, 'Both ranged_lot_category and total can not be set') if ranged_lot_category_id.present? && total.present?
  end

  def check_that_either_total_or_ranged_lot_category_id_is_present
    errors.add(:base, 'Either total or a ranged lot category must be provided') if ranged_lot_category_id.blank? && total.blank?
  end

  # @return [Boolean]
  def new_records_include_taxon_determination
    if new_record? && taxon_determination.blank? && !taxon_determinations.any?
      errors.add(:base, 'required taxon determination is not provided')
    end
  end

  # Duplicated with CollectionObject
  def reject_collecting_event(attributed)
    reject = true
    CollectingEvent.core_attributes.each do |a|
      if attributed[a].present?
        reject = false
        break
      end
    end
    # !! does not account for georeferences_attributes!
    reject
  end

end

#totalInteger

Returns The enumerated number of things observed in the field, as asserted by *the collector* of a CollectingEvent. Must be zero if is_absent = true.

Returns:

  • (Integer)

    The enumerated number of things observed in the field, as asserted by *the collector* of a CollectingEvent. Must be zero if is_absent = true.



19
20
21
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
# File 'app/models/field_occurrence.rb', line 19

class FieldOccurrence < ApplicationRecord
  include GlobalID::Identification
  include Housekeeping

  include Shared::Citations
  include Shared::DataAttributes
  include Shared::Identifiers
  include Shared::Notes
  include Shared::Tags
  include Shared::Depictions

  include Shared::OriginRelationship
  include Shared::Confidences
  include Shared::ProtocolRelationships
  include Shared::HasPapertrail
  include Shared::Observations
  include Shared::IsData
  include Shared::QueryBatchUpdate
  include SoftValidation

  # At present must be before IsDwcOccurence
  include FieldOccurrence::DwcExtensions
  include Shared::Taxonomy

  include Shared::BiologicalExtensions
  include Shared::IsDwcOccurrence

  is_origin_for 'Specimen', 'Lot', 'Extract', 'AssertedDistribution', 'Sequence'

  belongs_to :collecting_event, inverse_of: :field_occurrences
  belongs_to :ranged_lot_category, inverse_of: :ranged_lots

  has_many :georeferences, through: :collecting_event
  has_many :geographic_items, through: :georeferences

  # Hmmm- semantics here?
  # Should be observers?
  has_many :collectors, through: :collecting_event

  validates_presence_of :collecting_event

  validate :new_records_include_taxon_determination
  validate :check_that_either_total_or_ranged_lot_category_id_is_present
  validate :check_that_both_of_category_and_total_are_not_present
  validate :total_zero_when_absent

  accepts_nested_attributes_for :collecting_event, allow_destroy: true, reject_if: :reject_collecting_event

  def requires_taxon_determination?
    true
  end

  private

  def total_zero_when_absent
    errors.add(:total, 'Must be zero when absent.') if (total != 0) && is_absent
  end

  def check_that_both_of_category_and_total_are_not_present
    errors.add(:ranged_lot_category_id, 'Both ranged_lot_category and total can not be set') if ranged_lot_category_id.present? && total.present?
  end

  def check_that_either_total_or_ranged_lot_category_id_is_present
    errors.add(:base, 'Either total or a ranged lot category must be provided') if ranged_lot_category_id.blank? && total.blank?
  end

  # @return [Boolean]
  def new_records_include_taxon_determination
    if new_record? && taxon_determination.blank? && !taxon_determinations.any?
      errors.add(:base, 'required taxon determination is not provided')
    end
  end

  # Duplicated with CollectionObject
  def reject_collecting_event(attributed)
    reject = true
    CollectingEvent.core_attributes.each do |a|
      if attributed[a].present?
        reject = false
        break
      end
    end
    # !! does not account for georeferences_attributes!
    reject
  end

end

Instance Method Details

#check_that_both_of_category_and_total_are_not_presentObject (private)



77
78
79
# File 'app/models/field_occurrence.rb', line 77

def check_that_both_of_category_and_total_are_not_present
  errors.add(:ranged_lot_category_id, 'Both ranged_lot_category and total can not be set') if ranged_lot_category_id.present? && total.present?
end

#check_that_either_total_or_ranged_lot_category_id_is_presentObject (private)



81
82
83
# File 'app/models/field_occurrence.rb', line 81

def check_that_either_total_or_ranged_lot_category_id_is_present
  errors.add(:base, 'Either total or a ranged lot category must be provided') if ranged_lot_category_id.blank? && total.blank?
end

#new_records_include_taxon_determinationBoolean (private)

Returns:

  • (Boolean)


86
87
88
89
90
# File 'app/models/field_occurrence.rb', line 86

def new_records_include_taxon_determination
  if new_record? && taxon_determination.blank? && !taxon_determinations.any?
    errors.add(:base, 'required taxon determination is not provided')
  end
end

#reject_collecting_event(attributed) ⇒ Object (private)

Duplicated with CollectionObject



93
94
95
96
97
98
99
100
101
102
103
# File 'app/models/field_occurrence.rb', line 93

def reject_collecting_event(attributed)
  reject = true
  CollectingEvent.core_attributes.each do |a|
    if attributed[a].present?
      reject = false
      break
    end
  end
  # !! does not account for georeferences_attributes!
  reject
end

#requires_taxon_determination?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'app/models/field_occurrence.rb', line 67

def requires_taxon_determination?
  true
end

#total_zero_when_absentObject (private)



73
74
75
# File 'app/models/field_occurrence.rb', line 73

def total_zero_when_absent
  errors.add(:total, 'Must be zero when absent.') if (total != 0) && is_absent
end