Class: Jsonite

Inherits:
Object
  • Object
show all
Defined in:
lib/jsonite.rb,
lib/jsonite/helper.rb,
lib/jsonite/version.rb

Overview

Jsonite

A tiny, HAL-compliant JSON presenter.

tools.ietf.org/html/draft-kelly-json-hal-05

Defined Under Namespace

Modules: Helper

Constant Summary collapse

VERSION =
'0.0.2'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource, defaults = {}) ⇒ Jsonite

Initializes a new presenter instance with the given resource.

Default options are passed to #as_json during presentation.



176
177
178
# File 'lib/jsonite.rb', line 176

def initialize resource, defaults = {}
  @resource, @defaults = resource, defaults
end

Instance Attribute Details

#defaultsObject (readonly)

Returns the value of attribute defaults.



171
172
173
# File 'lib/jsonite.rb', line 171

def defaults
  @defaults
end

#resourceObject (readonly)

Returns the value of attribute resource.



171
172
173
# File 'lib/jsonite.rb', line 171

def resource
  @resource
end

Class Method Details

.embed(rel, options = {}, &handler) ⇒ Object

Defines an embedded resource.

class TodoPresenter < Jsonite
  property :description
end
class UserPresenter < Jsonite
  embed :todos, with: TodoPresenter
end
# {
#   "_embedded": {
#     "todos": [
#       {
#         "description": "Buy milk"
#       }
#     ]
#   }
# }

Configuration options:

  • :with - A specified presenter. Required if a handler isn’t present.



146
147
148
149
150
151
152
153
154
155
# File 'lib/jsonite.rb', line 146

def embed rel, options = {}, &handler
  if handler.nil?
    presenter = options.fetch :with
    handler = proc do |context|
      Jsonite.present send(rel), with: presenter, context: context
    end
  end

  embedded[rel] = handler
end

.embeddedObject



157
158
159
# File 'lib/jsonite.rb', line 157

def embedded
  @embedded ||= {}
end

Defines a link.

class UserPresenter < Jsonite
  link do |context|
    context.user_url self
  end
  link :todos do |context|
    context.user_todos_url self
  end
end
# {
#   "_links": {
#     "self": {
#       "href": "http://example.com/users/8oljbpyjetu8"
#     },
#     "todos": {
#       "href": "http://example.com/users/8oljbpyjetu8/todos"
#     }
#   }
# }

Configuration options are displayed as additional properties on a link.

class UserPresenter < Jsonite
  link :todos, title: 'To-dos', templated: true do |context|
    "#{context.user_todos_url self}{?done}
  end
end
# {
#   "_links": {
#     "todos": {
#       "href": "http://example.com/users/8oljbpyjetu8/todos{?done}",
#       "title": "To-dos",
#       "templated": true
#     }
#   }
# }


117
118
119
# File 'lib/jsonite.rb', line 117

def link rel = :self, options = {}, &handler
  links[rel] = options.merge handler: Proc.new # enforce handler presence
end


121
122
123
# File 'lib/jsonite.rb', line 121

def links
  @links ||= {}
end

.present(resource, options = {}) ⇒ Object

Presents a resource (or array of resources).

class UserPresenter < Jsonite
  property :email
end
users = User.all
UserPresenter.present(users.first)
# => {"email"=>"[email protected]"}
UserPresenter.present(users)
# => [{"email"=>"[email protected]"}, ...]

Configuration options:

  • :with - A specified presenter (defaults to ‘self`).

All other options are passed along to #as_json.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/jsonite.rb', line 29

def present resource, options = {}
  presenter = options.delete(:with) { self }

  case resource
  when Jsonite
    resource.as_json options
  else
    resource = if resource.respond_to?(:to_ary)
      resource.to_ary.map do |r|
        present presenter.new(r), options.merge(root: nil)
      end
    elsif resource.respond_to?(:as_json)
      present presenter.new(resource), options.merge(root: nil)
    else
      resource
    end

    root = options.fetch :root, Helper.resource_name(resource)
    root ? { root => resource } : resource
  end
end

.properties(*properties) ⇒ Object



74
75
76
77
78
# File 'lib/jsonite.rb', line 74

def properties *properties
  @properties ||= {}
  properties.map(&method(:property)) if properties.present?
  @properties
end

.property(name, options = {}, &handler) ⇒ Object

Defines a property to be exposed during presentation.

class UserPresenter < Jsonite
  property :email
end
# {
#   "email": "[email protected]"
# }

Configuration options:

  • :with - A specified presenter. Ignored when a handler is present. Useful when you want to embed a resource as a property (rather than in the _embedded node).



64
65
66
67
68
69
70
71
72
# File 'lib/jsonite.rb', line 64

def property name, options = {}, &handler
  handler ||= if options[:with]
    proc { Jsonite.present send(name), with: options[:with] }
  else
    proc { send name }
  end

  properties[name] = handler
end

Instance Method Details

#as_json(options = {}) ⇒ Object

Returns a JSON representation (Hash) of the resource.

Options:

  • :context - A context to pass a presenter instance while rendering properties, links, and embedded resources.



185
186
187
188
189
190
191
192
193
# File 'lib/jsonite.rb', line 185

def as_json options = {}
  return resource.as_json options if instance_of? Jsonite
  options = defaults.merge options
  context = options.delete :context
  hash = properties context
  hash.update _links: links(context) if self.class.links.present?
  hash.update _embedded: embedded(context) if self.class.embedded.present?
  hash.as_json options
end