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.