Module: HalInterpretation::Dsl

Defined in:
lib/hal_interpretation/dsl.rb

Instance Method Summary collapse

Instance Method Details

#extract(attr_name, opts = {}) ⇒ Object

Declare that an attribute should be extract from the HAL document.

attr_name - name of attribute on model to extract

opts - hash of named arguments to method

:from - JSON path from which to get the value for
  attribute. Default: "/#{attr_name}".

:with - Callable that can extract the value when
  passed a HalClient::Representation of the item.

:coercion - callable with which the raw value should be
  transformed before being stored.


25
26
27
28
29
30
31
32
33
34
# File 'lib/hal_interpretation/dsl.rb', line 25

def extract(attr_name, opts={})
  extractor_opts = {
    attr: attr_name,
    location: opts.fetch(:from) { "/#{attr_name}" }
  }
  extractor_opts[:extraction_proc] = opts.fetch(:with) if opts[:with]
  extractor_opts[:coercion] = opts[:coercion] if opts[:coercion]

  extractors << Extractor.new(extractor_opts)
end

Declare that an attribute should be extracted the HAL document’s links (or embeddeds) where only one instance of that link type is legal.

attr_name - name of the attribute on the model to extract

opts - hash of named arguments

:rel - rel of link to extract. Default: attr_name

:coercion - callable with which the raw URL should transformed
before being stored in the model

Examples

extract_link :author_website,
             rel: "http://xmlns.com/foaf/0.1/homepage"

extracts the target of the ‘…/homepage` link and stores in the `author_website` attribute of the model.

extract_link :parent, rel: "up",
              coercion: ->(url) {
                Blog.find id_from_url(u)
              }

looks up the blog pointed to by the ‘up` link and stores that model instance in the `parent` association of the model we are interpreting.



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hal_interpretation/dsl.rb', line 65

def extract_link(attr_name, opts={})
  orig_coercion = opts[:coercion] || IDENTITY
  adjusted_opts = opts.merge coercion: ->(urls) {
    fail "Too many instances (expected exactly 1, found #{urls.count})" if
      urls.count > 1

    instance_exec urls.first, &orig_coercion
  }

  extract_links attr_name, adjusted_opts
end

Declare that an attribute should be extracted the HAL document’s links (or embeddeds).

attr_name - name of the attribute on the model to extract

opts - hash of named arguments

:rel - rel of link to extract. Default: attr_name

:coercion - callable with which the raw URL should transformed
before being stored in the model

Examples

extract_links :author_websites,
              rel: "http://xmlns.com/foaf/0.1/homepage"

extracts the targets of the ‘…/homepage` link and stores in the `author_websites` attribute of the model.

extract_links :parents, rel: "up",
              coercion: ->(urls) {
                urls.map { |u| Blog.find id_from_url(u) }
              }

looks up the blogs pointed to by the ‘up` links and stores that collection of model instances in the `parents` association of the model we are interpreting.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/hal_interpretation/dsl.rb', line 105

def extract_links(attr_name, opts={})
  rel = opts.fetch(:rel) { attr_name }.to_s
  path = "/_links/" + json_path_escape(rel)

  stringify_href = ->(string_or_uri_tmpl) {
    if string_or_uri_tmpl.respond_to? :pattern
      string_or_uri_tmpl.pattern
    else
      string_or_uri_tmpl.to_str
    end
  }

  extract attr_name, from: path,
          with: ->(r){ r.raw_related_hrefs(rel){[]}.map &stringify_href },
          coercion: opts[:coercion]
end

Declare that an attribute should be extracted from the HAL document’s links (or embeddeds) as a representation.

attr_name - name of the attribute on the model to extract to as a representation

opts - hash of named arguments

:rel - rel of link to extract. Default: attr_name

:coercion - callable with which the raw URL should transformed
before being stored in the model

Examples

extract_related :author,
              rel: "http://xmlns.com/foaf/0.1/Person"

extracts the targets of the ‘…/Person` link and stores the corresponding HAL representation object in the `author` attribute of the model.

extract_related :author, rel: "http://xmlns.com/foaf/0.1/Person",
              coercion: ->(person_repr) {
                MyInterpretation.new(person_repr)
              }

looks up the author pointed to by the rel and uses coercion to initialize a custom object stored on the model that uses the representation



152
153
154
# File 'lib/hal_interpretation/dsl.rb', line 152

def extract_related(attr_name, opts={})
  extract_related_with_blk(attr_name, opts) {|r, rel| r.related(rel){[]}.first }
end

#extract_relateds(attr_name, opts = {}) ⇒ Object

Declare that an attribute should be extracted from the HAL document’s links (or embeddeds) as a representation set.

attr_name - name of the attribute on the model to extract to as a representation set

opts - hash of named arguments

:rel - rel of link to extract. Default: attr_name

:coercion - callable with which the raw URL should transformed
before being stored in the model

Examples

extract_relateds :authors,
               rel: "http://exampe.com/authors"

extracts the targets of the ‘…/authors` link and stores the corresponding HAL representation set object in the `authors` attribute of the model.

extract_relateds :authors, rel: "http://example.com/authors",
  coercion: ->(person_repr_set) {
    person_repr_set.map {|repr| MyInterpretation.new(repr)}
  }

looks up the authors pointed to by the rel and uses coercion to initialize an array of custom objects stored on the model that uses the representation set



186
187
188
# File 'lib/hal_interpretation/dsl.rb', line 186

def extract_relateds(attr_name, opts={})
  extract_related_with_blk(attr_name, opts) {|r, rel| r.related(rel){[]} }
end

#item_class(klass) ⇒ Object

Declare the class of models this interpreter builds.



4
5
6
7
8
# File 'lib/hal_interpretation/dsl.rb', line 4

def item_class(klass)
  define_method(:item_class) do
    klass
  end
end