restpack_serializer 0.4.9 → 0.4.10

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: 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