Overview | Documentation | Community

ActiveFedora Console Tour

Setup

  • You must have Fedora running in order for this to work.

You have two options for setting up the environment. 1) check out the full ActiveFedora source code, or 2) set up a rails app and run the console within that.

Option 2: Use a Rails App

If you don't want to bother with checking out the source code, you should set up a rails app and run script/console within that. If you choose to take that approach, you can define the model in /app/models rather than pasting it into the console.

The Tour

Open the Cosnole

This will load the ruby interactive console along with the ActiveFedora classes. If you are running within the ActiveFedora sources, it will also initialize connections to Fedora & Solr at localhost:8080

cd into the root directory of your code (either the ActiveFedora source code or your Rails app), then enter the following command

script/console

Define a Model

If you are running this in a rails app, you can put this code into app/models/oral_history.rb and then restart the console. Otherwise, paste all of this directly into the console:
class OralHistory < ActiveFedora::Base

   has_relationship "parts", :is_part_of, :inbound => true

  has_metadata :name => "dublin_core", :type => ActiveFedora::QualifiedDublinCoreDatastream do |m|
        # With QualifiedDublinCoreDatastreams, you only have to declare variations from the standard set of DCMI Terms.  The rest are automatically included.
        m.field "subject_heading", :string, :xml_node => "subject", :encoding => "LCSH" 
  end

    has_metadata :name => "properties", :type => ActiveFedora::MetadataDatastream do |m|
          # For metadata that doesn't fit elsewhere, you can create simple xml documents.
          m.field "my_metadata_field", :string
   end
end

Initialize the connections to Fedora and Solr

ActiveFedora::SolrService.register(SOLR_URL)
Fedora::Repository.register(FEDORA_URL)

Create an instance of the OralHistory class

oh = OralHistory.new
Get the pid of your new object
oh.pid
=> "changeme:30" 

This pid was retrieved from Fedora's getNextPid method. Your object will not show up in Fedora until you save it using oh.save.

RELATIONSHIPS

ActiveFedora provides convenience methods for creating and editing RELS-EXT relationships. It also auto-generates methods for using Solr to search based on these relationships.

List the object's relationships.
oh.relationships
=> {:self=>{}}
Call the "parts" method that was created by the has_relationship line in your class definition.
oh.parts
=> []
Now create another Fedora object and make it assert that it's a part of the OralHistory object, then save it to Fedora.
part = ActiveFedora::Base.new
part.add_relationship(:is_part_of, oh)
=> true
part.relationships
=> {:self=>{:is_part_of=>["info:fedora/changeme:233"]}}
part.save
=> ...

You can now see that object in Fedora by going to http://localhost:8080/fedora/objects/{PID} and you can see the relationship asserted in http://localhost:8080/fedora/objects/{PID}/datastreams/RELS-EXT/content

Now look and see that the object you created shows up when you call oh.parts
oh.parts
=> ...
oh.parts.each {|pt| puts pt.pid }
=> ...
oh.parts(:response_format=>:id_array)
=> ...

Note that you didn't have to save the oral history in order for this relationship to show up in solr because it is an inbound relationship. The child asserts :is_member_of rather than the parent asserting :has_member, so you only have to save the child to solr in order for it to work.

Collection Members

As of 1.0.4, all instances of ActiveFedoraL::Base and its subclasses have convenience methods for tracking collection members. We mainly use this to add references to file asset objects.
These methods are also an example of what you would get if you declared the following in one of your models.

has_relationship "collection_members", :has_collection_member, :inbound=>false

Create a new object and add it to the OralHistory's collection members. This time you have to save the object in order for the relationship to show up in solr because it is an outbound relationship where the OralHistory asserts :has_collection_member and points to the collection member object.
cm = ActiveFedora::Base.new
cm.pid
=> changeme:9
oh.collection_members_append(cm)
oh.save
oh.collection_members(:response_format => :id_array)
=> ["changeme:9"]

DATASTREAMS & METADATA

Blobs (a.k.a. File Datastreams, a.k.a Managed Content Datastreams)

file = File.new('spec/fixtures/minivan.jpg')
=> #<File:spec/fixtures/minivan.jpg>
file_ds = ActiveFedora::Datastream.new(:dsID => "minivan", :dsLabel => 'hello', :controlGroup => 'M', :blob => file)
=> ...
oh.add_datastream(file_ds)
=> "minivan" 
oh.save
=> true

Now user your browser to find the file datastreams in Fedora ...

MetadataDatastreams

prop = oh.datastreams["properties"]
prop.fields
=> {:my_metadata_field=>{:type=>:string, :values=>[]}}
prop.my_metadata_field_values << "my value" 
=> ["my value"]
prop.fields
=> {:my_metadata_field=>{:type=>:string, :values=>["my value"]}}

QualifiedDublinCoreDatastreams

QualifiedDublinCoreDatastream is a subclass of MetadataDatastream that is pre-configured to support all of the DCMI Metadata Terms.

oh.datastreams.keys
=> ["RELS-EXT", "DC", "dublin_core", "properties"]
dc = oh.datastreams["dublin_core"]
dc.class
=> ActiveFedora::QualifiedDublinCoreDatastream
dc.fields
=> ...
dc.subject_values
=> []
dc.subject_heading_values
=> []
dc.subject_values << "foo" 
=> ["foo"]
dc.subject_heading_values = ["bar", "baz"]
=> ["bar", "baz"]
dc.subject_values
=> ["foo"]
dc.subject_heading_values
=> ["bar", "baz"]

Serializing Metadata

dc.to_dc_xml
=> "<dc xmlns:dcterms='http://purl.org/dc/terms/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><dcterms:subject xsi:type='LCSH'>bar</dcterms:subject><dcterms:subject xsi:type='LCSH'>baz</dcterms:subject><dcterms:subject>foo</dcterms:subject></dc>" 

dc.to_xml
=> "<fields><subject_heading>bar</subject_heading><subject_heading>baz</subject_heading><subject>foo</subject></fields>" 

dc.to_solr
=> #<Solr::Document:0x1e5c0f8 @fields=[#<Solr::Field:0x1e590d8 @boost=nil, @value="bar", @name="subject_heading_field">, #<Solr::Field:0x1e5904c @boost=nil, @value="baz", @name="subject_heading_field">, #<Solr::Field:0x1e588e0 @boost=nil, @value="foo", @name="subject_field">]>
prop.to_xml
=> "<fields><my_metadata_field>my value</my_metadata_field></fields>" 

prop.to_solr
=> #<Solr::Document:0x1ac5638 @fields=[#<Solr::Field:0x1ac54bc @boost=nil, @value="my value", @name="my_metadata_field_field">]>

On auto-generating datatsream ids

If you don't specify a dsid, ActiveFedora will generate one for you.

file_ds2 = ActiveFedora::Datastream.new(:dsLabel => 'Minivan Plays', :altIDs => 'default', :controlGroup => 'M', :blob => file)
oh.add_datastream(file_ds2)
=> "DS1" 
oh.datastreams.keys
=> ["DS1", "minivan", "RELS-EXT", "DC", "dublin_core", "properties"]
>> oh.datastreams_in_memory["DS1"] == file_ds2
=> true

You can choose a different prefix for the dsid by passing a :prefix value to add_datastream (be careful to ensure that the resulting dsid is a valid XMLString, or fedora will reject it!)

file_ds3 = ActiveFedora::Datastream.new(:dsLabel => 'Minivan Plays', :altIDs => 'default', :controlGroup => 'M', :blob => file)
oh.add_datastream(file_ds3, :prefix=>"Foo")
=> "Foo1" 
oh.datastreams.keys
oh.save

Retrieving Existing Objects

You can use the load_instance class method on any kind of ActiveFedora::Base class to load objects from Fedora.

oh.pid
=> "changeme:30" 
copy_as_base = ActiveFedora::Base.load_instance("changeme:30")
copy_as_base.pid
=> "changeme:30" 
copy_as_base.relationships
=> {:self=>{:conforms_to=>["info:fedora/afmodel:OralHistory"], :has_collection_member=>["info:fedora/changeme:16"]}}
copy_as_base.datastreams.keys
=> ["DS1", "Foo1", "minivan", "RELS-EXT", "DC", "dublin_core", "properties"]

As you can see, ActiveFedora::Base will load the object, its datastreams, it's generic Fedora Object information, and even its RELS-EXT relationships. It will not, however, know how to deserialize any model-specific metadata datastreams. In other words, ActiveFedora::Base treats all datastreams as generic Fedora datastreams.

>> copy_as_base.datastreams["dublin_core"].class
=> ActiveFedora::Datastream

If you want the model-specific metadata to be deserialized, you must call load_instance on the appropriate model class. This will load all of the same info as ActiveFedora::Base, but it will also attempt to deserialize the xml from any metadata datastreams that were declared by the has_metadata method in the model.

copy_as_oh = OralHistory.load_instance(oh.pid)
copy_as_oh.datastreams["dublin_core"].class
=> ActiveFedora::QualifiedDublinCoreDatastream
copy_as_oh.datastreams["properties"].class
=> ActiveFedora::MetadataDatastream
copy_as_oh.datastreams["dublin_core"].subject_heading_values
=> ["bar", "baz"]
copy_as_oh.datastreams["dublin_core"].subject_values
=> ["foo"]

Finding Objects

All descendants of ActiveFedora::Base provide a find method that will search for objects of the given class. The method is somewhat incomplete at the moment, but is functional. We are actively working on making it better.

Finding Instances of the Class

Imitating ActiveRecord, you can search for instances of the given class by calling find(:all) on that class. In current versions of the gem, this method searches solr using the active_fedora_model_field. In future versions it will not hit solr at all, instead relying on Fedora's Resource Index and searching for anything that asserts "conformsTo" or "hasModel" relationships pointing at the given model.
Base.find(:all)
OralHistory.find(:all)

Note that the results from these two searches do not overlap. OralHistory.find will only return objects that have been saved with active_fedora_model_field set to "info:fedora/afmodel:OralHistory". If you open an object as an instance of a different model and save it as that model, it will overwrite the active_fedora_model_field. This is, of course, no good. That's why the method will be rewritten in Version 1.1. In the meantime, you could search directly against Solr with queries like this:

solr_result = ActiveFedora::SolrService.instance.conn.query('conforms_to_field:info\:fedora/afmodel\:OralHistory')

This query will return a Solr::Result containing all of the objects that have conformsTo relationships pointing at info:fedora/afmodel:OralHistory in their RELS-EXT. This relationship gets added to the RELS-EXT whenever you save an object as a given ActiveFedora model and it does not get erased if you later save it as a different model.

Finding (Loading) a specific Object

You can use this instead of .load_instance
Base.find("changeme:30")
OralHistory.find("changeme:30")

Find By Solr

The find_by_solr method always searches against solr. You can use it just like .find, but it will return a Solr::Result instead of ActiveFedora objects. This is basically there in case you want to explicitly hit solr when using future versions of ActiveFedora (where the ordinary find method no longer hits solr).

Base.find_by_solr(:all)
OralHistory.find_by_solr(:all)

Getting Started

Also available in: HTML TXT