restpack_serializer 0.4.25 → 0.4.26

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