Class: Valkyrie::Resource

Inherits:
Dry::Struct
  • Object
show all
Defined in:
lib/valkyrie/resource.rb,
lib/valkyrie/resource/access_controls.rb

Overview

The base resource class for all Valkyrie metadata objects. rubocop:disable Metrics/ClassLength

Examples:

Define a resource

class Book < Valkyrie::Resource
  attribute :member_ids, Valkyrie::Types::Array
  attribute :author
end

See Also:

Defined Under Namespace

Modules: AccessControls Classes: ReservedAttributeError

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.allow_nonexistent_keysObject

Allows a Valkyrie::Resource to be instantiated without providing every available key, and makes sure the defaults are set up if no value is given.



21
22
23
# File 'lib/valkyrie/resource.rb', line 21

def self.allow_nonexistent_keys
  transform_types(&:omittable)
end

.attribute(name, type = Valkyrie::Types::Set.optional, internal: false) ⇒ Object

Note:

Overridden from Dry::Struct to make the default type Types::Set

Define an attribute. Attributes are used to describe resources.

Parameters:

  • name (Symbol)
  • type (Dry::Types::Type) (defaults to: Valkyrie::Types::Set.optional)

Raises:



47
48
49
50
51
52
53
# File 'lib/valkyrie/resource.rb', line 47

def self.attribute(name, type = Valkyrie::Types::Set.optional, internal: false)
  raise ReservedAttributeError, "#{name} is a reserved attribute and defined by Valkyrie::Resource, do not redefine it." if reserved_attributes.include?(name.to_sym) &&
                                                                                                                            attribute_names.include?(name.to_sym) &&
                                                                                                                            !internal

  super(name, type)
end

.attributes(new_schema) ⇒ Dry::Struct

Note:

extends Dry::Struct by adding ‘#attr=` style setters

Parameters:

  • new_schema (Hash{Symbol => Dry::Types::Type})

Returns:

  • (Dry::Struct)

Raises:

  • (RepeatedAttributeError)

    when trying to define attribute with the same name as previously defined one

  • (ReservedAttributeError)

    when trying to define an attribute reserved by Valkyrie

See Also:

  • #attribute


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/valkyrie/resource.rb', line 63

def self.attributes(new_schema)
  new_schema[:member_ids] = new_schema[:member_ids].meta(ordered: true) if
    new_schema.key?(:member_ids)

  super

  new_schema.each_key do |key|
    key = key.to_s.chomp('?')
    next if instance_methods.include?("#{key}=".to_sym)

    class_eval(<<-RUBY)
      def #{key}=(value)
        set_value("#{key}".to_sym, value)
      end
    RUBY
  end

  self
end

.enable_optimistic_lockingObject



103
104
105
# File 'lib/valkyrie/resource.rb', line 103

def self.enable_optimistic_locking
  attribute(Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK, Valkyrie::Types::Set.of(Valkyrie::Types::OptimisticLockToken))
end

.fieldsArray<Symbol>

Returns Array of fields defined for this class.

Returns:

  • (Array<Symbol>)

    Array of fields defined for this class.



38
39
40
# File 'lib/valkyrie/resource.rb', line 38

def self.fields
  attribute_names.without(:new_record)
end

.human_readable_typeObject



95
96
97
# File 'lib/valkyrie/resource.rb', line 95

def self.human_readable_type
  @_human_readable_type ||= name.demodulize.titleize
end

.human_readable_type=(val) ⇒ Object



99
100
101
# File 'lib/valkyrie/resource.rb', line 99

def self.human_readable_type=(val)
  @_human_readable_type = val
end

.inherited(subclass) ⇒ Object

Note:

The current theory is that we should use this sparingly.

Overridden to provide default attributes.



27
28
29
30
31
32
33
34
35
# File 'lib/valkyrie/resource.rb', line 27

def self.inherited(subclass)
  super(subclass)
  subclass.allow_nonexistent_keys
  subclass.attribute :id, Valkyrie::Types::ID.optional, internal: true
  subclass.attribute :internal_resource, Valkyrie::Types::Any.default(subclass.to_s.freeze), internal: true
  subclass.attribute :created_at, Valkyrie::Types::DateTime.optional, internal: true
  subclass.attribute :updated_at, Valkyrie::Types::DateTime.optional, internal: true
  subclass.attribute :new_record, Types::Bool.default(true), internal: true
end

.model_nameActiveModel::Name

Note:

Added for ActiveModel compatibility.

Returns:

  • (ActiveModel::Name)


89
90
91
# File 'lib/valkyrie/resource.rb', line 89

def self.model_name
  @model_name ||= ::ActiveModel::Name.new(self)
end

.optimistic_locking_enabled?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/valkyrie/resource.rb', line 107

def self.optimistic_locking_enabled?
  schema.key?(Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK)
end

.reserved_attributesObject



83
84
85
# File 'lib/valkyrie/resource.rb', line 83

def self.reserved_attributes
  [:id, :internal_resource, :created_at, :updated_at, :new_record]
end

Instance Method Details

#[](name) ⇒ Object

Return an attribute’s value.

Parameters:

  • name (#to_sym)

    the name of the attribute to read



177
178
179
180
181
# File 'lib/valkyrie/resource.rb', line 177

def [](name)
  super(name.to_sym)
rescue Dry::Struct::MissingAttributeError
  nil
end

#__attributes__Object



123
124
125
# File 'lib/valkyrie/resource.rb', line 123

def __attributes__
  Hash[@attributes].freeze
end

#attributesObject



119
120
121
# File 'lib/valkyrie/resource.rb', line 119

def attributes
  Hash[self.class.attribute_names.map { |x| [x, nil] }].merge(super).freeze
end

#clear_optimistic_lock_token!Object



115
116
117
# File 'lib/valkyrie/resource.rb', line 115

def clear_optimistic_lock_token!
  send("#{Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK}=", []) if optimistic_locking_enabled?
end

#column_for_attribute(name) ⇒ Symbol

Note:

Added for ActiveModel compatibility.

Parameters:

  • name (Symbol)

Returns:

  • (Symbol)


140
141
142
# File 'lib/valkyrie/resource.rb', line 140

def column_for_attribute(name)
  name
end

#dupObject



127
128
129
# File 'lib/valkyrie/resource.rb', line 127

def dup
  new({})
end

#has_attribute?(name) ⇒ Boolean

Parameters:

  • name (Symbol)

    Attribute name

Returns:

  • (Boolean)


133
134
135
# File 'lib/valkyrie/resource.rb', line 133

def has_attribute?(name)
  respond_to?(name)
end

#human_readable_typeString

Provide a human readable name for the resource

Returns:

  • (String)


170
171
172
# File 'lib/valkyrie/resource.rb', line 170

def human_readable_type
  self.class.human_readable_type
end

#optimistic_locking_enabled?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/valkyrie/resource.rb', line 111

def optimistic_locking_enabled?
  self.class.optimistic_locking_enabled?
end

#ordered_attribute?(key) ⇒ Boolean

Returns if an attribute is set as ordered.

Returns:

  • (Boolean)


192
193
194
# File 'lib/valkyrie/resource.rb', line 192

def ordered_attribute?(key)
  self.class.schema.key(key.to_sym).type.meta.try(:[], :ordered)
end

#persisted?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/valkyrie/resource.rb', line 145

def persisted?
  new_record == false
end

#set_value(key, value) ⇒ Object

Set an attribute’s value.

Parameters:

  • key (#to_sym)

    the name of the attribute to set

  • value

    the value to set key to.



187
188
189
# File 'lib/valkyrie/resource.rb', line 187

def set_value(key, value)
  @attributes[key.to_sym] = self.class.schema.key(key.to_sym).type.call(value)
end

#to_keyObject



149
150
151
# File 'lib/valkyrie/resource.rb', line 149

def to_key
  [id]
end

#to_modelObject

Note:

Added for ActiveModel compatibility



158
159
160
# File 'lib/valkyrie/resource.rb', line 158

def to_model
  self
end

#to_paramObject



153
154
155
# File 'lib/valkyrie/resource.rb', line 153

def to_param
  to_key.map(&:to_s).join('-')
end

#to_sString

Returns:

  • (String)


163
164
165
# File 'lib/valkyrie/resource.rb', line 163

def to_s
  "#{self.class}: #{id}"
end