-
Notifications
You must be signed in to change notification settings - Fork 23
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::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 asValkyrie::Types::Strict::String
- Custom type specifying the expected class (e.g. CoverArt). Defining
cover_art
as typeCoverArt
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.
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_ids
is an array ofValkyrie::Types::ID
.Book.title
is a set ofValkyrie::Types::String
.Book.cover_art
is an array ofCoverArt
resources. -
.meta(ordered: true)
maintains order -
.optional
allows an attribute to have anil
value
-
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 anArray
ofValkyrie::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 anArray
ofValkyrie::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.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"