Class: ArchivalObject
- Includes:
- ASModel, Agents, Arks, Assessments::LinkedRecord, AutoGenerator, ComponentsAddChildren, Dates, Events, Extents, ExternalDocuments, ExternalIDs, Instances, LangMaterials, Notes, Publishable, ReindexTopContainers, RepresentativeFileVersion, ResourceRequestItems, RightsRestrictionNotes, RightsStatements, Subjects, TouchRecords, Transferable, TreeNodes
- Defined in:
- backend/app/model/archival_object.rb,
frontend/app/models/archival_object.rb,
public/app/models/archival_object.rb
Constant Summary
Constants included from RightsRestrictionNotes
RightsRestrictionNotes::RESTRICTION_NOTE_TYPES
Constants included from TreeNodes
TreeNodes::DB_RETRIES, TreeNodes::POSITION_STEP
Constants included from JSONModel
JSONModel::REFERENCE_KEY_REGEX
Constants inherited from Record
Instance Attribute Summary
Attributes inherited from Record
#agents, #classifications, #container_display, #container_summary_for_badge, #container_titles_and_uris, #criteria, #dates, #display_string, #extents, #external_documents, #full, #identifier, #json, #lang_materials, #level, #linked_digital_objects, #notes, #other_level, #primary_type, #raw, #repository_information, #resolved_repository, #resolved_resource, #resolved_top_container, #subjects, #uri
Class Method Summary collapse
-
.ordered_record_properties(record_ids) ⇒ Object
For archival objects, we want the level returned in our ordered_record response.
-
.produce_display_string(json) ⇒ Object
-
.sequel_to_jsonmodel(objs, opts = {}) ⇒ Object
-
.touch_records(obj) ⇒ Object
Instance Method Summary collapse
-
#cite ⇒ Object
-
#cite_item ⇒ Object
-
#cite_item_description ⇒ Object
-
#direct_component_id ⇒ Object
-
#finding_aid ⇒ Object
-
#instances ⇒ Object
-
#level_for_md_mapping ⇒ Object
should probably make these configurable options, but for now let’s assume anything like a “series” or greater is a Collection of some kind.
-
#metadata ⇒ Object
-
#parent_for_md_mapping ⇒ Object
-
#parse_notes ⇒ Object
-
#populate_from_accession(accession) ⇒ Object
-
#resource_identifier ⇒ Object
-
#resource_uri ⇒ Object
-
#root_node_uri ⇒ Object
-
#validate ⇒ Object
Methods included from ResourceRequestItems
Methods included from Arks
#apply_nested_records, included
Methods included from TouchRecords
#delete, included, #set_parent_and_position, #set_root, #update_from_json
Methods included from Assessments::LinkedRecord
Methods included from RepresentativeFileVersion
Methods included from RightsRestrictionNotes
Methods included from ReindexTopContainers
#accession_instance_root_record_update, #ao_instance_root_record_update, #delete, #reindex_top_containers, #reindex_top_containers_by_any_means_necessary, #resource_instance_update, #set_parent_and_position, #set_root, #update_from_json
Methods included from Publishable
Methods included from Events
Methods included from Transferable
Methods included from ComponentsAddChildren
Methods included from ExternalIDs
Methods included from Notes
included, #persistent_id_context, #update_from_json
Methods included from AutoGenerator
Methods included from TreeNodes
#ancestors, #attempt_set_parent_and_position, #attempt_set_position_in_list, #breadcrumb, #breadcrumb_identifier, #breadcrumb_title_for_node, #breadcrumb_uri_for_node, #children, #ensure_gap, #has_children?, included, #logical_position, #previous_node, #set_parent_and_position, #set_position_in_list, #set_root, #transfer_to_repository, #trigger_index_of_child_nodes, #update_from_json
Methods included from Agents
Methods included from Instances
Methods included from RightsStatements
Methods included from ExternalDocuments
Methods included from Dates
Methods included from LangMaterials
Methods included from Extents
Methods included from Subjects
Methods included from ASModel
all_models, included, update_publish_flag, update_suppressed_flag
Methods included from JSONModel
JSONModel, #JSONModel, add_error_handler, all, allow_unmapped_enum_value, backend_url, check_valid_refs, client_mode?, custom_validations, destroy_model, enum_default_value, enum_values, handle_error, init, load_schema, #models, models, parse_jsonmodel_ref, parse_reference, repository, repository_for, schema_src, set_publish_flags!, set_repository, strict_mode, strict_mode?, validate_schema, with_repository
Methods inherited from Record
#[], #dig, #initialize, #note, #parse_full_title, #request_item
Methods included from PrefixHelper
app_prefix, #app_prefix, app_prefix_js, #app_prefix_js
Methods included from RecordHelper
#badge_for_type, #icon_for_type, #record_class_for_type, #record_for_type, #record_from_resolved_json
Methods included from JsonHelper
#merge_notes, #process_json_notes
Methods included from ManipulateNode
#inheritance, #process_mixed_content, #strip_mixed_content
Constructor Details
This class inherits a constructor from Record
Class Method Details
.ordered_record_properties(record_ids) ⇒ Object
For archival objects, we want the level returned in our ordered_record response
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'backend/app/model/archival_object.rb', line 104 def self.ordered_record_properties(record_ids) result = super.clone self.filter(:id => record_ids).select(:id, :level_id, :other_level).each do |row| id = row[:id] level = if row[:other_level] row[:other_level] else BackendEnumSource.value_for_id('archival_record_level', row[:level_id]) end result[id] ||= {} result[id][:level] = level end result end |
.produce_display_string(json) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'backend/app/model/archival_object.rb', line 69 def self.produce_display_string(json) display_string = json['title'] || "" date_label = json.has_key?('dates') && json['dates'].length > 0 ? json['dates'].map do |date| if date['expression'] date['date_type'] == 'bulk' ? "#{I18n.t("date_type_bulk.bulk")}: #{date['expression']}" : date['expression'] elsif date['begin'] and date['end'] date['date_type'] == 'bulk' ? "#{I18n.t("date_type_bulk.bulk")}: #{date['begin']} - #{date['end']}" : "#{date['begin']} - #{date['end']}" else date['date_type'] == 'bulk' ? "#{I18n.t("date_type_bulk.bulk")}: #{date['begin']}" : date['begin'] end end.join(', ') : false display_string += ", " if json['title'] && date_label display_string += date_label if date_label display_string end |
.sequel_to_jsonmodel(objs, opts = {}) ⇒ Object
89 90 91 92 93 |
# File 'backend/app/model/archival_object.rb', line 89 def self.sequel_to_jsonmodel(objs, opts = {}) jsons = super AncestorListing.add_ancestors(objs, jsons) jsons end |
.touch_records(obj) ⇒ Object
122 123 124 |
# File 'backend/app/model/archival_object.rb', line 122 def self.touch_records(obj) [{ type: Resource, ids: [obj.root_record_id] }] end |
Instance Method Details
#cite ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'public/app/models/archival_object.rb', line 33 def cite cite = note('prefercite') unless cite.blank? cite = strip_mixed_content(cite['note_text']) else cite = identifier.blank? ? '' : "#{identifier}, " cite += strip_mixed_content(display_string) cite += if container_display.blank? || container_display.length > 5 '.' else @citation_container_display ||= parse_container_display(:citation => true).join('; ') ", #{@citation_container_display}." end if resolved_resource ttl = resolved_resource.dig('title') cite += " #{strip_mixed_content(ttl)}, #{resource_identifier}." end cite += " #{ repository_information['top']['name']}." unless !repository_information.dig('top', 'name') end "#{cite} #{cite_url_and_timestamp}." end |
#cite_item ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'public/app/models/archival_object.rb', line 58 def cite_item cite = note('prefercite') if !cite.blank? cite = strip_mixed_content(cite['note_text']) else cite = strip_mixed_content(display_string) cite += identifier.blank? ? '' : ", #{identifier}" cite += if container_display.blank? || container_display.length > 5 '.' else @citation_container_display ||= parse_container_display(:citation => true).join('; ') ", #{@citation_container_display}." end if resolved_resource ttl = resolved_resource.dig('title') cite += " #{strip_mixed_content(ttl)}, #{resource_identifier}." end unless repository_information['top']['name'].blank? cite += " #{ repository_information['top']['name']}." end end HTMLEntities.new.decode("#{cite}") end |
#cite_item_description ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'public/app/models/archival_object.rb', line 83 def cite_item_description cite = note('prefercite') if !cite.blank? cite = strip_mixed_content(cite['note_text']) else cite = strip_mixed_content(display_string) cite += identifier.blank? ? '' : ", #{identifier}" cite += if container_display.blank? || container_display.length > 5 '.' else @citation_container_display ||= parse_container_display(:citation => true).join('; ') ", #{@citation_container_display}." end if resolved_resource ttl = resolved_resource.dig('title') cite += " #{strip_mixed_content(ttl)}, #{resource_identifier}." end unless repository_information['top']['name'].blank? cite += " #{ repository_information['top']['name']}." end end HTMLEntities.new.decode("#{cite} #{cite_url_and_timestamp}.") end |
#direct_component_id ⇒ Object
15 16 17 18 19 20 21 |
# File 'public/app/models/archival_object.rb', line 15 def direct_component_id if json.has_key?('component_id_inherited') '' else json.fetch('component_id', '') end end |
#finding_aid ⇒ Object
27 28 29 30 31 |
# File 'public/app/models/archival_object.rb', line 27 def finding_aid # as this shares the same template as resources, # be clear that this object doesn't have a finding aid nil end |
#instances ⇒ Object
23 24 25 |
# File 'public/app/models/archival_object.rb', line 23 def instances json['instances'] end |
#level_for_md_mapping ⇒ Object
should probably make these configurable options, but for now let’s assume anything like a “series” or greater is a Collection of some kind. and Collections at the archival object level will be diffentiated from collections at the resource level in ASpace by the fact that the archival objects will be “partOf” something else.
120 121 122 123 124 125 126 |
# File 'public/app/models/archival_object.rb', line 120 def level_for_md_mapping if ['recordgrp', 'subgrp', 'fonds', 'collection', 'series'].include?(json['level'].downcase) ['Collection', 'ArchiveComponent'] else 'ArchiveComponent' end end |
#metadata ⇒ Object
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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'public/app/models/archival_object.rb', line 136 def md = { '@context' => "http://schema.org/", '@id' => AppConfig[:public_proxy_url] + uri, '@type' => level_for_md_mapping, 'name' => display_string, 'identifier' => json['identifier'], 'isPartOf' => AppConfig[:public_proxy_url] + parent_for_md_mapping }.compact md['description'] = json['notes'].select {|n| n['type'] == 'abstract'}.map {|abstract| strip_mixed_content(abstract['content'].join(' ')) } if md['description'].empty? md['description'] = json['notes'].select {|n| n['type'] == 'scopecontent'}.map {|scope| strip_mixed_content(scope['subnotes'].map {|s| s['content']}.join(' ')) } end md['description'] = md['description'][0] if md['description'].length == 1 md['creator'] = json['linked_agents'].select {|la| la['role'] == 'creator'}.map {|a| a['_resolved']}.map do |ag| { '@id' => AppConfig[:public_proxy_url] + ag['uri'], '@type' => ag['jsonmodel_type'] == 'agent_person' ? 'Person' : 'Organization', 'name' => ag['title'], 'sameAs' => ag['display_name']['authority_id'] }.compact end md['dateCreated'] = @dates.select {|d| d['label'] == 'creation' && ['inclusive', 'single'].include?(d['date_type'])} .reject {|d| d['_inherited']} .map do |date| date['final_expression'] end #just mapping the whole (and direct) extents for now. md['materialExtent'] = json['extents'].select {|e| e['portion'] == 'whole'} .reject {|e| e['_inherited']} .map do |extent| { "@type": "QuantitativeValue", "unitText": I18n.t("enumerations.extent_extent_type.#{extent['extent_type']}"), "value": extent['number'] } end md['isRelatedTo'] = json['notes'].select {|n| n['type'] == 'relatedmaterial'} .reject {|| ['_inherited']} .map {|| strip_mixed_content(['subnotes'].map {|text| text['content']}.join(' ')) } term_type_to_about_type = { 'geographic' => 'Place', 'temporal' => 'TemporalCoverage', 'uniform_title' => 'CreativeWork', 'topical' => 'Intangible', 'occupation' => 'Intangible' } md['about'] = json['subjects'].select {|s| term_type_to_about_type.keys.include?(s['_resolved']['terms'][0]['term_type']) }.map {|s| s['_resolved']}.map {|subj| hash = {'@type' => term_type_to_about_type[subj['terms'][0]['term_type']]} hash['@id'] = subj['authority_id'] if subj['authority_id'] hash['name'] = subj['title'] hash } md['about'].concat(json['linked_agents'].select {|la| la['role'] == 'subject'}.map {|a| a['_resolved']}.map {|ag| { '@type' => ag['jsonmodel_type'] == 'agent_person' ? 'Person' : 'Organization', 'name' => strip_mixed_content(ag['title']), } }) md['genre'] = json['subjects'].select {|s| s['_resolved']['terms'][0]['term_type'] == 'genre_form' }.map {|s| s['_resolved']}.map {|subj| subj['authority_id'] ? subj['authority_id'] : subj['title'] } #will need to update once more than one language code is allowed if raw['language'] md['inLanguage'] = { '@type' => 'Language', 'name' => I18n.t("enumerations.language_iso639_2.#{raw['language']}", :default => raw['language']) } end #will need to update here (and elsewhere) once ASpace allows more than one authority ID. #also, are there any changes needed now that the PUI has the ability to override the database ids in the URIs? md['holdingArchive'] = { '@id' => AppConfig[:public_proxy_url] + raw['repository'], '@type' => 'ArchiveOrganization', 'name' => json['repository']['_resolved']['name'], 'sameAs' => json['repository']['_resolved']['agent_representation']['_resolved']['display_name']['authority_id'] }.compact # add repository address to holdingArchive if repository_information["address"] md['holdingArchive']["address"] = { '@type' => 'PostalAddress', 'streetAddress' => repository_information["address"], 'addressLocality' => repository_information["city"], 'addressRegion' => repository_information["region"], 'postalCode' => repository_information["post_code"], 'addressCountry' => repository_information["country"], }.compact end # add repository telephone to holdingArchive if repository_information['telephones'] md['holdingArchive']['faxNumber'] = repository_information['telephones'] .select {|t| t['number_type'] == 'fax'} .map {|f| f['number']} md['holdingArchive']['telephone'] = repository_information['telephones'] .select {|t| t['number_type'] == 'business'} .map {|b| b['number']} end md['holdingArchive'].delete_if { |key, value| value.empty? } md.delete_if { |key, value| value.empty? } end |
#parent_for_md_mapping ⇒ Object
128 129 130 131 132 133 134 |
# File 'public/app/models/archival_object.rb', line 128 def parent_for_md_mapping if json['parent'].try(:any?) json['parent']['ref'] else json['resource']['ref'] end end |
#parse_notes ⇒ Object
5 6 7 8 9 |
# File 'public/app/models/archival_object.rb', line 5 def parse_notes rewrite_refs(json['notes'], resource_uri) if resource_uri super end |
#populate_from_accession(accession) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 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 |
# File 'frontend/app/models/archival_object.rb', line 3 def populate_from_accession(accession) values = accession.to_hash(:raw) # Recursively remove bits that don't make sense to copy (like "lock_version" # properties) values = JSONSchemaUtils.map_hash_with_schema(values, JSONModel(:accession).schema, [proc { |hash, schema| hash = hash.clone hash.delete_if {|k, v| k.to_s =~ /^(id_[0-9]|lock_version|instances|deaccessions|collection_management|user_defined|external_documents)$/} hash }]) # We'll replace this with our own relationship, linking us back to the # accession we were spawned from. # values.delete('related_accessions') self.accession_links = [{'ref' => accession.uri, '_resolved' => accession}] notes ||= [] if accession.content_description notes << JSONModel(:note_multipart).from_hash(:type => "scopecontent", :label => I18n.t('accession.content_description'), :subnotes => [{ 'content' => accession.content_description, 'jsonmodel_type' => 'note_text' }]) end if accession.condition_description notes << JSONModel(:note_singlepart).from_hash(:type => "physdesc", :label => I18n.t('accession.condition_description'), :content => [accession.condition_description]) end self.notes.concat(notes) self.rights_statements = Array(accession.rights_statements).map {|rights_statement| rights_statement.clone.tap {|r| r.delete('identifier')} } self.update(values) end |
#resource_identifier ⇒ Object
107 108 109 110 |
# File 'public/app/models/archival_object.rb', line 107 def resource_identifier @resource_identifier ||= resolved_resource ? ( (0..3).collect {|i| resolved_resource.dig("id_#{i}")}.compact.join('-')) : nil end |
#resource_uri ⇒ Object
11 12 13 |
# File 'public/app/models/archival_object.rb', line 11 def resource_uri resolved_resource && resolved_resource['uri'] end |
#root_node_uri ⇒ Object
112 113 114 |
# File 'public/app/models/archival_object.rb', line 112 def root_node_uri json.fetch('resource').fetch('ref') end |
#validate ⇒ Object
95 96 97 98 99 100 |
# File 'backend/app/model/archival_object.rb', line 95 def validate validates_unique([:root_record_id, :ref_id], :message => "An Archival Object Ref ID must be unique to its resource") map_validation_to_json_property([:root_record_id, :ref_id], :ref_id) super end |