Skip to content

Models Defining a Custom Hydra Model

awead edited this page Jun 20, 2012 · 13 revisions

Models – Defining a Custom Hydra Model

General Introduction/Tutorial

The Getting Started Building Your Own Hydra Application tutorial includes a detailed section on defining a JournalArticle model. Read that to get a sense of how to create a working Hydra Model.

Steps to Defining Your Model

These steps assume you have gone through the basic Hydra app setup and familiar with its general workings. In order to create a custom model, you’ll need to know how to create your OM terminology if you have a specific XML schema you want to use, or work with an existing OM terminology if one of the ones included with Hydra is sufficient.

Additionally, you’ll also need to know how to write rspec tests using fixtures, and have a working knowledge of the Fedora object relationship model. For help with rspec tests, it’s best to use the examples found in Hydra-Head as examples. You can copy those into your own application ands modify them to test your particular model. For more information about Fedora, see: “https://wiki.duraspace.org/display/FEDORA/Home”

  1. Pick xml schema(s)
  2. Create “fixture” XML
  3. Define or reuse OM Terminologies & Datastream Classes for your XML
  4. Write rspec tests for your Datastream classes
  5. Define the Model
  6. Write rspec tests for your Model
  7. Decide what relationships your Model will have & which predicates to use
  8. Add relationship methods to your Model
  9. Define a rightsMetadata datastream for your objects
  10. Setup depositor/owner permissions (include Hydra::ModelMethods in your model)
  11. Define any default permissions if needed
  12. Define delegate terms

rightsMetadata and Depositor/Owner Permissions

Two steps are necessary in order to ensure that your controllers will be able to set the permissions on your Assets. If you don’t follow these steps, users will be able to create objects but won’t be able to edit them.

Before reading this, make sure to read the page on Hydra Access Controls

Ensuring objects have a rightsMetadata datastream

If you are adhering to the formal Hydra commonMetadata cModel, which says that you must have a descMetadata datastream and a rightsMetadata datastream, you can put this line in your model:

  # This model adheres to the formal Hydra commonMetadata cModel, meaning that it has a descMetadata datastream and a rightsMetadata datastream
  include Hydra::ModelMixins::CommonMetadata

If you are not adhering to the formal Hydra commonMetadata cModel and simply want to have a rightsMetadata datastream, declare the datastream directly in your Model

  # Explicitly declaring rightsMetadata datastream
  has_metadata :name => "rightsMetadata", :type => Hydra::RightsMetadata

Using Hydra::ModelMethods

{Hydra::ModelMethods} will provide the {Hydra::ModelMethods#apply_depositor_metadata} method within your Controllers which in turn ensures that the user will have edit permissions on the objects he or she creates. When the user logs into the Hydra application, their login (ie. [email protected]) will added to the to the rightsMetadata datastream to grant them edit access.

You might want to override this with a method that is more specific to your model. The most important behavior to retain is adding depositor_id to the asset’s individual edit permissions if the asset has a rightsMetadata datastream.

  # in your model
  include Hydra::ModelMethods

Applying other default permissions

Using Hydra’s system of access controls, you can have newly created objects with a default set of group permissions. If you are using apply_depositor_metadata correctly, the depositor will have access to the item, but what if you want to grant other people access to the object based on their group membership?

In that case, you can use the after_create hook in your model to run a method that applies some default permissions to your objects when they are created. Either in the model code itself or in a separate file that you can include later, create a method called apply_default_permissions:

  def apply_default_permissions
    self.datastreams["rightsMetadata"].update_permissions( "group"=>{"archivist"=>"edit"} )
    self.datastreams["rightsMetadata"].update_permissions( "group"=>{"reviewer"=>"edit"} )
    self.datastreams["rightsMetadata"].update_permissions( "group"=>{"donor"=>"read"} )
    self.save
  end

This method will grant edit privileges to the archivist and reviewer groups, while anyone in the donor group will have read access. These groups and their members are define in the config/role_mapper_*.yml files. There will be one role mapper file for each of the Rails environments: development, test and production. For example, if your role_mapper_production.yml file contains:

archivist:
  - [email protected]
donor:
  - [email protected]
reviewer:
  - [email protected]
researcher:
  - [email protected]
patron:
  - [email protected]

The archivist1 and reviewer1 users will have edit access to all objects, by default, as well as donor1 who will have read access to all objects. The patron1 user will not have any access unless it specifically granted via the Hydra web application.

Defining delegate terms

The last step in creating your model will be to define delegate terms to each of the fields you want to use in your model. Delegate terms allow your views and controllers to interact directly with the terms you’ve defined in OM. You will need to have a delegate defined for every term you want to use in a view. If you have terms in your OM definition that are not needed at the view level, then you won’t need to create delegates for them, however, it is advisable to create delegates for any OM term that needs to be displayed or edited in any way.

Putting it all together

Using these above examples and expanding upon the JournalArticle model that is used in the content type example, we can construct a more advanced Hydra model:

class JournalArticle < ActiveFedora::Base
  include Hydra::ModelMethods
  include Hydra::ModelMixins::CommonMetadata
  include ActiveFedora::Relationships

  after_create :apply_default_permissions

  has_relationship "objects", :is_part_of, :inbound => true
  
  has_metadata :name => "descMetadata",   :type => JournalArticleModsDatastream
  has_metadata :name => "rightsMetadata", :type => Hydra::RightsMetadata
  has_metadata :name => "properties",     :type => MyApp::MyProperties

  delegate :title,            :to=> :descMetadata, :unique=>"true"
  delegate :abstract,         :to=> :descMetadata, :unique=>"true"
  delegate :start_page,       :to=> :descMetadata
  delegate :end_page,         :to=> :descMetadata
  delegate :publication_date, :to=> :descMetadata
  delegate :journal_title,    :to=> :descMetadata
  delegate :journal_volume,   :to=> :descMetadata
  delegate :journal_issue,    :to=> :descMetadata
  delegate :depositor,        :to=> :properties

  def apply_depositor_metadata(depositor_id)
    self.depositor = depositor_id
    super
  end
  
  def apply_default_permissions
    self.datastreams["rightsMetadata"].update_permissions( "group"=>{"archivist"=>"edit"} )
    self.datastreams["rightsMetadata"].update_permissions( "group"=>{"reviewer"=>"edit"} )
    self.datastreams["rightsMetadata"].update_permissions( "group"=>{"donor"=>"read"} )
    self.save
  end

end

Other Topics

OM

  • namespaces
  • Indexing
    • index_as
    • suppressing fields
    • advanced indexing with custom solr schemas (:displayable and :searchable)
  • retrieving Terms & Values

More Information

Further questions? Ask the hydra-tech list or join the freenode #projecthydra IRC channel.