restpack_serializer 0.4.25 → 0.4.26

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: 7d870c817c227fbac2102919ec10f69e727b61d4
4
- data.tar.gz: 14b4250d2a77c3d60b9e5c8872150b54503ff1f2
3
+ metadata.gz: 25923489c94e8e3dfc5b1406afddb1de14555e30
4
+ data.tar.gz: ba2c8686002cb5d6223df146d00d6a050a66b8b3
5
5
  SHA512:
6
- metadata.gz: 69e3fc5bc5c44d9c29ed24df5a06a326264e350d8147b9956ea1181546fdef97996145f0c3a7aabb081b5033129ca3e6ca3536ceca7d31c44e01b36c06ab49bb
7
- data.tar.gz: fe92f589efcf2273642b1c88d13415d9e75034d79e0eb50c993841a0c9aa6c8689b06a8b474cc1080df6dc69b5931b9a556460f53b2ae1add05e1c947d90d7f6
6
+ metadata.gz: 02e14de37827c4b899aa05e5d8bae3e8c5a6a3cb2348d2666bf4861933c3b6149e90df576fb10d2f541bb0a868fcc88de004fbe0b321377f1e94c281c30f04c3
7
+ data.tar.gz: 11dda7d263ad9263051518a7516c6bfa0f23575128b62d09889c4839db48c2caf6ce481091415a642c51b8d9ef4b8e1bfcc632e79e688b00b68db0db25be94b2
data/README.md CHANGED
@@ -345,6 +345,23 @@ Side-loading is available when filtering:
345
345
 
346
346
  * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?artist_ids=2,3&include=artists,songs
347
347
 
348
+ ## Sorting
349
+
350
+ Sorting attributes can be defined with the `can_sort_by` option:
351
+
352
+ ```ruby
353
+ class Account
354
+ include RestPack::Serializer
355
+ attributes :id, :application_id, :created_by, :name, :href
356
+
357
+ can_sort_by :id, :name
358
+ end
359
+ ```
360
+
361
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?sort=id
362
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?sort=-name
363
+ * http://restpack-serializer-sample.herokuapp.com/api/v1/albums.json?sort=name,-id
364
+
348
365
  ## Running Tests
349
366
 
350
367
  `bundle`
@@ -1,7 +1,8 @@
1
1
  module RestPack::Serializer
2
2
  class Options
3
3
  attr_accessor :page, :page_size, :include, :filters, :serializer,
4
- :model_class, :scope, :context, :include_links
4
+ :model_class, :scope, :context, :include_links,
5
+ :sorting
5
6
 
6
7
  def initialize(serializer, params = {}, scope = nil, context = {})
7
8
  params.symbolize_keys! if params.respond_to?(:symbolize_keys!)
@@ -10,6 +11,7 @@ module RestPack::Serializer
10
11
  @page_size = RestPack::Serializer.config.page_size
11
12
  @include = []
12
13
  @filters = filters_from_params(params, serializer)
14
+ @sorting = sorting_from_params(params, serializer)
13
15
  @serializer = serializer
14
16
  @model_class = serializer.model_class
15
17
  @scope = scope || model_class.send(:all)
@@ -42,6 +44,11 @@ module RestPack::Serializer
42
44
  @filters.sort.map {|k,v| "#{k}=#{v.join(',')}" }.join('&')
43
45
  end
44
46
 
47
+ def sorting_as_url_params
48
+ sorting_values = sorting.map { |k, v| v == :asc ? k : "-#{k}" }.join(',')
49
+ "sort=#{sorting_values}"
50
+ end
51
+
45
52
  private
46
53
 
47
54
  def filters_from_params(params, serializer)
@@ -53,5 +60,18 @@ module RestPack::Serializer
53
60
  end
54
61
  filters
55
62
  end
63
+
64
+ def sorting_from_params(params, serializer)
65
+ sort_values = params[:sort] && params[:sort].split(',')
66
+ return {} if sort_values.blank? || serializer.serializable_sorting_attributes.blank?
67
+ sorting_parameters = {}
68
+
69
+ sort_values.each do |sort_value|
70
+ sort_order = sort_value[0] == '-' ? :desc : :asc
71
+ sort_value = sort_value.gsub(/\A\-/, '').downcase.to_sym
72
+ sorting_parameters[sort_value] = sort_order if serializer.serializable_sorting_attributes.include?(sort_value)
73
+ end
74
+ sorting_parameters
75
+ end
56
76
  end
57
77
  end
@@ -2,7 +2,7 @@ module RestPack::Serializer::Attributes
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  def default_href
5
- "#{RestPack::Serializer.config.href_prefix}/#{self.class.key}/#{@model.id}"
5
+ "#{RestPack::Serializer.config.href_prefix}/#{self.class.key}/#{@model.to_param}"
6
6
  end
7
7
 
8
8
  module ClassMethods
@@ -8,6 +8,7 @@ module RestPack::Serializer::Paging
8
8
 
9
9
  def page_with_options(options)
10
10
  page = options.scope_with_filters.page(options.page).per(options.page_size)
11
+ page = page.reorder(options.sorting) if options.sorting.any?
11
12
 
12
13
  result = RestPack::Serializer::Result.new
13
14
  result.resources[self.key] = serialize_page(page, options)
@@ -58,6 +59,7 @@ module RestPack::Serializer::Paging
58
59
  params << "page=#{page}" unless page == 1
59
60
  params << "page_size=#{options.page_size}" unless options.default_page_size?
60
61
  params << "include=#{options.include.join(',')}" if options.include.any?
62
+ params << options.sorting_as_url_params if options.sorting.any?
61
63
  params << options.filters_as_url_params if options.filters.any?
62
64
 
63
65
  url += '?' + params.join('&') if params.any?
@@ -0,0 +1,14 @@
1
+ module RestPack::Serializer::Sortable
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ attr_reader :serializable_sorting_attributes
6
+
7
+ def can_sort_by(*attributes)
8
+ @serializable_sorting_attributes = []
9
+ attributes.each do |attribute|
10
+ @serializable_sorting_attributes << attribute.to_sym
11
+ end
12
+ end
13
+ end
14
+ end
@@ -7,6 +7,7 @@ require_relative "serializable/resource"
7
7
  require_relative "serializable/single"
8
8
  require_relative "serializable/side_loading"
9
9
  require_relative "serializable/symbolizer"
10
+ require_relative "serializable/sortable"
10
11
 
11
12
  module RestPack
12
13
  module Serializer
@@ -26,6 +27,7 @@ module RestPack
26
27
  include RestPack::Serializer::Attributes
27
28
  include RestPack::Serializer::Filterable
28
29
  include RestPack::Serializer::SideLoading
30
+ include RestPack::Serializer::Sortable
29
31
 
30
32
  class InvalidInclude < Exception; end
31
33
 
@@ -1,5 +1,5 @@
1
1
  module RestPack
2
2
  module Serializer
3
- VERSION = '0.4.25'
3
+ VERSION = '0.4.26'
4
4
  end
5
5
  end
data/spec/fixtures/db.rb CHANGED
@@ -57,6 +57,8 @@ module MyApp
57
57
  end
58
58
 
59
59
  class Song < ActiveRecord::Base
60
+ default_scope -> { order(id: :asc) }
61
+
60
62
  attr_accessible :title, :artist, :album
61
63
 
62
64
  belongs_to :artist
@@ -4,6 +4,7 @@ module MyApp
4
4
  attributes :id, :title, :album_id
5
5
  can_include :albums, :artists
6
6
  can_filter_by :title
7
+ can_sort_by :id, :title
7
8
 
8
9
  def title
9
10
  @context[:reverse_title?] ? @model.title.reverse : @model.title
@@ -59,6 +59,33 @@ describe RestPack::Serializer::Options do
59
59
  end
60
60
  end
61
61
 
62
+ context 'with sorting parameters' do
63
+ describe 'with no params' do
64
+ let(:params) { { } }
65
+ it { subject.sorting.should == {} }
66
+ end
67
+ describe 'with a sorting value' do
68
+ let(:params) { { 'sort' => 'Title' } }
69
+ it { subject.sorting.should == { title: :asc } }
70
+ it { subject.sorting_as_url_params.should == 'sort=title' }
71
+ end
72
+ describe 'with a descending sorting value' do
73
+ let(:params) { { 'sort' => '-title' } }
74
+ it { subject.sorting.should == { title: :desc } }
75
+ it { subject.sorting_as_url_params.should == 'sort=-title' }
76
+ end
77
+ describe 'with multiple sorting values' do
78
+ let(:params) { { 'sort' => '-Title,ID' } }
79
+ it { subject.sorting.should == { title: :desc, id: :asc } }
80
+ it { subject.sorting_as_url_params.should == 'sort=-title,id' }
81
+ end
82
+ describe 'with a not allowed sorting value' do
83
+ let(:params) { { 'sort' => '-title,album_id,id' } }
84
+ it { subject.sorting.should == { title: :desc, id: :asc } }
85
+ it { subject.sorting_as_url_params.should == 'sort=-title,id' }
86
+ end
87
+ end
88
+
62
89
  context 'scopes' do
63
90
  describe 'with default scope' do
64
91
  it { subject.scope.should == MyApp::Song.all }
@@ -180,6 +180,28 @@ describe RestPack::Serializer::Paging do
180
180
  end
181
181
  end
182
182
 
183
+ context 'when sorting' do
184
+ context 'with no sorting' do
185
+ let(:params) { {} }
186
+
187
+ it "uses the model's sorting" do
188
+ page[:songs].first[:id].to_i.should < page[:songs].last[:id].to_i
189
+ end
190
+ end
191
+
192
+ context 'with descending title sorting' do
193
+ let(:params) { { sort: '-title' } }
194
+
195
+ it 'returns a page with sorted songs' do
196
+ page[:songs].first[:title].should > page[:songs].last[:title]
197
+ end
198
+
199
+ it 'includes the sorting in page hrefs' do
200
+ page[:meta][:songs][:next_href].should == '/songs?page=2&sort=-title'
201
+ end
202
+ end
203
+ end
204
+
183
205
  context "with custom scope" do
184
206
  before do
185
207
  FactoryGirl.create(:album, year: 1930)
@@ -15,6 +15,10 @@ describe RestPack::Serializer do
15
15
  def self.table_name
16
16
  "people"
17
17
  end
18
+
19
+ def to_param
20
+ id.to_s
21
+ end
18
22
  end
19
23
 
20
24
  context "bare bones serializer" do
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe RestPack::Serializer::Sortable do
4
+ class CustomSerializer
5
+ include RestPack::Serializer
6
+ attributes :a, :b, :c
7
+
8
+ can_sort_by :a, :c
9
+ end
10
+
11
+ it 'captures the specified sorting attributes' do
12
+ CustomSerializer.serializable_sorting_attributes.should == [:a, :c]
13
+ end
14
+ 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.25
4
+ version: 0.4.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gavin Joyce
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-06 00:00:00.000000000 Z
11
+ date: 2014-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -231,6 +231,7 @@ files:
231
231
  - lib/restpack_serializer/serializable/resource.rb
232
232
  - lib/restpack_serializer/serializable/side_loading.rb
233
233
  - lib/restpack_serializer/serializable/single.rb
234
+ - lib/restpack_serializer/serializable/sortable.rb
234
235
  - lib/restpack_serializer/serializable/symbolizer.rb
235
236
  - lib/restpack_serializer/version.rb
236
237
  - restpack_serializer.gemspec
@@ -249,6 +250,7 @@ files:
249
250
  - spec/serializable/side_loading/has_many_spec.rb
250
251
  - spec/serializable/side_loading/side_loading_spec.rb
251
252
  - spec/serializable/single_spec.rb
253
+ - spec/serializable/sortable_spec.rb
252
254
  - spec/spec_helper.rb
253
255
  - spec/support/factory.rb
254
256
  homepage: https://github.com/RestPack
@@ -290,6 +292,7 @@ test_files:
290
292
  - spec/serializable/side_loading/has_many_spec.rb
291
293
  - spec/serializable/side_loading/side_loading_spec.rb
292
294
  - spec/serializable/single_spec.rb
295
+ - spec/serializable/sortable_spec.rb
293
296
  - spec/spec_helper.rb
294
297
  - spec/support/factory.rb
295
298
  has_rdoc: