Lesson: create instances of hydra works models - samvera/hydra-works GitHub Wiki
Goals
- Create objects for a collection and a bibliographic resource with its file that use your Collection, BibliographicWork, and BibliographicFileSet model classes
- Establish relationships between collections and works and between works and file sets.
Explanation
Now you will create instances of the models you defined in the previous lesson.
Step 1: Start the Rails console
Let's take a look at how the collection, work, and file set models we created in the previous lesson work. We'll start the rails console by typing
$ rails console
(Or you can abbreviate this as rails c
.)
You should see something like Loading development environment (Rails 4.2.0)
. Now you're in a "REPL", or interactive ruby console that has all of your Rails application's code and configuration loaded.
Step 2: In the console, create a collection
Let's create a new Collection instance. The expected output is shown after each command:
col = Collection.new(id: 'col-1')
ActiveFedora: loading fedora config from /Users/elr37/Documents/__DEVELOPMENT__/__SUFIA_SPRINT/2015-09-04/hydra-hydra-works-demo/config/fedora.yml
ActiveFedora: loading solr config from /Users/elr37/Documents/__DEVELOPMENT__/__SUFIA_SPRINT/2015-09-04/hydra-hydra-works-demo/config/solr.yml
Attempted to init base path `dev`, but it already exists
=> #<Collection id: "col-1", title: nil, head_id: [], tail_id: []>
col.title = "Works by Edgar Allan Poe"
=> "Works by Edgar Allan Poe"
col.save
=> true
puts col.resource.dump(:ttl)
<http://127.0.0.1:8984/rest/dev/col-1> a <http://pcdm.org/models#Collection>,
<http://fedora.info/definitions/v4/repository#Container>,
<http://projecthydra.org/works/models#Collection>,
<http://fedora.info/definitions/v4/repository#Resource>,
<http://www.w3.org/ns/ldp#RDFSource>,
<http://www.w3.org/ns/ldp#Container>;
<http://purl.org/dc/terms/title> "Works by Edgar Allan Poe";
<http://fedora.info/definitions/v4/repository#created> "2016-06-13T13:53:45.008Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
<http://fedora.info/definitions/v4/repository#createdBy> "bypassAdmin";
<http://fedora.info/definitions/v4/repository#exportsAs> <http://127.0.0.1:8984/rest/dev/col-1/fcr:export?format=jcr/xml>;
<http://fedora.info/definitions/v4/repository#hasParent> <http://127.0.0.1:8984/rest/dev>;
<http://fedora.info/definitions/v4/repository#lastModified> "2016-06-13T13:53:45.008Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
<http://fedora.info/definitions/v4/repository#lastModifiedBy> "bypassAdmin";
<http://fedora.info/definitions/v4/repository#numberOfChildren> "0"^^<http://www.w3.org/2001/XMLSchema#long>;
<http://fedora.info/definitions/v4/repository#writable> true;
<info:fedora/fedora-system:def/model#hasModel> "Collection" .
<http://127.0.0.1:8984/rest/dev/col-1/fcr:export?format=jcr/xml> <http://purl.org/dc/elements/1.1/format> <http://fedora.info/definitions/v4/repository#jcr/xml> .
=> nil
We've created a new Collection object in the repository. You can see that it has a URI (Fedora Commons persistence identifier) of 'http://127.0.0.1:8984/rest/dev/col-1' (default username/password fedoraAdmin/fedoraAdmin
). Because you set title, you can see it is also stored in the RDF graph. We can use those values by calling their accessors.
col.title
=> "Works by Edgar Allan Poe"
Finally we'll get the Fedora URI and the abbreviated version (id
) of the object:
col.uri
=> #<RDF::URI:0x3fc6d63f0854 URI:http://127.0.0.1:8984/rest/dev/col-1>
col.id
=> "col-1"
Validate hydra-works model type:
col.collection?
=> true
col.work?
=> false
col.file_set?
=> false
col.pcdm_collection?
=> true
col.pcdm_object?
=> false
Reference: How to retrieve a saved collection?
col = Collection.find("col-1")
NOTE: This is useful if you have to take a break from the tutorial and want to get the objects back. You can't use new twice with the same id.
Step 3: In the console, create a bibliographic resource work
Let's create a new BibliographicWork instance. I've shown the expected output after each command:
*NOTE: You can pass in attribute values to the new method and it will assign them to the new work in one step. You can still set or change attribute values with the dot attribute methods (e.g. abstract).
bw = BibliographicWork.new(id: 'work-1', title: 'The Raven', author: 'Poe, Edgar Allan')
=> #<BibliographicWork id: "work-1", head: [], tail: [], title: "The Raven", author: "Poe, Edgar Allan", abstract: nil>
bw.abstract = "A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'."
=> "A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'."
bw.save
=> true
puts bw.resource.dump(:ttl)
<http://127.0.0.1:8984/rest/dev/work-1> a <http://fedora.info/definitions/v4/repository#Container>,
<http://projecthydra.org/works/models#Work>,
<http://fedora.info/definitions/v4/repository#Resource>,
<http://pcdm.org/models#Object>,
<http://www.w3.org/ns/ldp#RDFSource>,
<http://www.w3.org/ns/ldp#Container>;
<http://purl.org/dc/terms/title> "The Raven";
<http://fedora.info/definitions/v4/repository#created> "2016-06-13T14:11:50.749Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
<http://fedora.info/definitions/v4/repository#createdBy> "bypassAdmin";
<http://fedora.info/definitions/v4/repository#exportsAs> <http://127.0.0.1:8984/rest/dev/work-1/fcr:export?format=jcr/xml>;
<http://fedora.info/definitions/v4/repository#hasParent> <http://127.0.0.1:8984/rest/dev>;
<http://fedora.info/definitions/v4/repository#lastModified> "2016-06-13T14:11:50.749Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
<http://fedora.info/definitions/v4/repository#lastModifiedBy> "bypassAdmin";
<http://fedora.info/definitions/v4/repository#numberOfChildren> "0"^^<http://www.w3.org/2001/XMLSchema#long>;
<http://fedora.info/definitions/v4/repository#writable> true;
<http://purl.org/dc/terms/abstract> "A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'.";
<http://purl.org/dc/terms/creator> "Poe, Edgar Allan";
<info:fedora/fedora-system:def/model#hasModel> "BibliographicWork" .
<http://127.0.0.1:8984/rest/dev/work-1/fcr:export?format=jcr/xml> <http://purl.org/dc/elements/1.1/format> <http://fedora.info/definitions/v4/repository#jcr/xml> .
=> nil
We've created a new bibliographic resource work in the repository. You can see that it has a URI (Fedora Commons persistence identifier) of 'http://127.0.0.1:8984/rest/dev/work-1' (default username/password fedoraAdmin/fedoraAdmin
). Because you set title, author, and abstract, you can see they are also stored in the RDF graph. We can use those values by calling their accessors.
bw.title
=> "The Raven"
bw.author
=> "Poe, Edgar Allan"
bw.abstract
=> "A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'."
You can also see the values for all attributes with a single command.
bw.attributes
=> {"id"=>"work-1", "head"=>[], "tail"=>[], "title"=>"The Raven", "author"=>"Poe, Edgar Allan", "abstract"=>"A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'."}
Finally we'll get the Fedora URI and the abbreviated version (id
) of the object:
bw.uri
=> #<RDF::URI:0x3ffe7839ab64 URI:http://127.0.0.1:8984/rest/dev/work-1>
bw.id
=> "work-1"
Validate hydra-works model type:
bw.collection?
=> false
bw.work?
=> true
bw.file_set?
=> false
bw.pcdm_collection?
=> false
bw.pcdm_object?
=> true
Reference: How to retrieve a saved bibliographic resource work?
bw = BibliographicWork.find("work-1")
NOTE: This is useful if you have to take a break from the tutorial and want to get the objects back. You can't use new twice with the same id.
Step 4: In the console, create a bibliographic resource file
Let's create a new BibliographicFileSet instance. I've shown the expected output after each command:
bf = BibliographicFileSet.new(id: 'fileset-1', title: 'The Raven pdf')
=> #<BibliographicFileSet id: "fileset-1", head: [], tail: [], title: "The Raven pdf">
bf.save
=> true
puts bf.resource.dump(:ttl)
<http://127.0.0.1:8984/rest/dev/fileset-1> a <http://fedora.info/definitions/v4/repository#Container>,
<http://projecthydra.org/works/models#FileSet>,
<http://fedora.info/definitions/v4/repository#Resource>,
<http://pcdm.org/models#Object>,
<http://www.w3.org/ns/ldp#RDFSource>,
<http://www.w3.org/ns/ldp#Container>;
<http://purl.org/dc/terms/title> "The Raven pdf";
<http://fedora.info/definitions/v4/repository#created> "2016-06-13T14:16:40.138Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
<http://fedora.info/definitions/v4/repository#createdBy> "bypassAdmin";
<http://fedora.info/definitions/v4/repository#exportsAs> <http://127.0.0.1:8984/rest/dev/fileset-1/fcr:export?format=jcr/xml>;
<http://fedora.info/definitions/v4/repository#hasParent> <http://127.0.0.1:8984/rest/dev>;
<http://fedora.info/definitions/v4/repository#lastModified> "2016-06-13T14:16:40.138Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
<http://fedora.info/definitions/v4/repository#lastModifiedBy> "bypassAdmin";
<http://fedora.info/definitions/v4/repository#numberOfChildren> "0"^^<http://www.w3.org/2001/XMLSchema#long>;
<http://fedora.info/definitions/v4/repository#writable> true;
<info:fedora/fedora-system:def/model#hasModel> "BibliographicFileSet" .
<http://127.0.0.1:8984/rest/dev/fileset-1/fcr:export?format=jcr/xml> <http://purl.org/dc/elements/1.1/format> <http://fedora.info/definitions/v4/repository#jcr/xml> .
=> nil
We've created a new bibliographic resource file in the repository. You can see that it has a URI (Fedora Commons persistence identifier) of 'http://127.0.0.1:8984/rest/dev/fileset-1' (default username/password fedoraAdmin/fedoraAdmin
). Because you set title you can see that it is also stored in the RDF graph. We can retrieve those values by calling their accessors.
bf.title
=> "The Raven pdf"
Finally we'll get the Fedora URI and the abbreviated version (id
) of the object:
bf.uri
=> #<RDF::URI:0x3ffe777dc4d0 URI:http://127.0.0.1:8984/rest/dev/fileset-1>
bf.id
=> "fileset-1"
Validate hydra-works model type:
bf.collection?
=> false
bf.work?
=> false
bf.file_set?
=> true
bf.pcdm_collection?
=> false
bf.pcdm_object?
=> true
Reference: How to retrieve a saved bibliographic resource file?
bf = BibliographicFileSet.find("fileset-1")
NOTE: This is useful if you have to take a break from the tutorial and want to get the objects back. You can't use new twice with the same id.
Step 5: In the console, add BibliographicWork to Collection and BibliographicFileSet to BibliographicWork
Add a work into a collection and add a file set into a work (all created in previous steps):
col.members << bw
=> [#<BibliographicWork id: "work-1", head: [], tail: [], title: "The Raven", author: "Poe, Edgar Allan", abstract: "A lonely man tries to ease his 'sorrow for the los...">]
col.save
=> true
bw.members << bf
=> [#<BibliographicFileSet id: "fileset-1", head: [], tail: [], title: "The Raven pdf">]
bw.save
=> true
See a list of all works in a collection and all file sets in a work and their reverse relationships:
col.works
=> [#<BibliographicWork id: "work-1", title: "The Raven", author: "Poe, Edgar Allan", head_id: nil, tail_id: nil>]
bw.in_collections
=> [#<Collection id: "col-1", title: "Works by Edgar Allan Poe", head_id: nil, tail_id: nil>]
bw.file_sets
=> [#<BibliographicFileSet id: "fileset-1", title: "The Raven pdf", head_id: nil, tail_id: nil>]
bf.in_works ### TODO in_works returns []
=> [#<BibliographicWork id: "work-1", title: "The Raven", author: "Poe, Edgar Allan", abstract: "A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'.", head_id: nil, tail_id: nil>]
NOTE: FileSet's in_works method fails to return the work. See issue #301
Step 6: Adding more members to a Collection and getting specific type members.
Let's build a few additional objects to play around with.
col2 = Collection.new(id: 'col-2', title: 'Collection 2')
=> #<Collection id: "col-2", head: [], tail: [], title: "Collection 2">
col2.save
=> true
bw2 = BibliographicWork.new(id: 'work-2', title: 'Work 2')
=> #<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>
bw2.save
=> true
Add these as members of the Collection.
# add a collection as a member of the collection
col.members << col2
=> [#<BibliographicWork id: "work-1", head: [], tail: [], title: "The Raven", author: "Poe, Edgar Allan", abstract: "A lonely man tries to ease his 'sorrow for the los...">,
#<Collection id: "col-2", head: [], tail: [], title: "Collection 2">]
# add a second work as a member of the collection
col.members << bw2
=> [#<BibliographicWork id: "work-1", head: [], tail: [], title: "The Raven", author: "Poe, Edgar Allan", abstract: "A lonely man tries to ease his 'sorrow for the los...">,
#<Collection id: "col-2", head: [], tail: [], title: "Collection 2">,
#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>]
col.save
=> true
You can get just collections or just works from the collection.
# get all members
col.members
=> [#<BibliographicWork id: "work-1", head: [], tail: [], title: "The Raven", author: "Poe, Edgar Allan", abstract: "A lonely man tries to ease his 'sorrow for the los...">,
#<Collection id: "col-2", head: [], tail: [], title: "Collection 2">,
#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>]
# get just collections
col.collections
=> [#<Collection id: "col-2", head: [], tail: [], title: "Collection 2">]
# get just works
col.works
=> [#<BibliographicWork id: "work-1", head: [], tail: [], title: "The Raven", author: "Poe, Edgar Allan", abstract: "A lonely man tries to ease his 'sorrow for the lost Lenore', by distracting his mind with old books of 'forgotten lore'.">,
#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>]
# get which collections a collection is in
col2.in_collections
=> [#<Collection id: "col-1", head: [], tail: [], title: "Works by Edgar Allan Poe">]
# what you get if the collection isn't in any other collections
col.in_collections
=> []
Step 7: Adding more members to a BibliographWork and getting specific type members.
Let's build another file set to play around with.
bf2 = BibliographicFileSet.new(id: 'fileset-2', title: 'File Set 2')
=> #<BibliographicFileSet id: "fileset-2", head: [], tail: [], title: "File Set 2">
bf2.save
=> true
Using the instances created in the previous step and the new file set, add more members to the BibliographicWork.
# add a work as a member of the work
bw.members << bw2
=> [#<BibliographicFileSet id: "fileset-1", head: [], tail: [], title: "The Raven pdf">,
#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>]
# add a second file set as a member of the work
bw.members << bf2
=> [#<BibliographicFileSet id: "fileset-1", head: [], tail: [], title: "The Raven pdf">,
#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>,
#<BibliographicFileSet id: "fileset-2", head: [], tail: [], title: "File Set 2">]
bw.save
=> true
You can get just works or just file sets that are members of a work.
# get all members
bw.members
=> [#<BibliographicFileSet id: "fileset-1", head: [], tail: [], title: "The Raven pdf">,
#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>,
#<BibliographicFileSet id: "fileset-2", head: [], tail: [], title: "File Set 2">]
# get just works
bw.works
=> [#<BibliographicWork id: "work-2", head: [], tail: [], title: "Work 2", author: nil, abstract: nil>]
# get just file sets
bw.file_sets
=> [#<BibliographicFileSet id: "fileset-1", head: [], tail: [], title: "The Raven pdf">,
#<BibliographicFileSet id: "fileset-2", head: [], tail: [], title: "File Set 2">]
There are other methods that can be used to manipulate and retrieve members. See Aggregations API Documentation for more information.
Once you're done, exit the console by typing exit
Next Step
Go on to Lesson: Explore Objects in Fedora and Solr or return to the Dive into Hydra-Works page.