munson 0.2.0 → 0.3.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/README.md +234 -246
- data/bin/console +2 -10
- data/lib/munson/agent.rb +35 -69
- data/lib/munson/attribute.rb +76 -0
- data/lib/munson/client.rb +43 -0
- data/lib/munson/collection.rb +19 -1
- data/lib/munson/connection.rb +61 -14
- data/lib/munson/document.rb +140 -0
- data/lib/munson/key_formatter.rb +87 -0
- data/lib/munson/middleware/encode_json_api.rb +10 -2
- data/lib/munson/middleware/json_parser.rb +11 -5
- data/lib/munson/query.rb +218 -0
- data/lib/munson/resource.rb +174 -20
- data/lib/munson/response_mapper.rb +92 -32
- data/lib/munson/version.rb +1 -1
- data/lib/munson.rb +30 -22
- metadata +7 -7
- data/lib/munson/model.rb +0 -15
- data/lib/munson/paginator/offset_paginator.rb +0 -45
- data/lib/munson/paginator/paged_paginator.rb +0 -47
- data/lib/munson/paginator.rb +0 -6
- data/lib/munson/query_builder.rb +0 -226
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 123416f906ed71b0bdc64d573de72e080c3e96ca
|
4
|
+
data.tar.gz: 2b29a00a7dc9417caa47588af57f05fe448d99a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53729cc19c386163266f1ee7a13bf4a508f76c757d465410739076525b9cc0b9030710b057e0d198bcb358a74a7e939803fa6e1541acaf6df10a58fb46f2a0d8
|
7
|
+
data.tar.gz: 3cf86622c38ee8673daf552033f0aac2cff89a1e40ddd3f6c122bcae58e60f7c947592c6348848e24d3634fcda3f0a848978cc45b3d2d9e334e71eda6dc07226
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
[](https://codeclimate.com/github/coryodaniel/munson)
|
4
4
|
[](https://codeclimate.com/github/coryodaniel/munson/coverage)
|
5
|
-

|
6
6
|
|
7
|
-
A JSON API
|
7
|
+
A JSON API client for Ruby
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -22,116 +22,103 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
$ gem install munson
|
24
24
|
|
25
|
-
## Usage
|
26
|
-
|
27
|
-
### Munson::Connection and configuring the default connection
|
28
|
-
|
29
|
-
Munson is designed to support multiple connections or API endpoints. A connection is a wrapper around Faraday::Connection that includes a few pieces of middleware for parsing and encoding requests and responses to JSON API Spec.
|
25
|
+
## Basic Usage
|
30
26
|
|
31
27
|
```ruby
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
```
|
36
|
-
|
37
|
-
Options can be any [Faraday::Connection options](https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb Faraday::Connection)
|
28
|
+
class Article < Munson::Resource
|
29
|
+
# This is done automatically if the tableize method is present
|
30
|
+
self.type = :articles
|
38
31
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
c.use MoreMiddleware
|
43
|
-
c.use AllTheMiddlewares
|
32
|
+
# how to process the JSON API ID. JSON API always uses strings, but Munson defaults to :integer
|
33
|
+
key_type :integer, #:string, ->(id){ }
|
34
|
+
attribute :title, :string
|
44
35
|
end
|
45
36
|
```
|
46
37
|
|
47
|
-
###
|
38
|
+
### Registering the JSONAPI 'type'
|
48
39
|
|
49
|
-
|
50
|
-
while allowing additional configuration for a particular 'resource.'
|
40
|
+
Calling ```Article.type = :articles``` registers the class ```Article``` as the handler for JSON API resources of the type ```articles```.
|
51
41
|
|
42
|
+
When the ActiveSupport method ```tableize``` is present, this will be set automatically. A class can be bound to multiple types:
|
52
43
|
|
53
44
|
```ruby
|
54
|
-
|
55
|
-
|
56
|
-
class Product
|
57
|
-
def self.munson
|
58
|
-
return @munson if @munson
|
59
|
-
@munson = Munson::Agent.new(
|
60
|
-
connection: Munson.default_connection, # || Munson::Connection.new(...)
|
61
|
-
paginator: :offset,
|
62
|
-
type: 'products'
|
63
|
-
)
|
64
|
-
end
|
65
|
-
end
|
45
|
+
Article.type = :articles
|
46
|
+
Munson.register_type(:posts, Article)
|
66
47
|
```
|
67
48
|
|
68
|
-
|
49
|
+
### Querying
|
69
50
|
```ruby
|
70
|
-
|
71
|
-
#
|
72
|
-
query.filter(category: 'Hats').filter(size: ['small', 'medium'])
|
51
|
+
articles = Article.fetch # Get some articles
|
52
|
+
article = Article.find(9) # Find an article
|
73
53
|
|
74
|
-
query.
|
75
|
-
#=> {:filter=>{:
|
54
|
+
query = Article.fields(:title).include(:author, :comments).sort(id: :desc).filter(published: true)
|
55
|
+
query.to_params #=> {:filter=>{:published=>"true"}, :fields=>{:articles=>"title"}, :include=>"author,comments", :sort=>"-id"}
|
56
|
+
query.to_query_string #=> "fields[articles]=title&filter[published]=true&include=author,comments&sort=-id"
|
76
57
|
|
77
|
-
|
58
|
+
query.fetch # Fetch articles w/ the given query string
|
78
59
|
```
|
79
60
|
|
61
|
+
The Munson::Resource delegates a few methods to its underlying Munson::Connection:
|
62
|
+
|
80
63
|
#### Filtering
|
81
64
|
|
82
65
|
```ruby
|
83
|
-
query = Product.
|
66
|
+
query = Product.filter(min_price: 30, max_price: 65)
|
67
|
+
|
84
68
|
# its chainable
|
85
69
|
query.filter(category: 'Hats').filter(size: ['small', 'medium'])
|
86
70
|
|
87
71
|
query.to_params
|
88
72
|
#=> {:filter=>{:min_price=>"30", :max_price=>"65", :category=>"Hats", :size=>"small,medium"}}
|
89
73
|
|
90
|
-
query.fetch #=>
|
74
|
+
query.fetch #=> Munson::Collection<Product,Product>
|
91
75
|
```
|
92
76
|
|
93
77
|
#### Sorting
|
94
78
|
|
95
79
|
```ruby
|
96
|
-
query = Product.
|
80
|
+
query = Product.sort(created_at: :desc)
|
81
|
+
|
97
82
|
# its chainable
|
98
83
|
query.sort(:price) # defaults to ASC
|
99
84
|
|
100
85
|
query.to_params
|
101
86
|
#=> {:sort=>"-created_at,price"}
|
102
87
|
|
103
|
-
query.fetch #=>
|
88
|
+
query.fetch #=> Munson::Collection<Product,Product>
|
104
89
|
```
|
105
90
|
|
106
91
|
#### Including (Side loading related resources)
|
107
92
|
|
108
93
|
```ruby
|
109
|
-
query = Product.
|
94
|
+
query = Product.include(:manufacturer)
|
95
|
+
|
110
96
|
# its chainable
|
111
|
-
query.
|
97
|
+
query.include(:vendor)
|
112
98
|
|
113
99
|
query.to_params
|
114
100
|
#=> {:include=>"manufacturer,vendor"}
|
115
101
|
|
116
|
-
query.fetch #=>
|
102
|
+
query.fetch #=> Munson::Collection<Product,Product>
|
117
103
|
```
|
118
104
|
|
119
105
|
#### Sparse Fieldsets
|
120
106
|
|
121
107
|
```ruby
|
122
|
-
query = Product.
|
108
|
+
query = Product.fields(products: [:name, :price])
|
109
|
+
|
123
110
|
# its chainable
|
124
|
-
query.
|
111
|
+
query.include(:manufacturer).fields(manufacturer: [:name])
|
125
112
|
|
126
113
|
query.to_params
|
127
114
|
#=> {:fields=>{:products=>"name,price", :manufacturer=>"name"}, :include=>"manufacturer"}
|
128
115
|
|
129
|
-
query.fetch #=>
|
116
|
+
query.fetch #=> Munson::Collection<Product,Product>
|
130
117
|
```
|
131
118
|
|
132
119
|
#### All the things!
|
133
120
|
```ruby
|
134
|
-
query = Product.
|
121
|
+
query = Product.
|
135
122
|
filter(min_price: 30, max_price: 65).
|
136
123
|
includes(:manufacturer).
|
137
124
|
sort(popularity: :desc, price: :asc).
|
@@ -139,228 +126,264 @@ query = Product.munson.
|
|
139
126
|
page(number: 1, limit: 100)
|
140
127
|
|
141
128
|
query.to_params
|
129
|
+
|
142
130
|
#=> {:filter=>{:min_price=>"30", :max_price=>"65"}, :fields=>{:product=>"name,price", :manufacturer=>"name,website"}, :include=>"manufacturer", :sort=>"-popularity,price", :page=>{:limit=>10}}
|
143
131
|
|
144
|
-
query.fetch #=>
|
132
|
+
query.fetch #=> Munson::Collection<Product,Product>
|
145
133
|
```
|
146
134
|
|
147
135
|
#### Fetching a single resource
|
148
136
|
|
149
137
|
```ruby
|
150
|
-
Product.
|
138
|
+
Product.find(1) #=> product
|
151
139
|
```
|
152
140
|
|
153
|
-
|
141
|
+
### Accessing Munson internals
|
142
|
+
Every Munson::Resource has an internally managed client. It is accessible via ```.munson```
|
154
143
|
|
155
|
-
A paged and offset paginator are included with Munson.
|
156
|
-
|
157
|
-
Using the ```offset``` paginator
|
158
144
|
```ruby
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
query = Product.munson.includes('manufacturer').page(offset: 10, limit: 25)
|
170
|
-
query.to_params
|
171
|
-
# => {:include=>"manufacturer", :page=>{:limit=>10, :offset=>10}}
|
172
|
-
|
173
|
-
query.fetch #=> Some lovely data
|
145
|
+
Article.munson #=> Munson::Client
|
146
|
+
Article.munson.path #=> base path to use for this resource. Defaults to "/" + type; i.e., "/articles"
|
147
|
+
Article.munson.agent #=> Munson::Agent: the agent wraps the Munson::Connection. It performs the low level GET/POST/PUT/PATCH/DELETE methods
|
148
|
+
Article.munson.query #=> Munson::Query: a chainable query building instance
|
149
|
+
Article.munson.connection #=> Munson::Connection: Small wrapper around the Farady connection
|
150
|
+
Article.munson.connection.response_key_format #=> :dasherize, :camelize, nil
|
151
|
+
Article.munson.connection.url #=> This endpoints base URL http://api.example.com/
|
152
|
+
Article.munson.connection.faraday #=> The faraday object for this connection
|
153
|
+
Article.muson.connection = SomeNewConnectionYouPrefer
|
154
|
+
Article.munson.connection.configure(opts) do { |faraday_conn| } #=> Feel free to reconfigure me ;D
|
174
155
|
```
|
175
156
|
|
176
|
-
|
157
|
+
### Persistence Resources
|
177
158
|
```ruby
|
178
|
-
class
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
paginator: :paged,
|
183
|
-
type: 'products'
|
184
|
-
)
|
185
|
-
end
|
159
|
+
class Article < Munson::Resource
|
160
|
+
attribute :title, :string
|
161
|
+
attribute :body, :string
|
162
|
+
attribute :created_at, :time
|
186
163
|
end
|
164
|
+
```
|
187
165
|
|
188
|
-
|
189
|
-
query.to_params
|
190
|
-
# => {:include=>"manufacturer", :page=>{:page=>10, :size=>10}}
|
166
|
+
Creating a new resource
|
191
167
|
|
192
|
-
|
168
|
+
```ruby
|
169
|
+
article = Article.new
|
170
|
+
article.title = "This is a great read!"
|
171
|
+
article.save #=> Boolean: Will attempt to POST to /articles
|
172
|
+
article.errors?
|
173
|
+
article.errors #=> Array of errors
|
193
174
|
```
|
194
175
|
|
195
|
-
|
196
|
-
Since the JSON API Spec does not dictate [how to paginate](http://jsonapi.org/format/#fetching-pagination), Munson has been designed to make adding custom paginators pretty easy.
|
176
|
+
Updating a resource
|
197
177
|
|
198
178
|
```ruby
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
179
|
+
article = Article.find(9)
|
180
|
+
article.title = "This is a great read!"
|
181
|
+
article.save #=> Boolean: Will attempt to PATCH to /articles
|
182
|
+
article.errors?
|
183
|
+
article.errors #=> Array of errors
|
184
|
+
```
|
203
185
|
|
204
|
-
|
205
|
-
def set(params={})
|
206
|
-
end
|
186
|
+
### Accessing Side Loaded Resources
|
207
187
|
|
208
|
-
|
209
|
-
def to_params
|
210
|
-
{ page: {} }
|
211
|
-
end
|
212
|
-
end
|
188
|
+
Given the following relationship:
|
213
189
|
|
214
|
-
```
|
190
|
+
```ruby
|
191
|
+
class Article < Munson::Resource
|
192
|
+
self.type = :articles
|
193
|
+
has_one :author
|
194
|
+
has_many :comments
|
215
195
|
|
216
|
-
|
196
|
+
key_type :integer
|
197
|
+
attribute :title, :string
|
198
|
+
end
|
217
199
|
|
218
|
-
|
200
|
+
class Person < Munson::Resource
|
201
|
+
self.type = :people
|
202
|
+
has_many :articles
|
219
203
|
|
220
|
-
|
204
|
+
attribute :first_name, String
|
205
|
+
attribute :last_name, :string
|
206
|
+
attribute :twitter, :string
|
207
|
+
attribute :created_at, :time, default: ->{ Time.now }, serialize: ->(val){ val.to_s }
|
208
|
+
attribute :post_count, :integer
|
209
|
+
end
|
221
210
|
|
222
|
-
|
223
|
-
|
211
|
+
class Comment < Munson::Resource
|
212
|
+
self.type = :comments
|
213
|
+
has_one :author
|
224
214
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
215
|
+
attribute :body, ->(val){ val.to_s }
|
216
|
+
attribute :score, :float
|
217
|
+
attribute :created_at, :time
|
218
|
+
attribute :is_spam, :boolean
|
219
|
+
attribute :mentions, :string, array: true
|
229
220
|
end
|
230
|
-
|
231
|
-
# Munson method is there, should you be looking for it.
|
232
|
-
Product.munson #=> Munson::Agent
|
233
221
|
```
|
234
222
|
|
235
|
-
**
|
223
|
+
**Note:** When specifying relationships in Munson, you are specifying the JSON API type name. You'll notice below that when ```.author``` is called it returns a person object. That it is because in the HTTP response, the relationship name is ```author``` but the resource type is ```people```.
|
224
|
+
|
225
|
+
```json
|
226
|
+
{
|
227
|
+
"data": [{
|
228
|
+
"type": "articles",
|
229
|
+
"id": "1",
|
230
|
+
"attributes": {
|
231
|
+
"title": "JSON API paints my bikeshed!"
|
232
|
+
},
|
233
|
+
"relationships": {
|
234
|
+
"author": {
|
235
|
+
"links": {
|
236
|
+
"self": "http://example.com/articles/1/relationships/author",
|
237
|
+
"related": "http://example.com/articles/1/author"
|
238
|
+
},
|
239
|
+
"data": { "type": "people", "id": "9" }
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}]
|
243
|
+
}
|
244
|
+
```
|
236
245
|
|
237
|
-
|
246
|
+
Munson initializes objects for side loaded resources. Only 1 HTTP call is made.
|
238
247
|
|
239
248
|
```ruby
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
249
|
+
article = Article.include(:author, :comments).find(9)
|
250
|
+
article.author #=> Person object
|
251
|
+
article.comments #=> Munson::Collection<Comment>
|
252
|
+
|
253
|
+
article.author.first_name #=> Chauncy
|
244
254
|
```
|
245
255
|
|
246
|
-
There are two ways to set the JSON API type when using a Munson::Resource
|
247
256
|
|
248
|
-
**Registering the type**
|
249
257
|
|
250
|
-
|
258
|
+
## Configuration
|
259
|
+
|
260
|
+
Munson is designed to support multiple connections or API endpoints. A connection is a wrapper around Faraday::Connection that includes a few pieces of middleware for parsing and encoding requests and responses to JSON API Spec.
|
261
|
+
|
262
|
+
Setting the default connection:
|
251
263
|
|
252
264
|
```ruby
|
253
|
-
|
254
|
-
|
255
|
-
|
265
|
+
Munson.configure(url: 'http://api.example.com') do |c|
|
266
|
+
c.use MyCustomMiddleware
|
267
|
+
c.use AllTheMiddlewares
|
256
268
|
end
|
257
269
|
```
|
258
270
|
|
259
|
-
|
271
|
+
Each Munson::Resource has its own Munson::Client. The client *copies* the default connection so its easy to set general configuration options, and overwrite them on a resource by resource basis.
|
260
272
|
|
261
273
|
```ruby
|
262
|
-
|
263
|
-
# its chainable
|
264
|
-
query.filter(category: 'Hats').filter(size: ['small', 'medium'])
|
274
|
+
Munson.configure(url: 'http://api.example.com', response_key_format: :dasherize)
|
265
275
|
|
266
|
-
|
267
|
-
|
276
|
+
class Kitten < Munson::Resource
|
277
|
+
munson.url = "http://api.differentsite.com"
|
278
|
+
end
|
268
279
|
|
269
|
-
|
280
|
+
# Overwritten URL
|
281
|
+
Kitten.munson.connection.url #=> "http://api.differentsite.com"
|
282
|
+
# Copied key format
|
283
|
+
Kitten.munson.connection.response_key_format #=> :dasherize
|
284
|
+
|
285
|
+
Munson.default_connection.url #=> "http://api.example.com"
|
286
|
+
Munson.default_connection.response_key_format #=> :dasherize
|
270
287
|
```
|
271
288
|
|
272
|
-
|
289
|
+
### Configuration Options
|
273
290
|
|
274
291
|
```ruby
|
275
|
-
|
276
|
-
|
277
|
-
|
292
|
+
Munson.configure(url: 'http://api.example.com', response_key_format: :dasherize) do |conn|
|
293
|
+
conn.use SomeCoolFaradayMiddleware
|
294
|
+
end
|
295
|
+
```
|
278
296
|
|
279
|
-
|
280
|
-
|
297
|
+
Two special options can be passed into ```.configure```:
|
298
|
+
* ```url``` the base url for this endpoint
|
299
|
+
* ```response_key_format``` the format of the JSONAPI response keys. Valid values are: ```:dasherize```, ```:camelize```, ```nil```
|
281
300
|
|
282
|
-
|
283
|
-
```
|
301
|
+
Additinally any Faraday Connection options can be passed. [Faraday::Connection options](https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb Faraday::Connection)
|
284
302
|
|
285
|
-
#### Including (Side loading related resources)
|
286
303
|
|
287
|
-
|
288
|
-
query = Product.includes(:manufacturer)
|
289
|
-
# its chainable
|
290
|
-
query.includes(:vendor)
|
304
|
+
## Advanced Usage
|
291
305
|
|
292
|
-
|
293
|
-
#=> {:include=>"manufacturer,vendor"}
|
306
|
+
### Custom Query Builder
|
294
307
|
|
295
|
-
|
296
|
-
|
308
|
+
Since the filter param's format isn't specified in the [spec](http://jsonapi.org/format/#fetching-filtering)
|
309
|
+
this implementation uses (JSONAPI::Resource's implementation](https://github.com/cerebris/jsonapi-resources#filters)
|
297
310
|
|
298
|
-
|
311
|
+
To override, implement your own custom query builder inheriting from {Munson::Query}
|
312
|
+
{Munson::Client} takes a Query class to use. This method could be overwritten in your Resource
|
299
313
|
|
300
314
|
```ruby
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
#=> {:fields=>{:products=>"name,price", :manufacturer=>"name"}, :include=>"manufacturer"}
|
315
|
+
class MyBuilder < Munson::Query
|
316
|
+
def filter_to_query_value
|
317
|
+
# ... your fancier logic
|
318
|
+
end
|
319
|
+
end
|
307
320
|
|
308
|
-
|
321
|
+
Article.munson.query_builder = MyBuilder
|
309
322
|
```
|
310
323
|
|
311
|
-
|
324
|
+
### Without inheriting from Munson::Resource
|
325
|
+
|
326
|
+
If for some reason you cannot inherit from Munson::Resource, you can still get a lot of JSONAPI parsing functionality
|
327
|
+
|
312
328
|
```ruby
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
fields(product: ['name', 'price'], manufacturer: ['name', 'website']).
|
318
|
-
page(number: 1, limit: 100)
|
329
|
+
class Album
|
330
|
+
# Just some attr accessors, NBD
|
331
|
+
attr_accessor :id
|
332
|
+
attr_accessor :title
|
319
333
|
|
320
|
-
|
321
|
-
|
334
|
+
# Give Album a client to use
|
335
|
+
def self.munson
|
336
|
+
return @munson if @munson
|
337
|
+
@munson = Munson::Client.new
|
338
|
+
end
|
322
339
|
|
323
|
-
|
324
|
-
|
340
|
+
# Set the type, note, this is not being set on self
|
341
|
+
munson.type = :albums
|
325
342
|
|
326
|
-
|
343
|
+
# Register the type w/ munson
|
344
|
+
Munson.register_type(munson.type, self)
|
345
|
+
|
346
|
+
# When you aren't inherited from Munson::Resource, Munson will pass a Munson::Document to a static method called munson_initializer for you to initialze your record as you wish
|
347
|
+
def self.munson_initializer(document)
|
348
|
+
new(document.id, document.attributes[:title])
|
349
|
+
end
|
350
|
+
|
351
|
+
def initialize(id, title)
|
352
|
+
@id = id
|
353
|
+
@title = title
|
354
|
+
end
|
355
|
+
end
|
356
|
+
```
|
327
357
|
|
328
358
|
```ruby
|
329
|
-
|
359
|
+
albums = Album.munson.include(:songs).fetch
|
360
|
+
albums.first.title #=> An album title!
|
330
361
|
```
|
331
362
|
|
332
|
-
|
363
|
+
### Any ol' object (Register type, add munson_initializer)
|
364
|
+
|
365
|
+
As long as a class is registered with munson and it response to munson_initializer, Munson will be able to initialize the object with or without a client
|
333
366
|
|
334
|
-
|
367
|
+
Extending the example above...
|
335
368
|
|
336
|
-
Using the ```offset``` paginator
|
337
369
|
```ruby
|
338
|
-
class
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
end
|
370
|
+
class Song
|
371
|
+
attr_reader :name
|
372
|
+
def self.munson_initializer(document)
|
373
|
+
new(document.attributes[:name])
|
374
|
+
end
|
343
375
|
|
344
|
-
|
345
|
-
|
346
|
-
|
376
|
+
def initialize(name)
|
377
|
+
@name = name
|
378
|
+
end
|
379
|
+
end
|
347
380
|
|
348
|
-
|
381
|
+
Munson.register_type :songs, Song
|
349
382
|
```
|
350
383
|
|
351
|
-
Using the ```paged``` paginator
|
352
384
|
```ruby
|
353
|
-
|
354
|
-
|
355
|
-
munson.paginator = :paged
|
356
|
-
munson.paginator_options = {default: 10, max: 100}
|
357
|
-
end
|
358
|
-
|
359
|
-
query = Product.includes('manufacturer').page(page: 10, size: 25)
|
360
|
-
query.to_params
|
361
|
-
# => {:include=>"manufacturer", :page=>{:page=>10, :size=>10}}
|
362
|
-
|
363
|
-
query.fetch #=> Some lovely data
|
385
|
+
album = Album.munson.include(:songs).find(9)
|
386
|
+
album.songs #=> Munson::Collection<Song>
|
364
387
|
```
|
365
388
|
|
366
389
|
## Development
|
@@ -369,58 +392,23 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
369
392
|
|
370
393
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
371
394
|
|
372
|
-
## Contributing
|
373
|
-
|
374
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/coryodaniel/munson.
|
375
|
-
|
376
|
-
### Munson::Model
|
377
|
-
WIP see [usage](#usage)
|
378
|
-
|
379
|
-
Finding related resources could set instance methods that mix/override behavior of the class level agent...
|
380
395
|
|
381
|
-
|
382
|
-
Article.find(1) uses Article.munson
|
383
|
-
|
384
|
-
/articles/1/author
|
385
|
-
article = Article.find(1) uses Article.munson
|
386
|
-
article.author uses article.munson as a new connection that sets the base uri to /articles/1
|
396
|
+
## Contributing
|
387
397
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
Address.update(1, {}) #update without loading
|
407
|
-
Address.destroy(1) #Destroy without loading
|
408
|
-
|
409
|
-
address = Address.find(300)
|
410
|
-
address.destroy
|
411
|
-
|
412
|
-
Address.find(10)
|
413
|
-
Address.filter(zip_code: 90210).find(10)
|
414
|
-
Address.filter(zip_code: 90210).all
|
415
|
-
Address.filter(zip_code: 90210).fetch
|
416
|
-
Address.includes(:user, 'user.purchases').filter(active: true).all
|
417
|
-
Address.includes(:user, 'user.purchases').find(10)
|
418
|
-
Address.sort(city: :asc)
|
419
|
-
Address.sort(city: :desc)
|
420
|
-
Address.fields(:street1, :street2, {user: :name})
|
421
|
-
Address.fields(:street1, :street2).fields(user: :name)
|
422
|
-
addresses = Address.fields(:street1, :street2).fields(user: :name)
|
423
|
-
addresses.first.shipped_products.filter(min_total: 300.00)
|
424
|
-
|
425
|
-
Custom collection/member methods?
|
426
|
-
```
|
398
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/stacksocial/munson.
|
399
|
+
|
400
|
+
|
401
|
+
## TODOS
|
402
|
+
* [ ] Update Yard docs :D
|
403
|
+
* [ ] A few pending tests :/
|
404
|
+
* [ ] Collection#next (queries for next page, if pagination present)
|
405
|
+
* [ ] Related Documents/Resources taking advantage of underlying resource[links]
|
406
|
+
* [ ] Resource should provide relationship information to the underlying document ?
|
407
|
+
* [ ] Error object to wrap an individual error
|
408
|
+
* [ ] consider enumerable protocol on a query
|
409
|
+
* [ ] Handle null/empty responses...
|
410
|
+
* [ ] munson/rails - magic up all the things
|
411
|
+
* [ ] auto set type based on pluralization (self.type = :foos)
|
412
|
+
* [ ] http://api.rubyonrails.org/classes/ActiveModel/Dirty.html ?
|
413
|
+
* [ ] Pluggable pagination (could it be a subclassed QueryBuilder? vs. a set of methods mixed into a query instance)
|
414
|
+
* [ ] Query#find([...]) find multiple records
|