-
Notifications
You must be signed in to change notification settings - Fork 20
Understanding resources
- 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.
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.
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-
Valkyrie::Types::Arrayallows multiple values, including duplicates. Examples above:Book.alternate_ids,Book.cover_art -
Valkyrie::Types::Setallows multiple values, removing duplicates. Examples above:Book.author,Book.title -
Valkyrie::Types::IDinternal identifier used to link Valkyrie resources. Examples above:Page.image_id,CoverArt.image_id -
Valkyrie::Types::Stringsingle value that is expected to be a string -
Strictin a type declaration causes an error to be raised when a value doesn't match the specified type. Example:Book.seriesis declared asValkyrie::Types::Strict::String - Custom type specifying the expected class (e.g. CoverArt). Defining
cover_artas typeCoverArtcauses the cover art resource to be stored with the book resource instead of as a separate entity. More on this in Saving a resource.
CoverArt is commented out because we haven't defined it yet. |
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. |
-
.of: declares the expected type of the elements of a multi-valued attribute. examples above:Book.alternate_idsis an array ofValkyrie::Types::ID.Book.titleis a set ofValkyrie::Types::String.Book.cover_artis an array ofCoverArtresources. -
.meta(ordered: true)maintains order -
.optionalallows an attribute to have anilvalue
-
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 anArrayofValkyrie::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 anArrayofValkyrie::ID. It holds the IDs for any resources that are members of this resource.
More on these in Retrieving resources.
Run the following in a new rails console (bundle exec rails console) to confirm resources are working as expected.
Create a new book.
> book = Book.newTry assigning Integers to String typed attributes.
> book.title = 1
=> 1
> book.title.first.class
=> IntegerNote 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"
CoverArt is commented out because we haven't defined it yet.