collection-json 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|