In one of our projects, we have several different models that have slightly different properties. We have a :part
and a :part_of
. On the surface, we might be thinking of these as the same thing.
However according to their Resource Description Framework (RDF 📖) definition they are not the same property. The :part
represents the property described by http://id.loc.gov/ontologies/bibframe/part. Whereas the :part_of
represents the property described by http://id.loc.gov/ontologies/bibframe/partOf. Those Uniform Resource Locators (URLs 📖) are meant to be a pointer to the conceptual data dictionary entry.
The classes I cared about were all descendants of ActiveFedora::Base
.
See https://github.com/samvera/active_fedora for more details on that base class.
Below is the list of descendants:
subclasses = ActiveFedora::Base.descendants
# [
# GenericWork,
# Image,
# DogBiscuits::Work,
# DogBiscuits::ConferenceItem,
# ConferenceItem,
# DogBiscuits::Dataset,
# Dataset,
# DogBiscuits::ExamPaper,
# ExamPaper,
# DogBiscuits::JournalArticle,
# JournalArticle,
# DogBiscuits::PublishedWork,
# PublishedWork,
# DogBiscuits::Thesis,
# Thesis,
# FileSet,
# Collection
# ]
To determine which ones used the part
property, I ran the following:
subclasses.select { |k| k.properties.key?("part") }
# [PublishedWork]
And likewise for the part_of
property:
klasses.select { |k| k.properties.key?("part_of") }
# [
# GenericWork,
# Image,
# ConferenceItem,
# JournalArticle,
# Thesis,
# Collection
# ]
Most interesting to me is that there is no intersection between models that have the part_of
and the part
properties. Now, I wonder if this is intentional or a subtle bug in data modeling? In my experience, I give it 50/50 odds.
Postscript
When I first started writing this post, I remembered the .subclasses
method. I wrote the following recursive Ruby 📖 function:
def descendants_of(klass)
klass.subclasses.map do |subklass|
[subklass, descendants_of(subklass)]
end.flatten.compact
end
And then, as I was reviewing this post, I thought “Wait, there’s probably already a method that does this.” The descendants
method already existed.
I include the above descendants_of
as a means demonstrating a recursive function.
Post-postscript
At my first job, we made heavy usage of data dictionaries and entity relationship diagrams. We went through a rigorous modeling of data. This was all within a “closed” space for data; though one that began opening and broadening as we looked at digital integrations between providers and regulatory agencies.
Libraries sit in a different place, with a goal of sharing information publicly. Which, in its aspirational form means to describe things in a consistent manner. One of those manners is via RDF. On the surface, it looks brilliant. We use a URL to describe the meaning of the “field”. With the goal being that when two objects from different origins have a property with the same URL we can assume that “field” describes the same conceptual range.
But there are many different URLs that can be chosen to describe a “field” in similar manners. Also, each person’s bias in interpretting the meaning of a “field” can introduce drift from the intended/desired universality of the meaning of the “field.”
Assuming many folks of different perspectives can and will describe things consistently seems to be analogous to the high school Physics caveat “Assuming no wind resistance nor friction…”