Skip to content

Understanding resources

E. Lynette Rayle edited this page Oct 22, 2020 · 19 revisions

back to Introduction

Goals

  • Configure autoloading for resources for this app.
  • Define a custom resource (Book).
  • Describe attribute types.
  • Describe attribute modifiers.
  • Describe special attributes.

Reference: Valkyrie Documentation Example Resource | supported types | using type | dry-types |

Valkyrie resources take the place of ActiveRecord::Models. A resource defines the attributes for a persistent object model. Each attribute is assigned a type and can have modifiers (e.g. of, meta, etc.). Set and Array are types for multi-valued attributes. The remaining types are single value types. See the references above for more information.

Add autoload for resources

Edit config/application.rb and under the line config.load_defaults 5.2 inside the ValkyriePgDemo module and Application class definition, add the following:

config.autoload_paths += %W(#{config.root}/app)

This configures the application to autoload from all directories under the app directory.

Defining resources

The following resources will be used throughout the tutorial.

Create the directory app/resources inside your project directory. Edit app/resources/book.rb to contain the following:

# frozen_string_literal: true
class Book < Valkyrie::Resource
  attribute :alternate_ids, Valkyrie::Types::Array
              .of(Valkyrie::Types::ID)
  attribute :title, Valkyrie::Types::Set
              .of(Valkyrie::Types::String)
              .meta(ordered: true)
  attribute :author, Valkyrie::Types::Set
              .of(Valkyrie::Types::Strict::String)
              .meta(ordered: true)
  attribute :series, Valkyrie::Types::Strict::String  
  attribute :member_ids, Valkyrie::Types::Array
              .of(Valkyrie::Types::ID).optional
  # attribute :cover_art, Valkyrie::Types::Array
  #             .of(CoverArt)                            
end

Attribute types:

  • Valkyrie::Types::Array allows multiple values, including duplicates. Examples above: Book.alternate_ids, Book.cover_art
  • Valkyrie::Types::Set allows multiple values, removing duplicates. Examples above: Book.author, Book.title
  • Valkyrie::Types::ID internal identifier used to link Valkyrie resources. Examples above: Page.image_id, CoverArt.image_id
  • Valkyrie::Types::String single value that is expected to be a string
  • Strict in a type declaration causes an error to be raised when a value doesn't match the specified type. Example: Book.series is declared as Valkyrie::Types::Strict::String
  • Custom type specifying the expected class (e.g. CoverArt). Defining cover_art as type CoverArt causes the cover art resource to be stored with the book resource instead of as a separate entity. More on this in Saving a resource.
info_16 CoverArt is commented out because we haven't defined it yet.
info_16 If an attribute is defined with a Strict type, a value of that type is required. To allow for a nil value, append .optional after the type declaration.

Attribute modifiers:

  • .of: declares the expected type of the elements of a multi-valued attribute. examples above: Book.alternate_ids is an array of Valkyrie::Types::ID. Book.title is a set of Valkyrie::Types::String. Book.cover_art is an array of CoverArt resources.
  • .meta(ordered: true) maintains order
  • .optional allows an attribute to have a nil value

Special attributes:

  • id -- reserved - This is the main Valkyrie::ID identifying the resource. All resources have an id. You do not need to define one.
  • alternate_ids -- This is expected to be an Array of Valkyrie::ID. This allows for a datasource specific formatted id. (e.g.numeric for Postgres and UUID for Fedora)
  • member_ids -- This is expected to be an Array of Valkyrie::ID. It holds the IDs for any resources that are members of this resource.

More on these in Retrieving resources.

SPOTCHECK

Run the following in a new rails console (bundle exec rails console) to confirm resources are working as expected.

Create a resource and test assigning expected and unexpected types

Create a new book.

> book = Book.new

Try assigning Integers to String typed attributes.

> book.title = 1   
=> 1
> book.title.first.class
=> Integer

Note that book.title is a Fixnum even though the title attribute is defined as a String. This is because basic attribute types indicate the type of value expected for a given attribute, but do not enforce type restrictions. See dry-types example usage documentation for more information.

Next, try assigning an Integer value to Strict::String typed attributes like author and series.

> book.author = 2  
 => Dry::Types::ConstraintError (2 violates constraints (type?(String, 2) failed))
> book.series = 3  
 => Dry::Types::ConstraintError (3 violates constraints (type?(String, 3) failed))

Now set values as expected to give us a good resource to work with. We'll see more on enforcing types and other validations in [Understanding Change Sets] and [Testing change set validations].

> book.alternate_ids = 'b1'           
 => "b1"
> book.alternate_ids                  
 => [#<Valkyrie::ID:... @id="b1">]
> book.title = "Sorcerer's Stone"     
 => "Sorcerer's Stone"
> book.title                          
 => ["Sorcerer's Stone"]
> book.title << "Philosopher's Stone"
 => ["Sorcerer's Stone", "Philosopher's Stone"]
> book.author = "J. K. Rowling"       
 => "J. K. Rowling"
> book.author                         
 => ["J. K. Rowling"]
> book.series = "Harry Potter"        
 => "Harry Potter"
> book.series                         
 => "Harry Potter"

Previous | Next

Clone this wiki locally