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

Parameters:

  • href (String) (defaults to: nil)

    Link that will be added to the self relation.



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.

Parameters:

Returns:

  • (true, false)

    Result of the comparison



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.

Parameters:

  • relation (String)

    relation

  • resource (Resource)

    resource to embed



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"

Parameters:

  • relation (String)

    relation

  • href (String)

    href

  • opts (Hash) (defaults to: {})

    options: templated, type, name, profile, title, hreflang



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.

Parameters:

  • name (String)

    The name of the namespace

  • href (String)

    The templated URI of the namespace



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

Parameters:

  • relation (String)

    relation

  • resource (Resource)

    resource to embed



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.

Returns:

  • (String, nil)

    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"

Parameters:

  • property (String)

    property



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"

Parameters:

  • property (Object)

    the key

  • value (Object)

    the value



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

Returns:

  • (Hash)

    hash representation of the resource



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