collection-json 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +60 -14
- data/lib/collection-json.rb +4 -5
- data/lib/collection-json/attribute.rb +62 -0
- data/lib/collection-json/attributes/collection.rb +25 -0
- data/lib/collection-json/attributes/data.rb +6 -13
- data/lib/collection-json/attributes/error.rb +6 -13
- data/lib/collection-json/attributes/item.rb +10 -24
- data/lib/collection-json/attributes/link.rb +8 -19
- data/lib/collection-json/attributes/query.rb +7 -24
- data/lib/collection-json/attributes/template.rb +10 -17
- data/lib/collection-json/builder.rb +39 -50
- data/lib/collection-json/transformers/uri.rb +11 -0
- data/lib/collection-json/version.rb +1 -1
- data/spec/collection-json/attributes/collection_spec.rb +15 -0
- data/spec/collection-json/attributes/item_spec.rb +13 -0
- data/spec/collection-json/attributes/template_spec.rb +1 -0
- data/spec/collection-json_spec.rb +9 -9
- metadata +11 -5
- data/lib/collection-json/collection.rb +0 -72
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# CollectionJSON
|
2
2
|
|
3
|
-
A lightweight gem to easily build response objects with a MIME type of
|
3
|
+
A lightweight gem to easily build and parse response objects with a MIME type of
|
4
4
|
'application/vnd.collection+json'.
|
5
5
|
|
6
6
|
Read http://amundsen.com/media-types/collection/ for more information about this
|
@@ -8,35 +8,37 @@ media type.
|
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
+
### Building
|
12
|
+
|
11
13
|
Use ```CollectionJSON.generate_for``` to build a response object which you can
|
12
14
|
call ```to_json``` on.
|
13
15
|
|
14
16
|
```ruby
|
15
|
-
|
17
|
+
collection = CollectionJSON.generate_for('/friends/') do |builder|
|
16
18
|
builder.add_link '/friends/rss', 'feed'
|
17
19
|
user.friends.each do |friend|
|
18
20
|
builder.add_item("/friends/#{friend.id}") do |item|
|
19
|
-
item.add_data "full-name", friend.full_name
|
20
|
-
item.add_data "email", friend.email
|
21
|
-
item.add_link "/blogs/#{friend.id}", "blog", ""
|
22
|
-
item.add_link "/blogs/#{friend.id}", "avatar", ""
|
21
|
+
item.add_data "full-name", {"value" => friend.full_name}
|
22
|
+
item.add_data "email", {"value" => friend.email}
|
23
|
+
item.add_link "/blogs/#{friend.id}", "blog", {"prompt" => "Blog"}
|
24
|
+
item.add_link "/blogs/#{friend.id}", "avatar", {"prompt" => "Avatar", "render" => "image"}
|
23
25
|
end
|
24
26
|
end
|
25
|
-
builder.add_query("/friends/search", "search", "Search") do |query|
|
27
|
+
builder.add_query("/friends/search", "search", {"prompt" => "Search"}) do |query|
|
26
28
|
query.add_data "search"
|
27
29
|
end
|
28
30
|
builder.set_template do |template|
|
29
|
-
template.add_data "full-name", ""
|
30
|
-
template.add_data "email", ""
|
31
|
-
template.add_data "blog", ""
|
32
|
-
template.add_data "avatar", ""
|
31
|
+
template.add_data "full-name", {"prompt" => "Full Name"}
|
32
|
+
template.add_data "email", {"prompt" => "Email"}
|
33
|
+
template.add_data "blog", {"prompt" => "Blog"}
|
34
|
+
template.add_data "avatar", {"prompt" => "Avatar"}
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
|
-
|
38
|
+
collection.to_json
|
37
39
|
```
|
38
40
|
|
39
|
-
|
41
|
+
Output:
|
40
42
|
|
41
43
|
```javascript
|
42
44
|
{ "collection" :
|
@@ -98,7 +100,7 @@ Sample output:
|
|
98
100
|
"queries" : [
|
99
101
|
{"rel" : "search", "href" : "http://example.org/friends/search", "prompt" : "Search",
|
100
102
|
"data" : [
|
101
|
-
{"name" : "
|
103
|
+
{"name" : "q", "prompt" : "Search Query"}
|
102
104
|
]
|
103
105
|
}
|
104
106
|
],
|
@@ -116,6 +118,50 @@ Sample output:
|
|
116
118
|
}
|
117
119
|
```
|
118
120
|
|
121
|
+
### Parsing
|
122
|
+
|
123
|
+
CollectionJSON also helps you to consume APIs by parsing JSON strings:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
collection = CollectionJSON.parse(json)
|
127
|
+
collection.href # => "http://example.org/friends/"
|
128
|
+
collection.items.count # => 3
|
129
|
+
```
|
130
|
+
|
131
|
+
You can then build queries:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
collection.queries.first.build({'search' => 'puppies'}) # => "http://example.org/friends/search?q=puppies"
|
135
|
+
```
|
136
|
+
|
137
|
+
It also builds templates:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
built_template = collection.template.build({"full-name" => "Lol Cat", "email" => "lol@cats.com"})
|
141
|
+
built_template.to_json
|
142
|
+
```
|
143
|
+
|
144
|
+
Output:
|
145
|
+
|
146
|
+
```javascript
|
147
|
+
{
|
148
|
+
"template" : {
|
149
|
+
"data" : [
|
150
|
+
{
|
151
|
+
"name" : "full-name",
|
152
|
+
"value" : "Lol Cat"
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"name" : "email",
|
156
|
+
"value" : "lol@cats.com"
|
157
|
+
}
|
158
|
+
]
|
159
|
+
}
|
160
|
+
}
|
161
|
+
```
|
162
|
+
|
163
|
+
## Notes
|
164
|
+
|
119
165
|
Set the ```COLLECTION_JSON_HOST``` environment variable to automatically add
|
120
166
|
this to the href's. Eg. ```COLLECTION_JSON_HOST=http://example.org```
|
121
167
|
|
data/lib/collection-json.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'json'
|
2
2
|
require "collection-json/version"
|
3
|
-
require "collection-json/collection"
|
3
|
+
require "collection-json/attributes/collection"
|
4
4
|
require "collection-json/builder"
|
5
5
|
|
6
6
|
COLLECTION_JSON_VERSION = "1.0"
|
7
7
|
ROOT_NODE = 'collection'
|
8
8
|
|
9
|
-
VALID_LINK_ATTRIBUTES = %w{href rel name render prompt}.map(&:to_sym)
|
10
|
-
|
11
9
|
module CollectionJSON
|
12
10
|
def self.generate_for(href, &block)
|
13
|
-
response = Collection.new
|
11
|
+
response = Collection.new
|
12
|
+
response.href href
|
14
13
|
if block_given?
|
15
14
|
builder = Builder.new(response)
|
16
15
|
yield(builder)
|
@@ -29,6 +28,6 @@ module CollectionJSON
|
|
29
28
|
|
30
29
|
def self.parse(json)
|
31
30
|
hash = JSON.parse(json)
|
32
|
-
collection = Collection.from_hash(hash)
|
31
|
+
collection = Collection.from_hash(hash[ROOT_NODE])
|
33
32
|
end
|
34
33
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
Dir[File.dirname(__FILE__) + "/transformers/*.rb"].each do |file|
|
4
|
+
require file
|
5
|
+
end
|
6
|
+
|
7
|
+
module CollectionJSON
|
8
|
+
class Attribute
|
9
|
+
def self.nested_attributes
|
10
|
+
@nested_attributes ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.attribute(name, opts={})
|
14
|
+
nested_attributes << name
|
15
|
+
define_method(name) do |arg=nil|
|
16
|
+
if arg
|
17
|
+
if opts[:transform]
|
18
|
+
instance_variable_set(:"@#{name}", opts[:transform].call(arg))
|
19
|
+
else
|
20
|
+
instance_variable_set(:"@#{name}", arg)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
unless instance_variable_get(:"@#{name}").nil?
|
24
|
+
instance_variable_get(:"@#{name}")
|
25
|
+
else
|
26
|
+
opts[:default]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.root_node(value = nil)
|
33
|
+
@root_node = value.to_s if value
|
34
|
+
@root_node
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.from_hash(hash)
|
38
|
+
self.new.tap do |item|
|
39
|
+
hash.each { |k,v| item.send(k, v) if item.respond_to?(k) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_hash
|
44
|
+
hash = Hash.new.tap do |item|
|
45
|
+
self.class.nested_attributes.each do |attribute|
|
46
|
+
value = send(attribute)
|
47
|
+
item[attribute] = value unless skip_value?(value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
self.class.root_node ? {self.class.root_node => hash} : hash
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_json(*args)
|
54
|
+
to_hash.to_json(args)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def skip_value?(value)
|
59
|
+
value.nil? || value.respond_to?(:length) && value.length == 0
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../attribute'
|
2
|
+
require_relative 'link'
|
3
|
+
require_relative 'item'
|
4
|
+
require_relative 'query'
|
5
|
+
require_relative 'error'
|
6
|
+
require_relative 'template'
|
7
|
+
|
8
|
+
module CollectionJSON
|
9
|
+
class Collection < Attribute
|
10
|
+
root_node :collection
|
11
|
+
attribute :href, transform: URI
|
12
|
+
attribute :version
|
13
|
+
attribute :links,
|
14
|
+
transform: lambda { |links| links.each.map { |l| Link.from_hash(l) }},
|
15
|
+
default: []
|
16
|
+
attribute :items,
|
17
|
+
transform: lambda { |items| items.each.map { |i| Item.from_hash(i) }},
|
18
|
+
default: []
|
19
|
+
attribute :queries,
|
20
|
+
transform: lambda { |queries| queries.each.map { |q| Query.from_hash(q) }},
|
21
|
+
default: []
|
22
|
+
attribute :template, transform: lambda { |template| Template.from_hash(template) }
|
23
|
+
attribute :error, transform: lambda { |template| Error.from_hash(template) }
|
24
|
+
end
|
25
|
+
end
|
@@ -1,16 +1,9 @@
|
|
1
|
-
|
2
|
-
class Data < Hash
|
3
|
-
def self.from_hash(hash)
|
4
|
-
self.new.merge! hash
|
5
|
-
end
|
6
|
-
|
7
|
-
def name; self['name']; end
|
8
|
-
def name=(value); self['name'] = value; end
|
1
|
+
require_relative '../attribute'
|
9
2
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
module CollectionJSON
|
4
|
+
class Data < Attribute
|
5
|
+
attribute :name
|
6
|
+
attribute :value
|
7
|
+
attribute :prompt
|
15
8
|
end
|
16
9
|
end
|
@@ -1,16 +1,9 @@
|
|
1
|
-
|
2
|
-
class Error < Hash
|
3
|
-
def self.from_hash(hash)
|
4
|
-
self.new.merge! hash
|
5
|
-
end
|
6
|
-
|
7
|
-
def title; self['title']; end
|
8
|
-
def title=(value); self['title'] = value; end
|
1
|
+
require_relative '../attribute'
|
9
2
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
module CollectionJSON
|
4
|
+
class Error < Attribute
|
5
|
+
attribute :title
|
6
|
+
attribute :code
|
7
|
+
attribute :message
|
15
8
|
end
|
16
9
|
end
|
@@ -1,29 +1,15 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../attribute'
|
2
2
|
require_relative 'data'
|
3
|
+
require_relative 'link'
|
3
4
|
|
4
5
|
module CollectionJSON
|
5
|
-
class Item <
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def links
|
14
|
-
self['links'].map {|link| Link.from_hash(link)}
|
15
|
-
end
|
16
|
-
|
17
|
-
def links=(array)
|
18
|
-
self['links'] = array
|
19
|
-
end
|
20
|
-
|
21
|
-
def data
|
22
|
-
self['data'].map {|data| Data.from_hash(data)}
|
23
|
-
end
|
24
|
-
|
25
|
-
def data=(array)
|
26
|
-
self['data'] = array
|
27
|
-
end
|
6
|
+
class Item < Attribute
|
7
|
+
attribute :href, transform: URI
|
8
|
+
attribute :data,
|
9
|
+
transform: lambda { |data| data.each.map { |d| Data.from_hash(d) }},
|
10
|
+
default: []
|
11
|
+
attribute :links,
|
12
|
+
transform: lambda { |links| links.each.map { |l| Link.from_hash(l) }},
|
13
|
+
default: []
|
28
14
|
end
|
29
15
|
end
|
@@ -1,22 +1,11 @@
|
|
1
|
-
|
2
|
-
class Link < Hash
|
3
|
-
def self.from_hash(hash)
|
4
|
-
self.new.merge! hash
|
5
|
-
end
|
6
|
-
|
7
|
-
def href; self['href']; end
|
8
|
-
def href=(value); self['href'] = value; end
|
9
|
-
|
10
|
-
def rel; self['rel']; end
|
11
|
-
def rel=(value); self['rel'] = value; end
|
1
|
+
require_relative '../attribute'
|
12
2
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def prompt=(value); self['prompt'] = value; end
|
3
|
+
module CollectionJSON
|
4
|
+
class Link < Attribute
|
5
|
+
attribute :href, transform: URI
|
6
|
+
attribute :rel
|
7
|
+
attribute :name
|
8
|
+
attribute :render
|
9
|
+
attribute :prompt
|
21
10
|
end
|
22
11
|
end
|
@@ -1,30 +1,13 @@
|
|
1
|
+
require_relative '../attribute'
|
1
2
|
require_relative 'data'
|
2
3
|
|
3
4
|
module CollectionJSON
|
4
|
-
class Query <
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def href=(value); self['href'] = value; end
|
11
|
-
|
12
|
-
def rel; self['rel']; end
|
13
|
-
def rel=(value); self['rel'] = value; end
|
14
|
-
|
15
|
-
def name; self['name']; end
|
16
|
-
def name=(value); self['name'] = value; end
|
17
|
-
|
18
|
-
def prompt; self['prompt']; end
|
19
|
-
def prompt=(value); self['prompt'] = value; end
|
20
|
-
|
21
|
-
def data
|
22
|
-
self['data'].map {|data| Data.from_hash(data)}
|
23
|
-
end
|
24
|
-
|
25
|
-
def data=(array)
|
26
|
-
self['data'] = array
|
27
|
-
end
|
5
|
+
class Query < Attribute
|
6
|
+
attribute :href, transform: URI
|
7
|
+
attribute :rel
|
8
|
+
attribute :data,
|
9
|
+
transform: lambda { |data| data.each.map { |d| Data.from_hash(d) }},
|
10
|
+
default: []
|
28
11
|
|
29
12
|
def build(params = {})
|
30
13
|
URI(href).tap do |uri|
|
@@ -1,26 +1,19 @@
|
|
1
1
|
require_relative 'data'
|
2
2
|
|
3
3
|
module CollectionJSON
|
4
|
-
class Template <
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def data
|
10
|
-
self['data'].map {|data| Data.from_hash(data)}
|
11
|
-
end
|
12
|
-
|
13
|
-
def data=(array)
|
14
|
-
self['data'] = array
|
15
|
-
end
|
4
|
+
class Template < Attribute
|
5
|
+
attribute :data,
|
6
|
+
transform: lambda { |data| data.each.map { |d| Data.from_hash(d) }},
|
7
|
+
default: []
|
16
8
|
|
17
9
|
def build(params = {})
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
{'template' => Hash.new}.tap do |hash|
|
11
|
+
hash['template']['data'] = data.inject([]) do |array,data|
|
12
|
+
result = {'name' => data.name, 'value' => data.value}
|
13
|
+
result['value'] = params[data.name] if params[data.name]
|
14
|
+
result['value'].nil? ? array : array << result
|
15
|
+
end
|
22
16
|
end
|
23
|
-
{ 'template' => { 'data' => data } }
|
24
17
|
end
|
25
18
|
end
|
26
19
|
end
|
@@ -6,48 +6,47 @@ module CollectionJSON
|
|
6
6
|
@collection = collection
|
7
7
|
end
|
8
8
|
|
9
|
-
def set_error(
|
10
|
-
collection.error =
|
9
|
+
def set_error(params = {})
|
10
|
+
collection.error = params
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
13
|
+
def add_link(href, rel, params = {})
|
14
|
+
params.merge!({'rel' => rel, 'href' => href})
|
15
|
+
collection.links << Link.from_hash(params)
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
-
href
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
item_builder = ItemBuilder.new(data, links)
|
29
|
-
yield(item_builder) if block_given?
|
30
|
-
item.merge!({'data' => item_builder.data}) if item_builder.data.length > 0
|
31
|
-
item.merge!({'links' => item_builder.links}) if item_builder.links.length > 0
|
18
|
+
def add_item(href, params = {}, &block)
|
19
|
+
params.merge!({'href' => href})
|
20
|
+
collection.items << Item.from_hash(params).tap do |item|
|
21
|
+
if block_given?
|
22
|
+
data = []
|
23
|
+
links = []
|
24
|
+
item_builder = ItemBuilder.new(data, links)
|
25
|
+
yield(item_builder)
|
26
|
+
item.data data
|
27
|
+
item.links links
|
28
|
+
end
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
35
|
-
def add_query(href, rel,
|
36
|
-
href
|
37
|
-
collection.queries << Query.from_hash(
|
32
|
+
def add_query(href, rel, params = {}, &block)
|
33
|
+
params.merge!({'href' => href, 'rel' => rel})
|
34
|
+
collection.queries << Query.from_hash(params).tap do |query|
|
35
|
+
data = []
|
38
36
|
query_builder = QueryBuilder.new(data)
|
39
37
|
yield(query_builder) if block_given?
|
40
|
-
query.
|
41
|
-
query.merge!({'data' => query_builder.data}) if query_builder.data.length > 0
|
38
|
+
query.data data
|
42
39
|
end
|
43
40
|
end
|
44
41
|
|
45
|
-
def set_template(
|
46
|
-
|
42
|
+
def set_template(params = {}, &block)
|
43
|
+
if block_given?
|
44
|
+
data = params['data'] || []
|
47
45
|
template_builder = TemplateBuilder.new(data)
|
48
|
-
yield(template_builder)
|
49
|
-
|
46
|
+
yield(template_builder)
|
47
|
+
params.merge!({'data' => data})
|
50
48
|
end
|
49
|
+
collection.template params
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
@@ -59,20 +58,14 @@ module CollectionJSON
|
|
59
58
|
@links = links
|
60
59
|
end
|
61
60
|
|
62
|
-
def add_data(name,
|
63
|
-
|
64
|
-
|
65
|
-
data.merge!({'prompt' => prompt}) if prompt != ''
|
66
|
-
end
|
61
|
+
def add_data(name, params = {})
|
62
|
+
params.merge!({'name' => name})
|
63
|
+
data << params
|
67
64
|
end
|
68
65
|
|
69
|
-
def add_link(href, rel,
|
70
|
-
href
|
71
|
-
links <<
|
72
|
-
link.merge!({'name' => name}) if name != ''
|
73
|
-
link.merge!({'prompt' => prompt}) if prompt != ''
|
74
|
-
link.merge!({'render' => render}) if render != ''
|
75
|
-
end
|
66
|
+
def add_link(href, rel, params = {})
|
67
|
+
params.merge!({'rel' => rel, 'href' => href})
|
68
|
+
links << params
|
76
69
|
end
|
77
70
|
end
|
78
71
|
|
@@ -83,11 +76,9 @@ module CollectionJSON
|
|
83
76
|
@data = data
|
84
77
|
end
|
85
78
|
|
86
|
-
def add_data(name,
|
87
|
-
|
88
|
-
|
89
|
-
data.merge!({'prompt' => prompt}) if prompt != ''
|
90
|
-
end
|
79
|
+
def add_data(name, params = {})
|
80
|
+
params.merge!({'name' => name})
|
81
|
+
data << params
|
91
82
|
end
|
92
83
|
end
|
93
84
|
|
@@ -98,11 +89,9 @@ module CollectionJSON
|
|
98
89
|
@data = data
|
99
90
|
end
|
100
91
|
|
101
|
-
def add_data(name,
|
102
|
-
|
103
|
-
|
104
|
-
data.merge!({'prompt' => prompt}) if prompt != ''
|
105
|
-
end
|
92
|
+
def add_data(name, params = {})
|
93
|
+
params.merge!({'name' => name})
|
94
|
+
data << params
|
106
95
|
end
|
107
96
|
end
|
108
97
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'collection-json/attributes/collection'
|
3
|
+
|
4
|
+
describe CollectionJSON::Collection do
|
5
|
+
it 'be serializable' do
|
6
|
+
collection = CollectionJSON::Collection.from_hash({
|
7
|
+
href: '/',
|
8
|
+
links: [{href: '/place'}],
|
9
|
+
items: [{
|
10
|
+
data: [{name: 'full-name', value: 'phil'}]
|
11
|
+
}]
|
12
|
+
})
|
13
|
+
collection.to_json.class.should eq(String)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'collection-json/attributes/item'
|
3
|
+
|
4
|
+
describe CollectionJSON::Item do
|
5
|
+
it 'be serializable' do
|
6
|
+
item = CollectionJSON::Item.from_hash({
|
7
|
+
href: 'http://www.example.com',
|
8
|
+
links: [{href: 'http://www.example.com/place'}],
|
9
|
+
data: [{name: 'full-name', value: 'phil'}]
|
10
|
+
})
|
11
|
+
item.to_json.class.should eq(String)
|
12
|
+
end
|
13
|
+
end
|
@@ -50,20 +50,20 @@ describe CollectionJSON do
|
|
50
50
|
builder.add_link '/friends/rss', 'feed'
|
51
51
|
@friends.each do |friend|
|
52
52
|
builder.add_item("/friends/#{friend['id']}") do |item|
|
53
|
-
item.add_data "full-name", friend["full-name"]
|
54
|
-
item.add_data "email", friend["email"]
|
55
|
-
item.add_link "/blogs/#{friend['id']}", "blog",
|
56
|
-
item.add_link "/blogs/#{friend['id']}", "avatar",
|
53
|
+
item.add_data "full-name", {'value' => friend["full-name"]}
|
54
|
+
item.add_data "email", {'value' => friend["email"]}
|
55
|
+
item.add_link "/blogs/#{friend['id']}", "blog", {'prompt' => "Blog"}
|
56
|
+
item.add_link "/blogs/#{friend['id']}", "avatar", {'prompt' => "Avatar", 'render' => 'image'}
|
57
57
|
end
|
58
58
|
end
|
59
|
-
builder.add_query("/friends/search", "search", "Search") do |query|
|
59
|
+
builder.add_query("/friends/search", "search", {'prompt' => "Search"}) do |query|
|
60
60
|
query.add_data "search"
|
61
61
|
end
|
62
62
|
builder.set_template do |template|
|
63
|
-
template.add_data "full-name",
|
64
|
-
template.add_data "email",
|
65
|
-
template.add_data "blog",
|
66
|
-
template.add_data "avatar",
|
63
|
+
template.add_data "full-name", {'prompt' => "Full Name"}
|
64
|
+
template.add_data "email", {'prompt' => "Email"}
|
65
|
+
template.add_data "blog", {'prompt' => "Blog"}
|
66
|
+
template.add_data "avatar", {'prompt' => "Avatar"}
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collection-json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70343263781380 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70343263781380
|
25
25
|
description: Lightweight gem for building Collection+JSON responses.
|
26
26
|
email:
|
27
27
|
- sebastian@uprise.co.nz
|
@@ -35,6 +35,8 @@ files:
|
|
35
35
|
- Rakefile
|
36
36
|
- collection-json.gemspec
|
37
37
|
- lib/collection-json.rb
|
38
|
+
- lib/collection-json/attribute.rb
|
39
|
+
- lib/collection-json/attributes/collection.rb
|
38
40
|
- lib/collection-json/attributes/data.rb
|
39
41
|
- lib/collection-json/attributes/error.rb
|
40
42
|
- lib/collection-json/attributes/item.rb
|
@@ -42,8 +44,10 @@ files:
|
|
42
44
|
- lib/collection-json/attributes/query.rb
|
43
45
|
- lib/collection-json/attributes/template.rb
|
44
46
|
- lib/collection-json/builder.rb
|
45
|
-
- lib/collection-json/
|
47
|
+
- lib/collection-json/transformers/uri.rb
|
46
48
|
- lib/collection-json/version.rb
|
49
|
+
- spec/collection-json/attributes/collection_spec.rb
|
50
|
+
- spec/collection-json/attributes/item_spec.rb
|
47
51
|
- spec/collection-json/attributes/template_spec.rb
|
48
52
|
- spec/collection-json_spec.rb
|
49
53
|
- spec/spec_helper.rb
|
@@ -72,6 +76,8 @@ signing_key:
|
|
72
76
|
specification_version: 3
|
73
77
|
summary: Builds Collection+JSON responses.
|
74
78
|
test_files:
|
79
|
+
- spec/collection-json/attributes/collection_spec.rb
|
80
|
+
- spec/collection-json/attributes/item_spec.rb
|
75
81
|
- spec/collection-json/attributes/template_spec.rb
|
76
82
|
- spec/collection-json_spec.rb
|
77
83
|
- spec/spec_helper.rb
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require_relative 'attributes/link'
|
2
|
-
require_relative 'attributes/item'
|
3
|
-
require_relative 'attributes/query'
|
4
|
-
require_relative 'attributes/error'
|
5
|
-
require_relative 'attributes/template'
|
6
|
-
|
7
|
-
module CollectionJSON
|
8
|
-
class Collection
|
9
|
-
attr_reader :href, :links, :items, :queries, :template, :version, :error
|
10
|
-
attr_writer :version
|
11
|
-
|
12
|
-
def self.from_hash(hash)
|
13
|
-
self.new(hash[ROOT_NODE]['href']).tap do |collection|
|
14
|
-
%w{items links queries error template}.each do |attribute|
|
15
|
-
if hash[ROOT_NODE][attribute]
|
16
|
-
collection.send("#{attribute}=", hash[ROOT_NODE][attribute])
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(href)
|
23
|
-
@href = CollectionJSON.add_host(href)
|
24
|
-
@version = COLLECTION_JSON_VERSION
|
25
|
-
@items = []
|
26
|
-
@links = []
|
27
|
-
@queries = []
|
28
|
-
@error = nil
|
29
|
-
@template = nil
|
30
|
-
end
|
31
|
-
|
32
|
-
def items=(array)
|
33
|
-
@items = array.map {|item| Item.from_hash(item)}
|
34
|
-
end
|
35
|
-
|
36
|
-
def links=(array)
|
37
|
-
@links = array.map {|link| Link.from_hash(link)}
|
38
|
-
end
|
39
|
-
|
40
|
-
def queries=(array)
|
41
|
-
@queries = array.map {|query| Query.from_hash(query)}
|
42
|
-
end
|
43
|
-
|
44
|
-
def template=(template)
|
45
|
-
@template = Template.from_hash(template)
|
46
|
-
end
|
47
|
-
|
48
|
-
def error=(error)
|
49
|
-
@error = Error.from_hash(error)
|
50
|
-
end
|
51
|
-
|
52
|
-
def collection
|
53
|
-
{ROOT_NODE => body}
|
54
|
-
end
|
55
|
-
|
56
|
-
def to_json(*args)
|
57
|
-
collection.to_json(args)
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
def body
|
62
|
-
{href: href, version: version}.tap do |body|
|
63
|
-
%w{items links queries}.each do |child_name|
|
64
|
-
child = send(child_name)
|
65
|
-
body.merge!({child_name => child}) if child.length > 0
|
66
|
-
end
|
67
|
-
body.merge!({error: error}) if error
|
68
|
-
body.merge!({template: template}) if template
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|