Skip to content

Using Types

Esmé Cowles edited this page Jul 31, 2018 · 7 revisions

Introduction

The type system for models comes from dry-types and is implemented via dry-struct, which have their own sets of documentation which we highly recommend everyone to read. However, as typing is a core aspect of Valkyrie, we felt it important to include our own little tutorial.

The purpose of types is to allow your models to automatically cast attributes to the appropriate type or even fail to instantiate should you give an inappropriate type. Some examples can be found below.

Built-in Types

Consult the dry-types list of built-in types for the list of standard types, including the typical String, boolean, numeric, datetime, etc. types. When using in Valkyrie, prefix the type with Valkyrie:: (e.g., Types::Integer becomes Valkyrie::Types::Integer).

Optional Types

Types which are marked as optional will become nil if not given a value on instantiation.

class Book < Valkyrie::Resource
  attribute :id, Valkyrie::Types::ID.optional
end

Book.new.id # => nil

Singular Values

There are a variety of types for single values, many of which can be found here. An important aspect to remember about Valkyrie is that while you can define a singular type, they will be stored in the backend as an array and then re-cast to singular. This is so that if you later change your mind and decide that you have multiple creators, you won't have to perform a costly data migration.

class Book < Valkyrie::Resource
  attribute :id, Valkyrie::Types::ID.optional
  attribute :creator, Valkyrie::Types::String
end

book = Book.new(creator: "Harry Potter")
book.creator # => "Harry Potter"
output = persister.save(resource: book) # This saves in your backend as ["Harry Potter"], but will cast to..
output.creator # => "Harry Potter"

Set & Array

Valkyrie::Types::Set and Valkyrie::Types::Array are provided as options for multi-valued fields. Set will de-duplicate and doesn't provide order, and Array will just store whatever you give it. Both will cast singular values to an array. You can define what kind of members are in an Array or Set via the of operator.

The default type for an attribute declaration is Valkyrie::Types::Set.optional

class Book < Valkyrie::Resource
  attribute :creators, Valkyrie::Types::Set
  attribute :nil_creators, Valkyrie::Types::Set.optional
  attribute :array_creators, Valkyrie::Types::Array
end

book = Book.new(creators: "one", array_creators: ["one", "one"])

book.creators # => ["one"]
book.nil_creators # => nil
book.array_creators # => ["one", "one"]