Skip to content

Instantly share code, notes, and snippets.

@escowles
Created April 4, 2014 14:04
Show Gist options
  • Save escowles/9975373 to your computer and use it in GitHub Desktop.
Save escowles/9975373 to your computer and use it in GitHub Desktop.
MADS linkage
source 'https://rubygems.org'
gem 'active-fedora', github: 'projecthydra/active_fedora', branch: 'master'
gem 'linkeddata'
#!/usr/bin/env ruby
# mads demo using AF 7.0 rc3
require 'active-fedora'
require 'linkeddata'
# vocabulary
class MADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
# MADS classes
property :ComplexSubject
property :Topic
property :MADSScheme
# MADS properties
property :isMemberOfMADSScheme
# elementList and elementList values
property :componentList
property :elementList
property :elementValue
property :TopicElement
end
# scheme
class MadsScheme < ActiveFedora::Rdf::Resource
configure type: MADS.MADSScheme
configure base_uri: "http://library.ucsd.edu/ark:/20775/"
property :name, predicate: RDF::RDFS.label
end
# topic
class MadsTopic < ActiveFedora::Rdf::Resource
configure type: MADS.Topic
property :name, predicate: MADS.authoritativeLabel
property :scheme, predicate: MADS.isMemberOfMADSScheme, class_name: "MadsScheme"
property :elementList, predicate: MADS.elementList, class_name: "MadsElementList"
accepts_nested_attributes_for :scheme, :elementList
end
class MadsElementList < ActiveFedora::Rdf::List
configure type: MADS.elementList
property :topicElement, predicate: MADS.TopicElement, class_name: "MadsTopicElement"
accepts_nested_attributes_for :topicElement
end
class MadsTopicElement < ActiveFedora::Rdf::Resource
property :elementValue, predicate: MADS.elementValue
configure :type => MADS.TopicElement
end
# complex subject
class MadsComplexSubjectDatastream < ActiveFedora::RdfxmlRDFDatastream
resource_class.configure type: MADS.ComplexSubject
resource_class.configure base_uri: "http://library.ucsd.edu/ark:/20775/"
property :name, predicate: MADS.authoritativeLabel
property :scheme, predicate: MADS.isMemberOfMADSScheme
property :componentList, predicate: MADS.componentList, class_name: "MadsComponentList"
accepts_nested_attributes_for :componentList, :topic, :scheme
delegate :topic_attributes=, to: :componentList
alias_method :topic, :componentList
end
class MadsComplexSubject < ActiveFedora::Base
has_metadata :name => "damsMetadata", :type => MadsComplexSubjectDatastream
has_attributes :name, :componentList, :scheme, datastream: "damsMetadata", multiple: false
delegate :componentList_attributes=, to: :damsMetadata
delegate :topic_attributes=, to: :damsMetadata
delegate :scheme_attributes=, to: :damsMetadata
end
class MadsComponentList < ActiveFedora::Rdf::List
configure type: MADS.componentList
property :topic, predicate: MADS.Topic, class_name: "MadsTopic"
accepts_nested_attributes_for :topic
end
# complex subject
complex_subject_params = {
name: 'Civilization, Modern',
scheme_attributes: [{
id: 'http://library.ucsd.edu/ark:/20775/bb3333333x',
name: 'Library of Congress Subject Headings'
}],
componentList_attributes: [{
topic_attributes: [{
id: 'http://library.ucsd.edu/ark:20775/bb2222222x',
name: 'Civilization, Modern',
elementList_attributes: [{
topicElement_attributes: [{elementValue:"Civilization, Modern"}]
}],
scheme_attributes: [{
id: 'http://library.ucsd.edu/ark:20775/bb4444444x',
name: 'Library of Congress Subject Headings'
}]
}
]
}]
}
sub = MadsComplexSubject.new(pid:'bb1111111x')
sub.attributes = complex_subject_params
puts sub.damsMetadata.content
<?xml version='1.0' encoding='utf-8' ?>
<rdf:RDF xmlns:ns0='http://www.loc.gov/mads/rdf/v1#'
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'>
<ns0:MADSScheme rdf:about='http://library.ucsd.edu/ark:20775/bb4444444x'>
<rdfs:label>Library of Congress Subject Headings</rdfs:label>
</ns0:MADSScheme>
<ns0:ComplexSubject rdf:about='http://library.ucsd.edu/ark:/20775/bb1111111x'>
<ns0:authoritativeLabel>Civilization, Modern</ns0:authoritativeLabel>
<ns0:componentList rdf:parseType='Collection'>
<ns0:Topic rdf:nodeID='g70290732937020'>
<ns0:authoritativeLabel>Civilization, Modern</ns0:authoritativeLabel>
<ns0:elementList rdf:parseType='Collection'>
<ns0:TopicElement rdf:nodeID='g70290732966240'>
<ns0:elementValue>Civilization, Modern</ns0:elementValue>
</ns0:TopicElement>
</ns0:elementList>
<ns0:isMemberOfMADSScheme rdf:resource='http://library.ucsd.edu/ark:20775/bb4444444x' />
</ns0:Topic>
</ns0:componentList>
<ns0:isMemberOfMADSScheme rdf:resource='http://library.ucsd.edu/ark:/20775/bb3333333x' />
</ns0:ComplexSubject>
</rdf:RDF>
@escowles
Copy link
Author

escowles commented Apr 4, 2014

I see two issues in the RDF output above:

  1. The topic_attributes hash includes an id property, but the generated Topic element has an auto-generated rdf:nodeID instead of using the id for rdf:about. By contrast, the MADSScheme objects are clearly getting assigned RDF subject by the id properties in their hashes.
  2. The MADSScheme linked to from Topic (bb4444444x) shows up, but the one linked to from ComplexSubject (bb3333333x) is missing.

@no-reply
Copy link

Answers are here (edit: I had the numbering reversed, previously.):

  1. This was a bug that caused nodes created directly with #attributes= (bypassing Rdf::Term#build) to skip setting their subjects. I have a pull request in for this. It should be fixed in 7.0.2 and later.
  2. You need to set the class_name on L55. property :scheme, predicate: MADS.isMemberOfMADSScheme, class_name: "MadsScheme". Without this, the node gets built as a generic Rdf::Resource, and when #attributes= tries to set :name, it fails (unfortunately, silently) since Rdf::Resource has no such property. We should consider a better failure state for this. Obviously, something should happen when you try to pass attributes that don't exist. On the other hand, I'm not sure how hard of a failure is desirable.

@no-reply
Copy link

There's now a PR in for error messages in #attributes=. With that, your gist should fail at L97 with ArgumentError: No association found for name name'. Has it been defined yet?`.

Hopefully this resolves both issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment