-
Notifications
You must be signed in to change notification settings - Fork 4
The Anatomy of a Model
A model is a set of instructions and rules for constructing an object of a particular type. This is how a model is put together in DogBiscuits 🐶 🍪:
module DogBiscuits
class Thesis < Work
include DogBiscuits::AddWorkBehaviour
type << ::RDF::URI.new('http://purl.org/ontology/bibo/Thesis')
def thesis?
true
end
# Create single date field from all dates.
def combine_dates
self.date = []
date << date_of_award
end
end
end
- Thesis inherits from Work (Work inherits from ActiveFedora::Base).
- DogBiscuits::AddWorkBehaviour is a concern that bundles together desired behaviours
- DogBiscuits::AddThesisMetadata is a concern that bundles together all metadata properties for Thesis
- Thesis has the rdf:type http://purl.org/ontology/bibo/Thesis
- The thesis? method allows us to test that the object is a thesis.
- Thesis has a custom ThesisIndexer class; this includes the DogBiscuits::IndexesThesis indexer
- The combine_dates method and before_save callback is used across different models to combine different dates into a single property dc:date - this allows for a single date search in the calling application
- Inherited from Work are DogBiscuits::ValidateLabel (to ensure a title is present) and DogBiscuits::CommonMetadata (a set of common metadata properties available to all Works a la Hyrax::BasicMetadata)
module DogBiscuits
module ThesisMetadata
extend ActiveSupport::Concern
include DogBiscuits::Abstract
include DogBiscuits::Doi
include DogBiscuits::Orcid
include DogBiscuits::MainFile
include DogBiscuits::Department
include DogBiscuits::Qualification
include DogBiscuits::Advisor
include DogBiscuits::AwardingInstitution
include DogBiscuits::DateOfAward
end
end
These metadata property concerns make properties (and other code) available across multiple models using mixins. They are included in the Model that needs them.
module DogBiscuits
module DateOfAward
extend ActiveSupport::Concern
included do
property :date_of_award, predicate: ::RDF::Vocab::DC.dateAccepted, multiple: false do |index|
index.as :stored_searchable, :facetable, :dateable
end
end
end
end
Wherever the object of a predicate is another repository object (and the relationship is not covered by PCDM or Hydra::Works), use has_and_belongs_to_many (HABM). This is a bit misleading as really it's just has_many, but it is only possible to define a 'predicate' and restrict the object to being of a certain 'class' with has_and_belongs_to_many.
module DogBiscuits
module AwardingInstitution
extend ActiveSupport::Concern
included do
has_and_belongs_to_many :awarding_institution_resource,
class_name: 'DogBiscuits::Organisation',
predicate: ::RDF::Vocab::Bibframe.dissertationInstitution
end
end
end
So we'd do:
organisation_object = Organisation.new
thesis.awarding_institution_resource << organisation_object
and in fedora we'd get:
<thesis> <bf:dissertationInstitution> <organisation_object>
But how do we search for the creator if all we have is the id of the related creator objects?
By indexing info about the organisation into the solr document for the Work. Otherwise if a search for the awarding instituion name wouldn't get any results.
Do this with a custom indexer, like the one shown below.
Convention:
- '_resource' for the name of the relationship to the object (eg. awarding_institution_resource)
- '_label' for the name of the solr field for the 'preflabel' of the related object (eg.awarding_institution_tesim)
- '_label_alt' for the variant names contained in the 'altlabel' field of the related object (eg. awarding_institution_value_alt_tesim)
Additional fields can be indexed into solr with a custom indexer.
The patterns for custom indexers is as follows:
-
A common indexer has been created to deal with any HABM relations as described above:
-
Each model then has it's own Indexer that includes IndexesCommon
module DogBiscuits
module ThesisIndexer
include DogBiscuits::IndexesCommon
included do
def labels_to_index
['creator', 'advisor', 'department', 'awarding_institution']
end
def strings_to_index
['creator', 'advisor']
end
def contributors_to_index
['advisor']
end
# Add any custom indexing into here. Method must exist, but can be empty.
def do_local_indexing(solr_doc)
# custom indexer
end
end
end
end
- The labels_to_index method should contain an array of any HABM fields to index, omitting the _resource part of the name.
- The strings_to_index method should contain an array of any properties to be mixed into the _values solr field. For example, if there was a creator property with creator names in addition to creator HABM relations, both can be indexed into the creator_label_tesim solr field.
- The contributors_to_index method should contain an array of properties that should be indexed additionally as contributor_combined (eg. advisor, editor) in order to create a single contributor field for facets in the search.
- The do_local_indexing method can be used for any additional custom indexing, specific to the model.