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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77b1cb59846fc5bde66cd2a8a1ac8afaca678780
4
- data.tar.gz: 123cc1037faf9288fc0f910fe13ac00a36dced22
3
+ metadata.gz: 34136d9503bd1cfed3341367129e8c7ff9ccfb9d
4
+ data.tar.gz: 1ec6acd5d189963b9cd0efe1d8649d4c282edca2
5
5
  SHA512:
6
- metadata.gz: dc2303a764828ed2a40072a55f9c7eb050c01f335b08ddebf209ee799c259b1584311913d397b46159dbc6391bee76993bacfd136a3dbffaa12e8a4eb3b5d473
7
- data.tar.gz: ff6259a0874cce63d6a7c172b6ed93893fbc3c6bce45613ac3047f0d4a5b1f2f760df7a6dc6b48a4d374f590668073815dfef30e02dcc3dd17e95586b305db39
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
@@ -1,5 +1,6 @@
1
1
  require 'eipiai/configuration'
2
2
 
3
+ require 'eipiai/models'
3
4
  require 'eipiai/roar'
4
5
  require 'eipiai/validation'
5
6
  require 'eipiai/webmachine'
@@ -0,0 +1,2 @@
1
+ require 'eipiai/models/collection'
2
+ require 'eipiai/models/representable'
@@ -0,0 +1,13 @@
1
+ module Eipiai
2
+ # Collection
3
+ #
4
+ # Module used in classes that represent a collection of objects.
5
+ #
6
+ module Collection
7
+ attr_reader :dataset
8
+
9
+ def initialize(dataset)
10
+ @dataset = dataset
11
+ end
12
+ end
13
+ end
@@ -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
@@ -3,5 +3,5 @@
3
3
  # The current version of the Eipiai library.
4
4
  #
5
5
  module Eipiai
6
- VERSION = '0.5.1'
6
+ VERSION = '0.6.0'
7
7
  end
@@ -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
- # resource.to_hash(item) # => { uid: 'hello' }
124
+ # get('/item/hello')
125
+ # resource.to_hash(item)['uid'] # => 'hello'
141
126
  #
142
- # @param [Object] o = represented to call #to_hash on
127
+ # @param [Object] obj to call #to_hash on
143
128
  # @return [Hash] hash representation of the object
144
129
  #
145
- def to_hash(o = represented)
146
- o.method(:to_hash).arity.zero? ? o.to_hash : o.to_hash(request: request)
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
- private
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
- # Same as `object_class_name`, except this method will return a constant
176
- # _and_ keeps the namespace intact.
140
+ # New object, instantiated by passing the provided `params` into the
141
+ # object's `#from_hash` method.
177
142
  #
178
- # Returns `nil` if constant does not exist.
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.send :object_class # => Item
147
+ # resource.new_object.class # => Item
182
148
  #
183
- # @return [Class, nil] object class, or nil if not found
149
+ # @return [Object, nil] instantiated object, or nil if not found
184
150
  #
185
- def object_class
186
- self.class.name.chomp('Resource').singularize.constantize
187
- rescue NameError
188
- nil
189
- end
151
+ def new_object
152
+ return if object_class.nil?
190
153
 
191
- # singular_representer_class
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
- # collection_representer_class
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
- singular_representer_class.new(new_object).path
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 object
45
- @object ||= Struct.new(:dataset).new(object_class.dataset) if object_class
44
+ def to_hash
45
+ super(request.get? ? object : new_object)
46
46
  end
47
47
 
48
- def representer_class
49
- request.get? ? collection_representer_class : singular_representer_class
50
- end
48
+ def object
49
+ return unless collection_class && object_class
51
50
 
52
- def represented
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
@@ -61,10 +61,6 @@ module Eipiai
61
61
  HealthCheck.new
62
62
  end
63
63
 
64
- def represented
65
- object
66
- end
67
-
68
64
  private
69
65
 
70
66
  # healthy?
@@ -42,10 +42,6 @@ module Eipiai
42
42
  @merged_params ||= super.merge('uid' => object_uid)
43
43
  end
44
44
 
45
- def represented
46
- singular_representer_class.new(object)
47
- end
48
-
49
45
  def object
50
46
  @object ||= object_class.first(uid: object_uid) if object_class
51
47
  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.5.1
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-14 00:00:00.000000000 Z
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