Class: Identifier::Global

Inherits:
Identifier show all
Includes:
SoftValidation
Defined in:
app/models/identifier/global.rb

Overview

The identifier that is globally unique.

Curators of a specific project assert one canonical global identifier per type for each object, this identifier is identified by having .relation.nil?. If the curators feel there are multiple global identifiers for a given instance they must provide an explicit relationship between the canonical identifier and the alternate identifiers.

Defined Under Namespace

Classes: Doi, GenBankAccessionCode, Isbn, Issn, Lccn, Lsid, MorphbankSpecimenNumber, Orcid, Uri, Uuid, WebOfScience, Wikidata, ZoologicalRecord

Constant Summary

Constants included from SoftValidation

SoftValidation::ANCESTORS_WITH_SOFT_VALIDATIONS

Constants included from Shared::DualAnnotator

Shared::DualAnnotator::ALWAYS_COMMUNITY

Instance Attribute Summary collapse

Attributes inherited from Identifier

#cached, #cached_numeric_identifier, #identifier, #identifier_object_id, #namespace_id, #project_id, #type

Instance Method Summary collapse

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 inherited from Identifier

#build_cached_numeric_identifier, #is_local?, prototype_identifier, #set_cached, #type_name

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

#labeled?

Methods included from Housekeeping

#has_polymorphic_relationship?

Methods included from Shared::PolymorphicAnnotator

#annotated_object_is_persisted?

Methods inherited from ApplicationRecord

transaction_with_retry

Instance Attribute Details

#relationString

Defines the relationship between the curator asserted canonical identifier and other identifiers of the same type. Must be provided for every global identifier of the same type beyond the first. Relations are drawn from skos (www.w3.org/TR/skos-reference/#mapping)

Returns:

  • (String)


14
15
16
17
18
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
# File 'app/models/identifier/global.rb', line 14

class Identifier::Global < Identifier

  include SoftValidation

  validates :namespace_id, absence: true
  validates :relation, inclusion: {in: ::SKOS_RELATIONS.keys}, allow_nil: true
  validate :permit_only_one_global_without_relation_supplied_per_type

  # Identifier can only be used once, i.e. mapped to a single TW concept
  validates_uniqueness_of :identifier, scope: [:project_id]

  soft_validate(:sv_resolves?, set: :resolved)

  def is_global?
    true
  end

  protected

  def build_cached
    identifier
  end

  def permit_only_one_global_without_relation_supplied_per_type
    if identifier_object && identifier_object.identifiers.where(type: type.to_s).where.not(id: id).any?
      errors.add(:relation, " an existing identifier of type #{type} exists, a relation for this identifier must be provided"
      ) if self.relation.nil?
    end
  end

  # TODO: add a resolution method so that this works on theings like wikidata Q numbers 
  def sv_resolves?
    responded = identifier.present? && (Utilities::Net.resolves?(identifier) rescue false)
    soft_validations.add(:identifier, "Identifier '#{identifier}' does not resolve.") unless responded
    responded
  end

end

Instance Method Details

#build_cachedObject (protected)



33
34
35
# File 'app/models/identifier/global.rb', line 33

def build_cached
  identifier
end

#is_global?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'app/models/identifier/global.rb', line 27

def is_global?
  true
end

#permit_only_one_global_without_relation_supplied_per_typeObject (protected)



37
38
39
40
41
42
# File 'app/models/identifier/global.rb', line 37

def permit_only_one_global_without_relation_supplied_per_type
  if identifier_object && identifier_object.identifiers.where(type: type.to_s).where.not(id: id).any?
    errors.add(:relation, " an existing identifier of type #{type} exists, a relation for this identifier must be provided"
    ) if self.relation.nil?
  end
end

#sv_resolves?Boolean (protected)

TODO: add a resolution method so that this works on theings like wikidata Q numbers

Returns:

  • (Boolean)


45
46
47
48
49
# File 'app/models/identifier/global.rb', line 45

def sv_resolves?
  responded = identifier.present? && (Utilities::Net.resolves?(identifier) rescue false)
  soft_validations.add(:identifier, "Identifier '#{identifier}' does not resolve.") unless responded
  responded
end