restpack_serializer 0.4.9 → 0.4.10

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: c406b9af62170a52083627f373ffdc67a1942140
4
- data.tar.gz: 7b73768866438375cf7e1b870e5da680ef60b363
3
+ metadata.gz: 2dfadef3b0cdb67cc4f5a4b659448218f230bcba
4
+ data.tar.gz: 5f83c011e2b01d6c539250e289661fde606d1d55
5
5
  SHA512:
6
- metadata.gz: ddd06300644271b871ace5bf86921c284145361fe7d3f5e3c334fedf7e8475f10afaaf74299e628a21320706229ae56927c7a20a404b414c8d8aed53a26d2fd5
7
- data.tar.gz: a92f904c22955987d9415c772e61b7b0bccbffb8864d102d3a1d6b3d96d2b9af431eb4dc79e4d29b6bf6d756a51d80d687fb4b300499243380b27501ca0d401c
6
+ metadata.gz: b13cf34cf4f9e0a4cda766e356d6fc69e249eb9944de45f3ad5e489e9fda2f9506b377540f9a798782aa5cf230ecdaa5f966df884040b98b62afe5790689266d
7
+ data.tar.gz: 0d6c339987850df7d6a3e8dfe2a3e683eb2df3277878c0e98eaf613a0677f1da91eff1007bce939e9d8092d5ca976d9694143676209fd94f2406a682edc28492
data/README.md CHANGED
@@ -64,8 +64,8 @@ end
64
64
 
65
65
  These endpoint will live at URLs such as `/albums` and `/albums/142857`:
66
66
 
67
- * http://restpack-serializer-sample.herokuapp.com/albums.json
68
- * http://restpack-serializer-sample.herokuapp.com/albums/4.json
67
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json
68
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums/4.json
69
69
 
70
70
  Both `page` and `resource` methods take an optional scope argument allowing us to enforce arbitrary constraints:
71
71
 
@@ -77,12 +77,12 @@ AlbumSerializer.page(params, Albums.where("year < 1950"))
77
77
 
78
78
  Collections are paged by default. `page` and `page_size` parameters are available:
79
79
 
80
- * http://restpack-serializer-sample.herokuapp.com/songs.json?page=2
81
- * http://restpack-serializer-sample.herokuapp.com/songs.json?page=2&page_size=3
80
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/songs.json?page=2
81
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/songs.json?page=2&page_size=3
82
82
 
83
83
  Paging details are included in a `meta` attribute:
84
84
 
85
- http://restpack-serializer-sample.herokuapp.com/songs.json?page=2&page_size=3 yields:
85
+ http://restpack-serializer-sample.herokuapp.com/api/v1/songs.json?page=2&page_size=3 yields:
86
86
 
87
87
  ```javascript
88
88
  {
@@ -163,11 +163,11 @@ In this example, we are allowing related `songs` and `artists` to be included in
163
163
 
164
164
  #### No side-loads
165
165
 
166
- * http://restpack-serializer-sample.herokuapp.com/albums.json
166
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json
167
167
 
168
168
  #### Side-load related Artists
169
169
 
170
- * http://restpack-serializer-sample.herokuapp.com/albums.json?include=artists
170
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?include=artists
171
171
 
172
172
  which yields:
173
173
 
@@ -269,15 +269,15 @@ which yields:
269
269
 
270
270
  #### Side-load related Songs
271
271
 
272
- * http://restpack-serializer-sample.herokuapp.com/albums.json?include=songs
272
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?include=songs
273
273
 
274
274
  An album `:has_many` songs, so the side-loaded songs are paged. The `meta.songs` includes `previous_href` and `next_href` which point to the previous and next page of this side-loaded data. These URLs take the form:
275
275
 
276
- * http://restpack-serializer-sample.herokuapp.com/songs.json?album_ids=1,2,3,4&page=2
276
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/songs.json?album_ids=1,2,3,4&page=2
277
277
 
278
278
  #### Side-load related Artists and Songs
279
279
 
280
- * http://restpack-serializer-sample.herokuapp.com/albums.json?include=artists,songs
280
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?include=artists,songs
281
281
 
282
282
  ## Filtering
283
283
 
@@ -285,13 +285,13 @@ Simple filtering based on primary and foreign keys is supported by default:
285
285
 
286
286
  #### By primary key:
287
287
 
288
- * http://restpack-serializer-sample.herokuapp.com/albums.json?id=1
289
- * http://restpack-serializer-sample.herokuapp.com/albums.json?ids=1,2,4
288
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?id=1
289
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?ids=1,2,4
290
290
 
291
291
  #### By foreign key:
292
292
 
293
- * http://restpack-serializer-sample.herokuapp.com/albums.json?artist_id=1
294
- * http://restpack-serializer-sample.herokuapp.com/albums.json?artist_ids=2,3
293
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?artist_id=1
294
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?artist_ids=2,3
295
295
 
296
296
  #### Custom filters:
297
297
 
@@ -308,4 +308,4 @@ end
308
308
 
309
309
  Side-loading is available when filtering:
310
310
 
311
- * http://restpack-serializer-sample.herokuapp.com/albums.json?artist_ids=2,3&include=artists,songs
311
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?artist_ids=2,3&include=artists,songs
@@ -5,6 +5,7 @@ require 'restpack_serializer/version'
5
5
  require 'restpack_serializer/configuration'
6
6
  require 'restpack_serializer/serializable'
7
7
  require 'restpack_serializer/factory'
8
+ require 'restpack_serializer/result'
8
9
 
9
10
  module RestPack
10
11
  module Serializer
@@ -0,0 +1,53 @@
1
+ module RestPack::Serializer
2
+ class Result
3
+ attr_accessor :resources, :meta, :links
4
+
5
+ def initialize
6
+ @resources = {}
7
+ @meta = {}
8
+ @links = {}
9
+ end
10
+
11
+ def serialize
12
+ result = {}
13
+
14
+ result[:meta] = @meta unless @meta.empty?
15
+ result[:links] = @links unless @links.empty?
16
+
17
+ unless @resources.empty?
18
+ inject_to_many_links!
19
+ result[@resources.keys.first] = @resources.values.first
20
+
21
+ linked = @resources.except(@resources.keys.first)
22
+ result[:linked] = linked unless linked.empty?
23
+ end
24
+
25
+ result
26
+ end
27
+
28
+ private
29
+
30
+ def inject_to_many_links! #find and inject to_many links from related @resources
31
+ @resources.keys.each do |key|
32
+ @resources[key].each do |item|
33
+ if item[:links]
34
+ item[:links].each do |link_key, link_value|
35
+ unless link_value.is_a? Array
36
+ plural_linked_key = "#{link_key}s".to_sym
37
+
38
+ if @resources[plural_linked_key]
39
+ linked_resource = @resources[plural_linked_key].find { |i| i[:id] == link_value }
40
+ if linked_resource
41
+ linked_resource[:links] ||= {}
42
+ linked_resource[:links][key] ||= []
43
+ linked_resource[:links][key] << item[:id]
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -12,24 +12,21 @@ module RestPack::Serializer::Paging
12
12
  per_page: options.page_size
13
13
  )
14
14
 
15
- result = {
16
- self.key => serialize_page(page),
17
- :meta => {
18
- self.key => serialize_meta(page, options)
19
- }
20
- }
15
+ result = RestPack::Serializer::Result.new
16
+ result.resources[self.key] = serialize_page(page)
17
+ result.meta[self.key] = serialize_meta(page, options)
21
18
 
22
19
  if options.include_links
23
- result[:links] = self.links
20
+ result.links = self.links
24
21
  Array(RestPack::Serializer::Factory.create(*options.include)).each do |serializer|
25
- result[:links].merge! serializer.class.links
22
+ result.links.merge! serializer.class.links
26
23
  end
27
24
  end
28
25
 
29
26
  side_load_data = side_loads(page, options)
30
- result[:meta].merge!(side_load_data[:meta] || {})
31
- result = result.merge side_load_data.except(:meta)
32
- inject_to_many_links result
27
+ result.meta.merge!(side_load_data[:meta] || {})
28
+ result.resources.merge! side_load_data.except(:meta)
29
+ result.serialize
33
30
  end
34
31
 
35
32
  private
@@ -69,32 +66,5 @@ module RestPack::Serializer::Paging
69
66
  url += '?' + params.join('&') if params.any?
70
67
  url
71
68
  end
72
-
73
- def inject_to_many_links(result) #TODO: GJ: extract this into a result class and refactor
74
- keys = result.keys - [:meta, :links]
75
-
76
- keys.each do |key|
77
- result[key].each do |item|
78
- if item[:links]
79
- item[:links].each do |link_key, link_value|
80
- unless link_value.is_a? Array
81
- plural_linked_key = "#{link_key}s".to_sym
82
-
83
- if result[plural_linked_key]
84
- linked_resource = result[plural_linked_key].find { |i| i[:id] == link_value }
85
- if linked_resource
86
- linked_resource[:links] ||= {}
87
- linked_resource[:links][key] ||= []
88
- linked_resource[:links][key] << item[:id]
89
- end
90
- end
91
- end
92
- end
93
- end
94
- end
95
- end
96
-
97
- result
98
- end
99
69
  end
100
70
  end
@@ -1,5 +1,5 @@
1
1
  module RestPack
2
2
  module Serializer
3
- VERSION = '0.4.9'
3
+ VERSION = '0.4.10'
4
4
  end
5
5
  end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe RestPack::Serializer::Result do
4
+ context 'a new instance' do
5
+ it 'has defaults' do
6
+ subject.resources.should == {}
7
+ subject.meta.should == {}
8
+ subject.links.should == {}
9
+ end
10
+ end
11
+
12
+ context 'when serializing' do
13
+ let(:result) { subject.serialize }
14
+ context 'in jsonapi.org format' do
15
+ context 'an empty result' do
16
+ it 'returns an empty result' do
17
+ result.should == {}
18
+ end
19
+ end
20
+
21
+ context 'a simple list of resources' do
22
+ before do
23
+ subject.resources[:albums] = [{ name: 'Album 1' }, { name: 'Album 2'}]
24
+ subject.meta[:albums] = { count: 2 }
25
+ subject.links['albums.songs'] = { href: 'songs.json', type: 'songs' }
26
+ end
27
+
28
+ it 'returns correct jsonapi.org format' do
29
+ result[:albums].should == subject.resources[:albums]
30
+ result[:meta].should == subject.meta
31
+ result[:links].should == subject.links
32
+ end
33
+ end
34
+
35
+ context 'a list with side-loaded resources' do
36
+ before do
37
+ subject.resources[:albums] = [{ id: '1', name: 'AMOK'}]
38
+ subject.resources[:songs] = [{ id: '91', name: 'Before Your Very Eyes...', links: { album: '1' }}]
39
+ subject.links['albums.songs'] = { type: 'songs', href: '/api/v1/songs?album_id={albums.id}' }
40
+ subject.links['songs.album'] = { type: 'albums', href: '/api/v1/albums/{songs.album}' }
41
+ end
42
+
43
+ it 'returns correct jsonapi.org format, including injected to_many links' do
44
+ result[:albums].should == [{ id: '1', name: 'AMOK', links: { songs: ['91'] } }]
45
+ result[:links].should == subject.links
46
+ result[:linked][:songs].should == subject.resources[:songs]
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -101,7 +101,7 @@ describe RestPack::Serializer::Paging do
101
101
  let(:params) { { include: 'albums' } }
102
102
 
103
103
  it "includes side-loaded models" do
104
- page[:albums].should_not == nil
104
+ page[:linked][:albums].should_not == nil
105
105
  end
106
106
 
107
107
  it "includes the side-loads in the main meta data" do
@@ -118,7 +118,7 @@ describe RestPack::Serializer::Paging do
118
118
  song[:links][:album].should == song_model.album_id.to_s
119
119
  song[:links][:artist].should == song_model.artist_id.to_s
120
120
 
121
- album = page[:albums].first
121
+ album = page[:linked][:albums].first
122
122
  album_model = MyApp::Album.find(album[:id])
123
123
 
124
124
  album[:links][:artist].should == album_model.artist_id.to_s
@@ -128,8 +128,8 @@ describe RestPack::Serializer::Paging do
128
128
  context "with includes as comma delimited string" do
129
129
  let(:params) { { include: "albums,artists" } }
130
130
  it "includes side-loaded models" do
131
- page[:albums].should_not == nil
132
- page[:artists].should_not == nil
131
+ page[:linked][:albums].should_not == nil
132
+ page[:linked][:artists].should_not == nil
133
133
  end
134
134
 
135
135
  it "includes the side-loads in page hrefs" do
@@ -18,8 +18,8 @@ describe RestPack::Serializer::Resource do
18
18
  let(:params) { { id: @song.id, include: 'albums' } }
19
19
 
20
20
  it "includes side-loaded models" do
21
- resource[:albums].count.should == 1
22
- resource[:albums].first[:id].should == @song.album.id.to_s
21
+ resource[:linked][:albums].count.should == 1
22
+ resource[:linked][:albums].first[:id].should == @song.album.id.to_s
23
23
  end
24
24
 
25
25
  it "includes the side-loads in the main meta data" do
@@ -75,7 +75,7 @@ describe RestPack::Serializer::SideLoading do
75
75
  MyApp::ArtistSerializer.filterable_by.should == [:id]
76
76
  end
77
77
  end
78
- context "a model with a single :belongs_torelations" do
78
+ context "a model with a single :belongs_to relations" do
79
79
  it "is filterable by primary key and foreign keys" do
80
80
  MyApp::AlbumSerializer.filterable_by.should =~ [:id, :artist_id, :year]
81
81
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restpack_serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gavin Joyce
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-25 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: activerecord
@@ -225,6 +225,7 @@ files:
225
225
  - lib/restpack_serializer/configuration.rb
226
226
  - lib/restpack_serializer/factory.rb
227
227
  - lib/restpack_serializer/options.rb
228
+ - lib/restpack_serializer/result.rb
228
229
  - lib/restpack_serializer/serializable.rb
229
230
  - lib/restpack_serializer/serializable/attributes.rb
230
231
  - lib/restpack_serializer/serializable/filterable.rb
@@ -237,6 +238,7 @@ files:
237
238
  - spec/fixtures/db.rb
238
239
  - spec/fixtures/serializers.rb
239
240
  - spec/restpack_serializer_spec.rb
241
+ - spec/result_spec.rb
240
242
  - spec/serializable/attributes_spec.rb
241
243
  - spec/serializable/filterable_spec.rb
242
244
  - spec/serializable/options_spec.rb
@@ -267,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
269
  version: '0'
268
270
  requirements: []
269
271
  rubyforge_project:
270
- rubygems_version: 2.0.7
272
+ rubygems_version: 2.0.5
271
273
  signing_key:
272
274
  specification_version: 4
273
275
  summary: Model serialization, paging, side-loading and filtering
@@ -276,6 +278,7 @@ test_files:
276
278
  - spec/fixtures/db.rb
277
279
  - spec/fixtures/serializers.rb
278
280
  - spec/restpack_serializer_spec.rb
281
+ - spec/result_spec.rb
279
282
  - spec/serializable/attributes_spec.rb
280
283
  - spec/serializable/filterable_spec.rb
281
284
  - spec/serializable/options_spec.rb