-
Notifications
You must be signed in to change notification settings - Fork 1
/
simple.rb
executable file
·140 lines (123 loc) · 3.21 KB
/
simple.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
$LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
require 'halogen'
require 'pp'
# Example of a straightforward Halogen representer with no resource,
# collection, or conditional definitions
#
class GoatRepresenter
include Halogen
# Simple instance methods that will be used for properties below
#
def id; 1; end
def first_name; 'Gideon'; end
def last_name; 'Goat'; end
# == 1. Properties
#
# If you define a property without an explicit value or proc, Halogen will
# look for a public instance method with the corresponding name.
#
# This will call GoatRepresenter#id.
#
property :id # => { id: 1 }
# You can also define a property with an explicit value, e.g.:
#
property :age, value: 9.2 # => { age: 9.2 }
# Or you can use a proc to determine the property value at render time.
#
# The example below could also be written: property(:full_name) { ... }
#
property :full_name do # => { full_name: 'Gideon Goat' }
"#{first_name} #{last_name}"
end
# == 2. Links
#
# As with properties, links can be defined with a proc:
#
link :self do
"/goats/#{id}" # => { self: { href: '/goats/1' } }
end
# ...Or with an explicit value:
#
link :root, value: '/goats' # => { root: { href: '/goats' } }
# Links can also be defined as "templated", following HAL+JSON conventions:
#
link :find, :templated do # => ... { href: '/goats/{?id}', templated: true }
'/goats/{?id}'
end
# If Halogen is loaded in a Rails application, url helpers will be available
# automatically:
#
# link(:new) { new_goat_path }
# == 3. Embeds
#
# Embedded resources are not rendered by default. They will be included if
# both of the following conditions are met:
#
# 1. The proc returns either a Halogen instance or an array of Halogen instances
# 2. The embed is requested via the parent representer's options, e.g.:
#
# GoatRepresenter.new(embed: { kids: true, parents: false })
#
embed :kids do # => { kids: <GoatKidsRepresenter#render> }
GoatKidsRepresenter.new
end
embed :parents do # => will not be included according to example options above
[
self.class.new,
self.class.new
]
end
# Embedded resources can be nested to any depth, e.g.:
#
# GoatRepresenter.new(embed: {
# kids: {
# foods: {
# ingredients: true
# },
# enclosure: true
# }
# })
end
# Another simple representer to demonstrate embedded resources above
#
class GoatKidsRepresenter
include Halogen
property :count, value: 5
end
puts 'GoatRepresenter.new(embed: { kids: true }).render:'
puts
pp GoatRepresenter.new(embed: { kids: true }).render
#
# Result:
#
# {
# id: 1,
# age: 9.2,
# full_name: "Gideon Goat",
# _embedded: {
# kids: { count: 5 }
# },
# _links: {
# self: { href: '/goats/1' },
# root: { href: '/goats"'},
# find: { href: '/goats/{?id}', templated: true }
# }
# }
#
puts
puts 'GoatRepresenter.new.render:'
puts
pp GoatRepresenter.new.render
#
# Result:
#
# {
# id: 1,
# age: 9.2,
# full_name: "Gideon Goat",
# _links: {
# self: { href: '/goats/1' },
# root: { href: '/goats"'},
# find: { href: '/goats/{?id}', templated: true }
# }
# }