json_api_model 0.1.1 → 0.1.2

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: b3324fc4a9bc44c2e4f35bb8bfc07c85fa37d9b9
4
- data.tar.gz: 8b131250bc286d8c6e6e7fbe3c47064d65f63942
3
+ metadata.gz: c0c2e854a3a779030b0ab788040d6481ec4f72c8
4
+ data.tar.gz: 0bac3b49d6310dca35407b67411e615d6d422643
5
5
  SHA512:
6
- metadata.gz: f7338edaeb52f641a1b942c8d603c81274de36f91f9d4fd25b3d87b9d920b11baf240b4d0e829e2c0e737cbc02b7c313d2d9faa7177e83996822a70185e97ab8
7
- data.tar.gz: 99f5989402ddff1c256cb6753347356e0f8fb7945d371e4993866c3d700bea5f3bbf06f7fa271b330359b1c7602cdacbe09119e01115187635b29d46a3319dc4
6
+ metadata.gz: 4733844d6db1d48f8353d0e384bdfaa8e3695e51260668bdf546ca9e7c625ea21d218c295f5f663df34628301392d3d20517c7d8619559a7d5d3e67189e843db
7
+ data.tar.gz: 92d708f1e39de4cdb028785cc489edc3029b8c99e5d8631129500e225d62dfeca65d60a506fa30bd0f6f9f104d602e658f0055d01ef29cf32b68f5a76b823910
data/Gemfile.lock ADDED
@@ -0,0 +1,67 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ json_api_model (0.1.1)
5
+ json_api_client
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (5.2.0)
11
+ activesupport (= 5.2.0)
12
+ activesupport (5.2.0)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 0.7, < 2)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ addressable (2.5.2)
18
+ public_suffix (>= 2.0.2, < 4.0)
19
+ concurrent-ruby (1.0.5)
20
+ crack (0.4.3)
21
+ safe_yaml (~> 1.0.0)
22
+ docile (1.3.1)
23
+ faraday (0.15.2)
24
+ multipart-post (>= 1.2, < 3)
25
+ faraday_middleware (0.12.2)
26
+ faraday (>= 0.7.4, < 1.0)
27
+ hashdiff (0.3.7)
28
+ i18n (1.0.1)
29
+ concurrent-ruby (~> 1.0)
30
+ json (2.1.0)
31
+ json_api_client (1.5.3)
32
+ activemodel (>= 3.2.0)
33
+ activesupport (>= 3.2.0)
34
+ addressable (~> 2.2)
35
+ faraday (~> 0.9)
36
+ faraday_middleware (~> 0.9)
37
+ minitest (5.11.3)
38
+ multipart-post (2.0.0)
39
+ public_suffix (3.0.2)
40
+ rake (10.5.0)
41
+ safe_yaml (1.0.4)
42
+ simplecov (0.16.1)
43
+ docile (~> 1.1)
44
+ json (>= 1.8, < 3)
45
+ simplecov-html (~> 0.10.0)
46
+ simplecov-html (0.10.2)
47
+ thread_safe (0.3.6)
48
+ tzinfo (1.2.5)
49
+ thread_safe (~> 0.1)
50
+ webmock (3.4.2)
51
+ addressable (>= 2.3.6)
52
+ crack (>= 0.3.2)
53
+ hashdiff
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ bundler (~> 1.16)
60
+ json_api_model!
61
+ minitest (~> 5.0)
62
+ rake (~> 10.0)
63
+ simplecov
64
+ webmock
65
+
66
+ BUNDLED WITH
67
+ 1.16.1
data/README.md CHANGED
@@ -20,11 +20,94 @@ Or install it yourself as:
20
20
 
21
21
  $ gem install json_api_model
22
22
 
23
+ ## Disclaimer
24
+
25
+ This is a work in progress. Right now only fetching data works. This will soon change.
26
+
23
27
  ## Usage
24
28
 
25
- TODO: finish writing this
29
+ Using the model wrappers is pretty straighforward. It thinly wraps `JsonApiClient` to separate communication defintions from your in-app business specific logic. To specify what client class your model is wrapping, use the `wraps` method.
30
+
31
+ Any instance or class(non-query) level method will fall thorugh to the client.
32
+
33
+ ### Example
34
+
35
+ If you have an app that talks to a `user` service. Here's how your `User` model might look:
36
+
37
+ ```ruby
38
+ module UserService
39
+ class User < JsonApiModel::Model
40
+ wraps UserService::Client::User
41
+
42
+ def lucky_number
43
+ 42
44
+ end
45
+ end
46
+ end
47
+ ```
48
+
49
+ And the interaction with it is not that different from how you would work with the client:
50
+
51
+ ```ruby
52
+ # fetching looks identical to as json_api_client (because it thinly wraps it)
53
+ user = UserService::User.where( id: 8 ).first
54
+
55
+ # now you can access your app logic
56
+ user.lucky_number
57
+
58
+ # => 42
59
+
60
+ # but also transparently access the client properties
61
+ user.id
62
+ # => 8
63
+ ```
64
+
65
+ ### Rendering
66
+
67
+ If you need to propagate your response set up, `JsonApiModel` adds `as_json` handling so that:
68
+
69
+ ```ruby
70
+ class WhateversController < ApplicationController
71
+ def index
72
+ render json: MyService::MyModel.where( params ).all
73
+ end
74
+ end
75
+ ```
76
+
77
+ Would produce the standard JSONAPI response of:
78
+
79
+ ```ruby
80
+ {
81
+ data: data,
82
+ meta: meta
83
+ }
84
+ ```
85
+
86
+ But if that's not the structure you want, you can modify the `to_json` output as:
87
+
88
+ ```ruby
89
+ class MyModelInRussianConroller < ApplicationController
90
+
91
+ def индекс
92
+ @response = MyModel.where( params ).all
93
+
94
+ @response.as_json do |data, meta|
95
+ {
96
+ данные: data,
97
+ мета: {
98
+ счёт: meta["record_count"],
99
+ страницы: meta["page_count"]
100
+ }
101
+ }
102
+ end
103
+ end
104
+ end
105
+ ```
106
+
107
+
108
+ ### Configuration
26
109
 
27
- Sample Base Class
110
+ If you don't want to override the connection configuration of the client gem in an initializer, you can modify the connection options inside an inhrited class.
28
111
 
29
112
  ```ruby
30
113
  module MyService
@@ -45,31 +128,40 @@ module MyService
45
128
  end
46
129
  ```
47
130
 
48
- Inherited Class
131
+ ### Monitoring
49
132
 
50
- ```ruby
51
- module MySerive
52
- class MyModel < Base
53
- wraps MyService::Client::MyModel
133
+ `JsonApiModel` emits several `ActiveSupport::Notifications` events you can subscribe to:
54
134
 
55
- def instanece_level_business
56
- 42
57
- end
58
- end
59
- end
60
- ```
135
+ * `find.json_api_model`: fires on every `find`/`all`/`to_a` call. Probably most common.
136
+
137
+ | key | value |
138
+ |------|-------|
139
+ | url | full url hit |
140
+ | args | args passed into the requestor |
61
141
 
62
- In the controller
142
+ * `first.json_api_model`: fires on `Model.first`
143
+
144
+ | key | value |
145
+ |------|-------|
146
+ | url | full url hit |
147
+
148
+ * `last.json_api_model`: fired on `Model.last`
149
+
150
+ | key | value |
151
+ |------|-------|
152
+ | url | full url hit |
153
+
154
+ **NOTE**: By default the instrumenter is null, so be sure to configure your app to actually have a notifier and subscribe to the events
63
155
 
64
156
  ```ruby
65
- class WhateversController < ApplicationController
66
- def index
67
- render json: MyService::MyModel.where( request.query_parameters ).all.as_json
68
- end
157
+ # config/initializers/json_api_model.rb
158
+ JsonApiModel.instrumenter = ActiveSupport::Notifications.instrumenter
159
+
160
+ ActiveSupport::Notifications.subscribe "find.json_api_model" do |name, started, finished, unique_id, payload|
161
+ Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
69
162
  end
70
163
  ```
71
164
 
72
-
73
165
  ## Development
74
166
 
75
167
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -78,7 +170,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
78
170
 
79
171
  ## Contributing
80
172
 
81
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/json_api_model. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
173
+ Bug reports and pull requests are welcome on GitHub at https://github.com/gaorlov/json_api_model. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
82
174
 
83
175
  ## License
84
176
 
@@ -86,4 +178,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
86
178
 
87
179
  ## Code of Conduct
88
180
 
89
- Everyone interacting in the JsonApiModel project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/json_api_model/blob/master/CODE_OF_CONDUCT.md).
181
+ Everyone interacting in the JsonApiModel project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/gaorlov/json_api_model/blob/master/CODE_OF_CONDUCT.md).
@@ -25,4 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "bundler", "~> 1.16"
26
26
  spec.add_development_dependency "rake", "~> 10.0"
27
27
  spec.add_development_dependency "minitest", "~> 5.0"
28
+ spec.add_development_dependency "simplecov"
29
+ spec.add_development_dependency "webmock"
28
30
  end
@@ -13,6 +13,7 @@ module JsonApiModel
13
13
  def new_from_client( client )
14
14
  model = new
15
15
  model.client = client
16
+ model
16
17
  end
17
18
 
18
19
  def connection( &block )
@@ -26,7 +27,7 @@ module JsonApiModel
26
27
  end
27
28
  end
28
29
 
29
- attr_reader :client
30
+ attr_accessor :client
30
31
 
31
32
  def initialize( attributes = {} )
32
33
  @client = self.class.client_class.new( attributes )
@@ -36,10 +37,10 @@ module JsonApiModel
36
37
  client.send m, *args, &block
37
38
  end
38
39
 
39
- private
40
-
41
- def client=( client )
42
- @client = client
40
+ def as_json
41
+ client.as_json
43
42
  end
43
+
44
+ RESERVED_FIELDS = [ :type, :id ]
44
45
  end
45
46
  end
@@ -1,14 +1,17 @@
1
1
  module JsonApiModel
2
2
  class ResultSet
3
- def initialize( client_result_set, resource_class )
4
- @set = client_result_set
3
+ def initialize( client_result_set, model_class )
4
+ @set = client_result_set.clone
5
+ @set.map! do | resource |
6
+ model_class.new_from_client( resource )
7
+ end
5
8
  end
6
9
 
7
10
  def as_json( opts = {} )
8
11
  if block_given?
9
12
  yield @set, meta
10
13
  else
11
- { data: @set,
14
+ { data: @set.map(&:as_json),
12
15
  meta: meta
13
16
  }
14
17
  end
@@ -1,8 +1,8 @@
1
1
  module JsonApiModel
2
2
  class Scope
3
- def initialize( resource_class )
4
- @resource_class = resource_class
5
- @client_scope = JsonApiClient::Query::Builder.new( resource_class.client_class )
3
+ def initialize( model_class )
4
+ @model_class = model_class
5
+ @client_scope = JsonApiClient::Query::Builder.new( model_class.client_class )
6
6
  end
7
7
 
8
8
  def to_a
@@ -17,24 +17,24 @@ module JsonApiModel
17
17
  args: args,
18
18
  url: url do
19
19
  results = @client_scope.find args
20
- ResultSet.new( results, @resource_class )
20
+ ResultSet.new( results, @model_class )
21
21
  end
22
22
  end
23
23
 
24
24
  def first
25
25
  JsonApiModel.instrumenter.instrument 'first.json_api_model', url: url do
26
- @resource_class.new_from_client @client_scope.first
26
+ @model_class.new_from_client @client_scope.first
27
27
  end
28
28
  end
29
29
 
30
30
  def last
31
31
  JsonApiModel.instrumenter.instrument 'last.json_api_model', url: url do
32
- @resource_class.new_from_client @client_scope.last
32
+ @model_class.new_from_client @client_scope.last
33
33
  end
34
34
  end
35
35
 
36
36
  def build
37
- @resource_class.new_from_client @client_scope.build
37
+ @model_class.new_from_client @client_scope.build
38
38
  end
39
39
 
40
40
  def params
@@ -53,7 +53,7 @@ module JsonApiModel
53
53
  private
54
54
 
55
55
  def url
56
- @resource_class.client_class.requestor.send( :resource_path, params )
56
+ @model_class.client_class.requestor.send( :resource_path, params )
57
57
  end
58
58
  end
59
59
  end
@@ -1,3 +1,3 @@
1
1
  module JsonApiModel
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_api_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Orlov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-11 00:00:00.000000000 Z
11
+ date: 2018-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json_api_client
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description:
70
98
  email:
71
99
  - gaorlov@gmail.com
@@ -77,6 +105,7 @@ files:
77
105
  - ".travis.yml"
78
106
  - CODE_OF_CONDUCT.md
79
107
  - Gemfile
108
+ - Gemfile.lock
80
109
  - LICENSE.txt
81
110
  - README.md
82
111
  - Rakefile