Class: Halibut::Core::Resource

Inherits:
Object
  • Object
show all
Defined in:
lib/halibut/core/resource.rb

Overview

This class represents a HAL Resource object.

spec spec spec

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(href = nil, properties = {}, links = {}, embedded = {}) ⇒ Resource

Initialize a new Resource.

As defined in the spec, the resource SHOULD have a self link, but it isn’t required. Also optionally, I’m toying with the idea of being able to pass in properties, links and embedded resources as parameters to this method, like suggested in github.com/locks/halibut/issues/1.

# Resource without self link (e.g. POSTing a new resource)
resource = Halibut::Core::Resource.new
resource.set_property :name,   'Halibut Rules'
resource.set_property :winner, 'Tiger Blood'

# Resource with a self link
resource = Halibut::Core::Resource.new


40
41
42
43
44
45
46
47
48
# File 'lib/halibut/core/resource.rb', line 40

def initialize(href=nil, properties={}, links={}, embedded={})
  @namespaces      = RelationMap.new
  @links           = RelationMap.new
  @embedded        = RelationMap.new
  @embedded_arrays = RelationMap.new(single_item_arrays: true)
  @properties = {}

  add_link('self', href) if href
end

Instance Attribute Details

#embeddedObject (readonly)

A collection of embedded resources, grouped by relation.



18
19
20
# File 'lib/halibut/core/resource.rb', line 18

def embedded
  @embedded
end

A collection of links, grouped by relation



15
16
17
# File 'lib/halibut/core/resource.rb', line 15

def links
  @links
end

#namespace(name) ⇒ Object (readonly) Also known as: ns

A collection of namespaces defined in the document



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

def namespace
  @namespace
end

#propertiesObject (readonly)

All the properties set in this resource



12
13
14
# File 'lib/halibut/core/resource.rb', line 12

def properties
  @properties
end

Instance Method Details

#==(other) ⇒ true, false

Compares two resources.



165
166
167
168
169
# File 'lib/halibut/core/resource.rb', line 165

def ==(other)
  @properties == other.properties &&
  @links      == other.links      &&
  @embedded   == other.embedded
end

#[]=(property, value) ⇒ Object



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

def []=(property, value)
  tap { @properties[property] = value }
end

#add_embedded_resource(relation, resource) ⇒ Object

Embeds resource in a relation array

To embed a single object, see #embed_resource.



142
143
144
# File 'lib/halibut/core/resource.rb', line 142

def add_embedded_resource(relation, resource)
  @embedded_arrays.add relation, resource
end

Adds link to relation.

resource = Halibut::Core::Resource.new
resource.add_link 'next', '/resource/2', name: 'Foo'
link = resource.links['next'].first
link.href
# => "/resource/2"
link.name
# => "Foo"


121
122
123
# File 'lib/halibut/core/resource.rb', line 121

def add_link(relation, href, opts={})
  @links.add relation, Link.new(href, opts)
end

#add_namespace(name, href) ⇒ Object

Adds a namespace to the resource.



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

def add_namespace(name, href)
  add_link 'curie', href, templated: true, name: name
end

#embed_resource(relation, resource) ⇒ Object

Embeds resource in relation

To embed many resources, call #add_embedded_resource with each item



131
132
133
134
# File 'lib/halibut/core/resource.rb', line 131

def embed_resource(relation, resource)
  warn 'Calling Halibut::Core::Resource#embed_resource for populating an array is deprecated. Use Halibut::Core::Resource#add_embeded_resource instead.' if @embedded[relation]
  @embedded.add relation, resource
end

#hrefString?

Returns the self link of the resource.



53
54
55
# File 'lib/halibut/core/resource.rb', line 53

def href
  @links.fetch('self', []).map(&:href).first
end

#namespacesObject



62
63
64
# File 'lib/halibut/core/resource.rb', line 62

def namespaces
  @links['curie']
end

#property(property) ⇒ Object

Returns the value of a property in the resource

resource = Halibut::Core::Resource.new
resource.set_property :name, 'FooBar'
resource.property :name
# => "FooBar"


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

def property(property)
  @properties.fetch(property, nil)
end

#set_property(property, value) ⇒ Object

Sets a property in the resource.

resource = Halibut::Core::Resource.new
resource.set_property :name, 'FooBar'
resource.property :name
# => "FooBar"


75
76
77
78
79
80
81
# File 'lib/halibut/core/resource.rb', line 75

def set_property(property, value)
  if property == '_links' || property == '_embedded'
    raise ArgumentError, "Argument #{property} is a reserved property"
  end

  tap { @properties[property] = value }
end

#to_hashHash

Hash representation of the resource. Will ommit links and embedded keys if they’re empty



150
151
152
153
154
155
156
157
158
159
# File 'lib/halibut/core/resource.rb', line 150

def to_hash
  {}.merge(@properties).tap do |h|
    h['_links'] = {}.merge @links    unless @links.empty?

    combined_embedded = {}
    combined_embedded.merge! @embedded unless @embedded.empty?
    combined_embedded.merge! @embedded_arrays unless @embedded_arrays.empty?
    h['_embedded'] = combined_embedded unless combined_embedded.empty?
  end
end