eipiai 0.5.1 → 0.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/eipiai.rb +1 -0
- data/lib/eipiai/models.rb +2 -0
- data/lib/eipiai/models/collection.rb +13 -0
- data/lib/eipiai/models/representable.rb +69 -0
- data/lib/eipiai/version.rb +1 -1
- data/lib/eipiai/webmachine.rb +2 -0
- data/lib/eipiai/webmachine/resources/api.rb +6 -0
- data/lib/eipiai/webmachine/resources/base.rb +18 -92
- data/lib/eipiai/webmachine/resources/collection.rb +6 -8
- data/lib/eipiai/webmachine/resources/concerns/objectifiable.rb +105 -0
- data/lib/eipiai/webmachine/resources/health.rb +0 -4
- data/lib/eipiai/webmachine/resources/singular.rb +0 -4
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34136d9503bd1cfed3341367129e8c7ff9ccfb9d
|
4
|
+
data.tar.gz: 1ec6acd5d189963b9cd0efe1d8649d4c282edca2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3adf462831a8f4c9287acbea3bb93d66b31dc8c3e862052d152a7ba091a8611989da4130d35d5f0f2623d115ebefa05d64df378545933e98e552a93b8cb6edfb
|
7
|
+
data.tar.gz: 3a8ab95d17d35671725ea6edbebbd94f599126ce5f073e3350fc2733bbf3fc53935ea9febd22361d5a53b94d1769c250dd643b6c0acaac68a29f88bda379f72e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## [v0.5.1](https://github.com/blendle/eipiai/tree/v0.5.1) (2015-12-14)
|
4
|
+
[Full Changelog](https://github.com/blendle/eipiai/compare/v0.5.0...v0.5.1)
|
5
|
+
|
6
|
+
**Merged pull requests:**
|
7
|
+
|
8
|
+
- improve curied links matching regex [\#9](https://github.com/blendle/eipiai/pull/9) ([JeanMertz](https://github.com/JeanMertz))
|
9
|
+
|
3
10
|
## [v0.5.0](https://github.com/blendle/eipiai/tree/v0.5.0) (2015-12-14)
|
4
11
|
[Full Changelog](https://github.com/blendle/eipiai/compare/v0.4.0...v0.5.0)
|
5
12
|
|
data/lib/eipiai.rb
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
module Eipiai
|
2
|
+
# Representable
|
3
|
+
#
|
4
|
+
# Module used to make a model "representable".
|
5
|
+
#
|
6
|
+
# When including this module into a class, it is expected that a similar
|
7
|
+
# class with a suffix "Representer" exists.
|
8
|
+
#
|
9
|
+
module Representable
|
10
|
+
# represented
|
11
|
+
#
|
12
|
+
# Return the represented version of the object.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# item = Item.new.extend(Eipiai::Representable)
|
16
|
+
# item.represented.class # => ItemRepresenter
|
17
|
+
#
|
18
|
+
# @return [Object] Representer instance based on current model
|
19
|
+
#
|
20
|
+
def represented
|
21
|
+
"#{self.class.name}Representer".constantize.new(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
# to_hash
|
25
|
+
#
|
26
|
+
# call `#to_hash` on the representer belonging to the object.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# item = Item.new.extend(Eipiai::Representable)
|
30
|
+
# item.to_hash # => { '_links' => { 'self' => { 'href' => '/item' } } }
|
31
|
+
#
|
32
|
+
# @param [Hash] options to be used inside the representer
|
33
|
+
# @return [Hash] hash representation of the object
|
34
|
+
#
|
35
|
+
def to_hash(options = {})
|
36
|
+
represented.to_hash(options)
|
37
|
+
end
|
38
|
+
|
39
|
+
# from_hash
|
40
|
+
#
|
41
|
+
# call `#from_hash` on the representer belonging to the object.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# item = Item.new.extend(Eipiai::Representable)
|
45
|
+
# item.from_hash('uid' => 'hello').uid # => 'hello'
|
46
|
+
#
|
47
|
+
# @param [Hash] hash to be used to set the object attributes
|
48
|
+
# @return [Object] the object itself
|
49
|
+
#
|
50
|
+
def from_hash(hash = {})
|
51
|
+
represented.from_hash(hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
# path
|
55
|
+
#
|
56
|
+
# The "path" to access the model. This method calls the representer's `path`
|
57
|
+
# method.
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
# item = Item.new(uid: 'hello').extend(Eipiai::Representable)
|
61
|
+
# item.path # => '/item/hello'
|
62
|
+
#
|
63
|
+
# @return [String] path to the objects resource
|
64
|
+
#
|
65
|
+
def path
|
66
|
+
represented.path
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/eipiai/version.rb
CHANGED
data/lib/eipiai/webmachine.rb
CHANGED
@@ -3,6 +3,8 @@ require 'webmachine'
|
|
3
3
|
require 'eipiai/webmachine/ext/decision'
|
4
4
|
require 'eipiai/webmachine/ext/request'
|
5
5
|
|
6
|
+
require 'eipiai/webmachine/resources/concerns/objectifiable'
|
7
|
+
|
6
8
|
require 'eipiai/webmachine/resources/api'
|
7
9
|
require 'eipiai/webmachine/resources/base'
|
8
10
|
require 'eipiai/webmachine/resources/collection'
|
@@ -4,7 +4,13 @@ require 'active_support/core_ext/string/inflections'
|
|
4
4
|
require 'json'
|
5
5
|
|
6
6
|
module Eipiai
|
7
|
+
# Api
|
8
|
+
#
|
9
|
+
# A noop class that exists to satisfy the needs of the Eipiai resource
|
10
|
+
# handler.
|
11
|
+
#
|
7
12
|
class Api
|
13
|
+
include Eipiai::Representable
|
8
14
|
end
|
9
15
|
|
10
16
|
# ApiResource
|
@@ -12,6 +12,8 @@ module Eipiai
|
|
12
12
|
# endpoint.
|
13
13
|
#
|
14
14
|
module Resource
|
15
|
+
include Objectifiable
|
16
|
+
|
15
17
|
# Includes the correct resource into the class, depending on its name.
|
16
18
|
#
|
17
19
|
# If the resource is called `ItemResource`, the `Item` part is considered
|
@@ -81,24 +83,6 @@ module Eipiai
|
|
81
83
|
[['application/json', :from_json]]
|
82
84
|
end
|
83
85
|
|
84
|
-
# new_object
|
85
|
-
#
|
86
|
-
# Return the instantiated object, based on the representer provided by
|
87
|
-
# `singular_representer_class` and the parameters provided by `params`.
|
88
|
-
#
|
89
|
-
# See `Object#new_object` for the version without using representers.
|
90
|
-
#
|
91
|
-
# @example
|
92
|
-
# resource.new_object.class # => Item
|
93
|
-
#
|
94
|
-
# @return [Class, nil] instantiated representer, or nil if not found
|
95
|
-
#
|
96
|
-
def new_object
|
97
|
-
return if singular_representer_class.nil? || object_class.nil?
|
98
|
-
|
99
|
-
@new_object ||= singular_representer_class.new(object_class.new).from_hash(params)
|
100
|
-
end
|
101
|
-
|
102
86
|
# params
|
103
87
|
#
|
104
88
|
# Given a string in JSON format, returns the hash representation of that
|
@@ -137,98 +121,40 @@ module Eipiai
|
|
137
121
|
#
|
138
122
|
# @example
|
139
123
|
# item = Item.new(uid: 'hello')
|
140
|
-
#
|
124
|
+
# get('/item/hello')
|
125
|
+
# resource.to_hash(item)['uid'] # => 'hello'
|
141
126
|
#
|
142
|
-
# @param [Object]
|
127
|
+
# @param [Object] obj to call #to_hash on
|
143
128
|
# @return [Hash] hash representation of the object
|
144
129
|
#
|
145
|
-
def to_hash(
|
146
|
-
|
130
|
+
def to_hash(obj = object)
|
131
|
+
obj.method(:to_hash).arity.zero? ? obj.to_hash : obj.to_hash(request: request)
|
147
132
|
end
|
148
133
|
|
149
134
|
def to_json
|
150
135
|
to_hash.to_json
|
151
136
|
end
|
152
137
|
|
153
|
-
|
154
|
-
|
155
|
-
# object_class_name
|
156
|
-
#
|
157
|
-
# String representation of the "object class", based on the current
|
158
|
-
# resource name.
|
159
|
-
#
|
160
|
-
# If the resource is called `ItemsResource`, object_class_name will be
|
161
|
-
# `Item`. It is expected that this name represents the class of the object
|
162
|
-
# the resource provides access to through the API.
|
163
|
-
#
|
164
|
-
# @example
|
165
|
-
# resource.send :object_class_name # => 'Item'
|
166
|
-
#
|
167
|
-
# @return [String] name of object class
|
168
|
-
#
|
169
|
-
def object_class_name
|
170
|
-
self.class.name.chomp('Resource').demodulize.singularize
|
171
|
-
end
|
172
|
-
|
173
|
-
# object_class
|
138
|
+
# new_object
|
174
139
|
#
|
175
|
-
#
|
176
|
-
#
|
140
|
+
# New object, instantiated by passing the provided `params` into the
|
141
|
+
# object's `#from_hash` method.
|
177
142
|
#
|
178
|
-
#
|
143
|
+
# The only requirement is that the object responds to `#from_hash`, that
|
144
|
+
# method accepts a hash of parameters, and it returns the object itself.
|
179
145
|
#
|
180
146
|
# @example
|
181
|
-
# resource.
|
147
|
+
# resource.new_object.class # => Item
|
182
148
|
#
|
183
|
-
# @return [
|
149
|
+
# @return [Object, nil] instantiated object, or nil if not found
|
184
150
|
#
|
185
|
-
def
|
186
|
-
|
187
|
-
rescue NameError
|
188
|
-
nil
|
189
|
-
end
|
151
|
+
def new_object
|
152
|
+
return if object_class.nil?
|
190
153
|
|
191
|
-
|
192
|
-
#
|
193
|
-
# Constant, representing the representer belonging to the defined
|
194
|
-
# `object`.
|
195
|
-
#
|
196
|
-
# If the resource is called `ItemResource`, the representer will be
|
197
|
-
# `ItemRepresenter`.
|
198
|
-
#
|
199
|
-
# Returns `nil` if constant does not exist.
|
200
|
-
#
|
201
|
-
# @example
|
202
|
-
# resource.send :singular_representer_class # => ItemRepresenter
|
203
|
-
#
|
204
|
-
# @return [Class, nil] representer class, or nil if not found
|
205
|
-
#
|
206
|
-
def singular_representer_class
|
207
|
-
"#{object_class}Representer".constantize
|
208
|
-
rescue NameError
|
209
|
-
nil
|
154
|
+
@new_object ||= object_class.new.from_hash(params)
|
210
155
|
end
|
211
156
|
|
212
|
-
|
213
|
-
#
|
214
|
-
# Constant, representing the representer belonging to the defined
|
215
|
-
# collection of `object`s.
|
216
|
-
#
|
217
|
-
# If the resource is called `ItemResource`, the representer will be
|
218
|
-
# `ItemsRepresenter`.
|
219
|
-
#
|
220
|
-
# Returns `nil` if constant does not exist.
|
221
|
-
#
|
222
|
-
# @example
|
223
|
-
# resource.send :collection_representer_class # => ItemsRepresenter
|
224
|
-
#
|
225
|
-
# @return [Class, nil] representer class, or nil if not found
|
226
|
-
#
|
227
|
-
def collection_representer_class
|
228
|
-
"#{object_class.to_s.pluralize}Representer".constantize
|
229
|
-
rescue NameError
|
230
|
-
nil
|
231
|
-
end
|
157
|
+
private
|
232
158
|
|
233
159
|
def json_error_body(errors)
|
234
160
|
response.headers['Content-Type'] = 'application/json'
|
@@ -20,7 +20,7 @@ module Eipiai
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def create_path
|
23
|
-
|
23
|
+
new_object.path
|
24
24
|
end
|
25
25
|
|
26
26
|
def from_json
|
@@ -41,16 +41,14 @@ module Eipiai
|
|
41
41
|
true
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
45
|
-
|
44
|
+
def to_hash
|
45
|
+
super(request.get? ? object : new_object)
|
46
46
|
end
|
47
47
|
|
48
|
-
def
|
49
|
-
|
50
|
-
end
|
48
|
+
def object
|
49
|
+
return unless collection_class && object_class
|
51
50
|
|
52
|
-
|
53
|
-
representer_class.new(request.get? ? object : new_object)
|
51
|
+
@object ||= collection_class.new(object_class.dataset)
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Eipiai
|
2
|
+
module Resource
|
3
|
+
# Objectifiable
|
4
|
+
#
|
5
|
+
# When included in a resource, provides basic methods to get to the "object"
|
6
|
+
# that the resource provides access to.
|
7
|
+
#
|
8
|
+
# Provided methods are:
|
9
|
+
#
|
10
|
+
# * resource_name # ItemRepresenter => 'Item'
|
11
|
+
# * object_class_name # ItemRepresenter => 'Item'
|
12
|
+
# * collection_class_name # ItemRepresenter => 'Items'
|
13
|
+
# * object_class # ItemRepresenter => Item
|
14
|
+
# * collection_class # ItemRepresenter => Items
|
15
|
+
#
|
16
|
+
module Objectifiable
|
17
|
+
private
|
18
|
+
|
19
|
+
# resource_name
|
20
|
+
#
|
21
|
+
# Take the resource class name, and strip `Resource` part from the name.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# resource.send :resource_name # => 'Eipiai::TestApp::Items'
|
25
|
+
#
|
26
|
+
# @return [String] resource name
|
27
|
+
#
|
28
|
+
def resource_name
|
29
|
+
self.class.name.chomp('Resource')
|
30
|
+
end
|
31
|
+
|
32
|
+
# object_class_name
|
33
|
+
#
|
34
|
+
# String representation of the "object class", based on the current
|
35
|
+
# resource name.
|
36
|
+
#
|
37
|
+
# If the resource is called `ItemsResource`, object_class_name will be
|
38
|
+
# `Item`. It is expected that this name represents the class of the object
|
39
|
+
# the resource provides access to through the API.
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# resource.send :object_class_name # => 'Item'
|
43
|
+
#
|
44
|
+
# @return [String] name of object class
|
45
|
+
#
|
46
|
+
def object_class_name
|
47
|
+
resource_name.demodulize.singularize
|
48
|
+
end
|
49
|
+
|
50
|
+
# object_class
|
51
|
+
#
|
52
|
+
# Same as `object_class_name`, except this method will return a constant
|
53
|
+
# _and_ keeps the namespace intact.
|
54
|
+
#
|
55
|
+
# Returns `nil` if constant does not exist.
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# resource.send :object_class # => Item
|
59
|
+
#
|
60
|
+
# @return [Class, nil] object class, or nil if not found
|
61
|
+
#
|
62
|
+
def object_class
|
63
|
+
resource_name.singularize.constantize
|
64
|
+
rescue NameError
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
|
68
|
+
# collection_class_name
|
69
|
+
#
|
70
|
+
# String representation of the "collection class", based on the current
|
71
|
+
# resource name.
|
72
|
+
#
|
73
|
+
# If the resource is called `ItemResource`, collection_class_name will be
|
74
|
+
# `Items`. It is expected that this name represents a collection of `Item`
|
75
|
+
# objects.
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# resource.send :collection_class_name # => 'Items'
|
79
|
+
#
|
80
|
+
# @return [String] name of collection class
|
81
|
+
#
|
82
|
+
def collection_class_name
|
83
|
+
resource_name.demodulize.pluralize
|
84
|
+
end
|
85
|
+
|
86
|
+
# collection_class
|
87
|
+
#
|
88
|
+
# Same as `collection_class_name`, except this method will return a
|
89
|
+
# constant _and_ keeps the namespace intact.
|
90
|
+
#
|
91
|
+
# Returns `nil` if constant does not exist.
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# resource.send :collection_class # => Items
|
95
|
+
#
|
96
|
+
# @return [Class, nil] collection class, or nil if not found
|
97
|
+
#
|
98
|
+
def collection_class
|
99
|
+
resource_name.pluralize.constantize
|
100
|
+
rescue NameError
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eipiai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Mertz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -244,6 +244,9 @@ files:
|
|
244
244
|
- features/webmachine.feature
|
245
245
|
- lib/eipiai.rb
|
246
246
|
- lib/eipiai/configuration.rb
|
247
|
+
- lib/eipiai/models.rb
|
248
|
+
- lib/eipiai/models/collection.rb
|
249
|
+
- lib/eipiai/models/representable.rb
|
247
250
|
- lib/eipiai/roar.rb
|
248
251
|
- lib/eipiai/roar/ext/hal.rb
|
249
252
|
- lib/eipiai/roar/representers/api.rb
|
@@ -259,6 +262,7 @@ files:
|
|
259
262
|
- lib/eipiai/webmachine/resources/api.rb
|
260
263
|
- lib/eipiai/webmachine/resources/base.rb
|
261
264
|
- lib/eipiai/webmachine/resources/collection.rb
|
265
|
+
- lib/eipiai/webmachine/resources/concerns/objectifiable.rb
|
262
266
|
- lib/eipiai/webmachine/resources/health.rb
|
263
267
|
- lib/eipiai/webmachine/resources/singular.rb
|
264
268
|
- script/bootstrap
|