api-model 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd7712e1eb0b5faac320b38518575bfbdeaf61b8
4
- data.tar.gz: 2ea94f183ad7de875863ff989327dc414d2dc54a
3
+ metadata.gz: b4468bee16f23aca5211838b3f54b918a0340716
4
+ data.tar.gz: 27a2004bc4145a4e6c71e3ae87c703b092b0c7d3
5
5
  SHA512:
6
- metadata.gz: f1e74e2574025ccf61e563ca0631e855211ff6953cb36a2d4986ef8c301c8477cda1913421c66d103dc225db2f10653693feec8706cbbd989dae3a60e351f585
7
- data.tar.gz: 68171597b2cb8448a10237485904d3353012196cc911d6c1cf09648e0e0e1d7f84bb5957e29ce51b4648fd995cd095bf9467c70ff26cae40ff1d385be17c4eae
6
+ metadata.gz: dcfae89dae5eb342dd14c6992efdd94cb2bff77582d2ede112bc3446a129225a1dd0025c4783bb7425bbe95c04518eca6e8f5d53d3a7bc2d177b994adfb45eeb
7
+ data.tar.gz: 6028927509a5e087babd8ad3f01d37819928a2bc39651c49a16c862bb77ea9b85c861d14560faf6f62d7b74fd69c3ec04cc04d76b35923958386c352488387cf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- api-model (0.0.4)
4
+ api-model (0.1.0)
5
5
  activemodel
6
6
  activesupport
7
7
  hashie
data/README.md CHANGED
@@ -30,7 +30,7 @@ Then, let's say the API endpoint /foo returned JSON which looks like `{ "name":
30
30
  Request types and params
31
31
  ------------------------
32
32
 
33
- There's a couple of convenience methods to make it simpler to send GET and POST requests,
33
+ There's a couple of convenience methods to make it simpler to send GET and POST requests,
34
34
  or you can send other request types:
35
35
 
36
36
  ```ruby
@@ -114,11 +114,29 @@ use as a builder should respond to `#build`, with the instance hash as an argume
114
114
  MyModel.get_json "/foo", { some_param: "bar" }, builder: MyCustomBuilder.new
115
115
  ```
116
116
 
117
+ Handling validation errors in responses
118
+ ---------------------------------------
119
+
120
+ ApiModel uses a bunch of Rails' ActiveModel enhancements to make it easy to use things such as validation errors.
121
+ You can define validations in the normal ActiveModel::Validations style and check validity before posting
122
+ to external APIs should you wish to. Or, if an external API returns errors which you would like to convert to
123
+ ActiveModel validations, you can do that, too:
124
+
125
+ ```ruby
126
+ class Car
127
+ property :name
128
+ end
129
+
130
+ car = Car.new
131
+ car.set_errors_from_hash name: "cannot be blank"
132
+ car.errors[:name] # => ["cannot be blank"]
133
+ ```
134
+
117
135
  Configuring API Model
118
136
  ---------------------
119
137
 
120
138
  You can configure API model in a number of places; globally using `ApiModel::Base.api_config`, per-model
121
- using `MyModel.api_config`, and per-api call by passing in options in the options hash (although some
139
+ using `MyModel.api_config`, and per-api call by passing in options in the options hash (although some
122
140
  configuration options may not be available on the per-api call technique).
123
141
 
124
142
  ### API Host
@@ -141,7 +159,7 @@ to refer to the full url all the time.
141
159
  ```
142
160
 
143
161
  If the API response which you receive is deeply nested and you want to cut out some levels of nesting, you
144
- can use `json_root` to set which key objects should be built from.
162
+ can use `json_root` to set which key objects should be built from.
145
163
 
146
164
  You can dig down multiple levels by separating keys with a period. With the example above, say the server
147
165
  was returning JSON which looked like `{"data":{"posts":{"name":"Foo"}}}`, it would behave as if the
@@ -201,12 +219,12 @@ something like this:
201
219
  ```ruby
202
220
  class MyCustomCacheStrategy
203
221
  attr_accessor :id, :options
204
-
222
+
205
223
  def initialize(id, options)
206
224
  @id = id
207
225
  @options = options
208
226
  end
209
-
227
+
210
228
  def cache(&block)
211
229
  # here you can check whether you want to actually call the api by running
212
230
  # block.call, or want to find and return your cached response.
data/api-model.gemspec CHANGED
@@ -2,7 +2,7 @@ $:.push File.expand_path("../lib", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "api-model"
5
- s.version = "0.0.4"
5
+ s.version = "0.1.0"
6
6
  s.authors = ["Damien Timewell"]
7
7
  s.email = ["mail@damientimewell.com"]
8
8
  s.homepage = "https://github.com/iZettle/api-model"
data/lib/api-model.rb CHANGED
@@ -8,7 +8,8 @@ require 'ostruct'
8
8
  require 'api_model/initializer'
9
9
  require 'api_model/http_request'
10
10
  require 'api_model/response'
11
- require 'api_model/rest_methods'
11
+ require 'api_model/class_methods'
12
+ require 'api_model/instance_methods'
12
13
  require 'api_model/configuration'
13
14
  require 'api_model/cache_stategies/no_cache'
14
15
  require 'api_model/response_parser/json'
@@ -36,17 +37,9 @@ module ApiModel
36
37
  extend ActiveModel::Naming
37
38
  extend ActiveModel::Callbacks
38
39
 
39
- extend RestMethods
40
+ extend ClassMethods
40
41
  include ConfigurationMethods
41
-
42
- # Overrides Hashie::Trash to catch errors from trying to set properties which have not been defined
43
- # and defines it automatically
44
- def property_exists?(property_name)
45
- super property_name
46
- rescue NoMethodError
47
- Log.debug "Could not set #{property_name} on #{self.class.name}. Defining it now."
48
- self.class.property property_name.to_sym
49
- end
42
+ include InstanceMethods
50
43
  end
51
44
 
52
45
  end
@@ -1,5 +1,5 @@
1
1
  module ApiModel
2
- module RestMethods
2
+ module ClassMethods
3
3
 
4
4
  def get_json(path, params={}, options={})
5
5
  call_api :get, path, options.merge(params: params)
@@ -0,0 +1,28 @@
1
+ module ApiModel
2
+ module InstanceMethods
3
+
4
+ # Overrides Hashie::Trash to catch errors from trying to set properties which have not been defined
5
+ # and defines it automatically
6
+ def property_exists?(property_name)
7
+ super property_name
8
+ rescue NoMethodError
9
+ Log.debug "Could not set #{property_name} on #{self.class.name}. Defining it now."
10
+ self.class.property property_name.to_sym
11
+ end
12
+
13
+ # Convenience method to handle error hashes and set them as ActiveModel errors on instances.
14
+ # Using the `obj`, you can move the errors on to child classes if needed.
15
+ def set_errors_from_hash(errors_hash, obj = self)
16
+ errors_hash.each do |field,messages|
17
+ if messages.is_a?(Array)
18
+ messages.each do |message|
19
+ obj.errors.add field.to_sym, message
20
+ end
21
+ else
22
+ obj.errors.add field.to_sym, messages
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -127,6 +127,27 @@ describe ApiModel do
127
127
  end
128
128
  end
129
129
 
130
+ describe "setting errors from a hash" do
131
+ let(:car) { Car.new }
132
+ let(:blog_post) { BlogPost.new }
133
+
134
+ it 'should assign errors from a simple hash using active model errors' do
135
+ car.set_errors_from_hash name: "Is invalid"
136
+ car.errors[:name].should eq ["Is invalid"]
137
+ end
138
+
139
+ it 'should assign multiple errors from an array' do
140
+ car.set_errors_from_hash top_speed: ["is too fast", "would break the sound barrier"]
141
+ car.errors[:top_speed].size.should eq 2
142
+ end
143
+
144
+ it 'should be possible to assign the errors to other classes' do
145
+ car.set_errors_from_hash({ name: "is bad" }, blog_post)
146
+ car.errors.size.should eq 0
147
+ blog_post.errors[:name].should eq ["is bad"]
148
+ end
149
+ end
150
+
130
151
  describe "cache_id" do
131
152
  it 'should use options and the request path to create an identifier for the cache' do
132
153
  BlogPost.cache_id("/box", params: { foo: "bar" }).should eq "/boxfoobar"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien Timewell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-21 00:00:00.000000000 Z
11
+ date: 2014-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -140,12 +140,13 @@ files:
140
140
  - api-model.gemspec
141
141
  - lib/api-model.rb
142
142
  - lib/api_model/cache_stategies/no_cache.rb
143
+ - lib/api_model/class_methods.rb
143
144
  - lib/api_model/configuration.rb
144
145
  - lib/api_model/http_request.rb
145
146
  - lib/api_model/initializer.rb
147
+ - lib/api_model/instance_methods.rb
146
148
  - lib/api_model/response.rb
147
149
  - lib/api_model/response_parser/json.rb
148
- - lib/api_model/rest_methods.rb
149
150
  - spec/api-model/api_model_spec.rb
150
151
  - spec/api-model/configuration_spec.rb
151
152
  - spec/api-model/http_request_spec.rb