jsonapi-utils 0.4.9 → 0.5.0.beta1

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: 9e79dcc432ea412e938f711f040d12c70cb5196f
4
- data.tar.gz: e34a24d48a769016f737c156311523935b4714a7
3
+ metadata.gz: e739a959755e7910791783ee16583499f32c06a6
4
+ data.tar.gz: 817a8fb3526e0fc8f15e4081a277a9e81d557340
5
5
  SHA512:
6
- metadata.gz: 9b4222af57feada6a8c45b7385e8c889535e8000e229093e4053ce2812ef041aaf799216267e5105195282b027d516cf5b01db12204697f33d92c169a3b2ecd1
7
- data.tar.gz: 4accdb7433731907f5cd9121c8e8227d916dae0480e1decf56b727208b7ef1537ef765236c4058130c21f74e77e09aceefcc4f1ed18c3d9d152c200b0f773030
6
+ metadata.gz: 3307a7571da692f2606d056cb0d7c8b28acc3abcd9cd53b39e521d5a979ef4b95c4499f5eb41b4b816417cb47e59b31548cf19fd262c214844c3d81941deee2a
7
+ data.tar.gz: a210faeb4ea1aa675d236ef1e8993c81bcc2f273392f0fa80dd983d322ebdba6846019556cc2ccddcb1ae6afbc11bafe483ce75b95da12c19e46e4ffb5a1f30b
data/README.md CHANGED
@@ -4,16 +4,47 @@
4
4
  [![Gem Version](https://badge.fury.io/rb/jsonapi-utils.svg)](https://badge.fury.io/rb/jsonapi-utils)
5
5
  [![Build Status](https://travis-ci.org/b2beauty/jsonapi-utils.svg?branch=master)](https://travis-ci.org/b2beauty/jsonapi-utils)
6
6
 
7
- Simple yet powerful way to have your Rails API compliant with [JSON API](http://jsonapi.org).
8
-
9
- JSONAPI::Utils (JU) was built on top of [JSONAPI::Resources](https://github.com/cerebris/jsonapi-resources) taking advantage of its resource-driven style and bringing a Rails way to build modern APIs with no or less learning curve.
7
+ Simple yet powerful way to get your Rails API compliant with [JSON API](http://jsonapi.org).
8
+
9
+ JSONAPI::Utils (JU) is built on top of [JSONAPI::Resources](https://github.com/cerebris/jsonapi-resources) taking advantage of its resource-driven style and bringing a Rails way to build modern APIs with no or less learning curve.
10
+
11
+ ## Contents
12
+
13
+ * [Installation](#installation)
14
+ * [How does it work?](#how-does-it-work)
15
+ * [Usage](#usage)
16
+ * [Response](#response)
17
+ * [Rendes](#renders)
18
+ * [Formatters](#formatters)
19
+ * [Request](#request)
20
+ * [Params helpers](#params-helpers)
21
+ * [Full example](#full-example)
22
+ * [Models](#models)
23
+ * [Resources](#resources)
24
+ * [Routes & Controllers](routes--controllers)
25
+ * [Initializer](#initializer)
26
+ * [Requests & Responses](requests--responses)
27
+ * [Index](#index)
28
+ * [Index (options)](#index-options)
29
+ * [Show](#show)
30
+ * [Show (options)](#show-options)
31
+ * [Relationships (identifier objects)](#relationships-identifier-objects)
32
+ * [Nested resources](#nested-resources)
33
+ * [Development](#development)
34
+ * [Contributing](#contributing)
35
+ * [License](#license)
10
36
 
11
37
  ## Installation
12
38
 
39
+ For:
40
+
41
+ * Ruby ~> 2.0 with Rails ~> 4.0, use JU's `0.4.6` version (stable);
42
+ * Ruby ~> 2.1 with Rails 5, use JU's `0.5.0.beta1` version.
43
+
13
44
  Add these lines to your application's Gemfile:
14
45
 
15
46
  ```ruby
16
- gem 'jsonapi-utils', '~> 0.4.8'
47
+ gem 'jsonapi-utils', '~> 0.4.6'
17
48
  ```
18
49
 
19
50
  And then execute:
@@ -171,6 +202,19 @@ Content-Type: application/vnd.api+json
171
202
  }
172
203
  ```
173
204
 
205
+ #### Params helpers
206
+
207
+ JU brings helper methods as a shortcut to get values from permitted params based on the resource configuration.
208
+
209
+ - `resource_params`:
210
+ - Returns the permitted params present in the `attributes` JSON member;
211
+ - Example: `{ name: 'Bilbo', gender: 'male', city: 'Shire' }`
212
+ - Same of calling: `params.require(:data).require(:attributes).permit(:name, :gender, :city)`
213
+ - `relationship_params`:
214
+ - Returns the relationship `id`s, distinguished by key, present in `relationships` JSON member;
215
+ - Example: `{ author: 1, posts: [1, 2, 3] }`
216
+ - Same as calling: `params.require(:relationships).require(:author).require(:data).permit(:id)`
217
+
174
218
  ## Full example
175
219
 
176
220
  In order to start working with JU after installing the gem you simply need to do the following:
@@ -224,7 +268,7 @@ end
224
268
 
225
269
  ### Routes & Controllers
226
270
 
227
- Let's define our routes using the `jsonapi_resources` and `jsonapi_links` macros provied by the `jsonapi-resources` gem:
271
+ Let's define our routes using the `jsonapi_resources` and `jsonapi_links` methods provied by the `jsonapi-resources` gem:
228
272
 
229
273
  ```ruby
230
274
  Rails.application.routes.draw do
@@ -235,11 +279,13 @@ Rails.application.routes.draw do
235
279
  end
236
280
  ```
237
281
 
238
- In our base controller we need to include the `JSONAPI::Utils` module and define some default rendering:
282
+ In our Rails controller we just need to include the `JSONAPI::Utils` module.
283
+
284
+ > Note: with JU default rendering can be defined, like in the below example with `jsonapi_render_not_found` for when ActiveRecord doesn't find a record.
239
285
 
240
286
  ```ruby
241
287
  # app/controllers/base_controller.rb
242
- class BaseController < JSONAPI::ResourceController
288
+ class BaseController < ActionController::Base
243
289
  include JSONAPI::Utils
244
290
  protect_from_forgery with: :null_session
245
291
  rescue_from ActiveRecord::RecordNotFound, with: :jsonapi_render_not_found
@@ -250,49 +296,43 @@ Finally, having inhirited `JSONAPI::Utils` methods from the `BaseController` we
250
296
 
251
297
  ```ruby
252
298
  # app/controllers/users_controller.rb
253
- # GET /users
254
- def index
255
- users = User.all
256
- jsonapi_render json: users
257
- end
299
+ # GET /users
300
+ def index
301
+ users = User.all
302
+ jsonapi_render json: users
303
+ end
258
304
 
259
- # GET /users/:id
260
- def show
261
- user = User.find(params[:id])
262
- jsonapi_render json: user
263
- end
305
+ # GET /users/:id
306
+ def show
307
+ user = User.find(params[:id])
308
+ jsonapi_render json: user
309
+ end
264
310
 
265
- # POST /users
266
- def create
267
- user = User.new(user_params)
268
- if user.save
269
- jsonapi_render json: user, status: :created
270
- else
271
- jsonapi_render_errors json: user, status: :unprocessable_entity
272
- end
311
+ # POST /users
312
+ def create
313
+ user = User.new(resource_params)
314
+ if user.save
315
+ jsonapi_render json: user, status: :created
316
+ else
317
+ jsonapi_render_errors json: user, status: :unprocessable_entity
273
318
  end
319
+ end
274
320
 
275
- # PATCH /users/:id
276
- def update
277
- user = User.find(params[:id])
278
- if user.update(user_params)
279
- jsonapi_render json: user
280
- else
281
- jsonapi_render_errors json: user, status: :unprocessable_entity
282
- end
283
- end
284
-
285
- # DELETE /users/:id
286
- def destroy
287
- User.find(params[:id]).destroy
288
- head :no_content
321
+ # PATCH /users/:id
322
+ def update
323
+ user = User.find(params[:id])
324
+ if user.update(resource_params)
325
+ jsonapi_render json: user
326
+ else
327
+ jsonapi_render_errors json: user, status: :unprocessable_entity
289
328
  end
329
+ end
290
330
 
291
- private
292
-
293
- def user_params
294
- params.require(:data).require(:attributes).permit(:first_name, :last_name, :admin)
295
- end
331
+ # DELETE /users/:id
332
+ def destroy
333
+ User.find(params[:id]).destroy
334
+ head :no_content
335
+ end
296
336
  ```
297
337
 
298
338
  And:
@@ -324,12 +364,7 @@ class PostsController < BaseController
324
364
  private
325
365
 
326
366
  def post_params
327
- params.require(:data).require(:attributes).permit(:title, :body)
328
- .merge(user_id: author_params[:id])
329
- end
330
-
331
- def author_params
332
- params.require(:relationships).require(:author).require(:data).permit(:id)
367
+ resource_params.merge(user_id: relationship_params[:author])
333
368
  end
334
369
 
335
370
  def load_user
@@ -348,8 +383,6 @@ JSONAPI.configure do |config|
348
383
  config.json_key_format = :underscored_key
349
384
  config.route_format = :dasherized_route
350
385
 
351
- config.operations_processor = :active_record
352
-
353
386
  config.allow_include = true
354
387
  config.allow_sort = true
355
388
  config.allow_filter = true
@@ -387,7 +420,7 @@ Here's some examples of requests – based on those sample [controllers](#routes
387
420
  * [Relationships (identifier objects)](#relationships-identifier-objects)
388
421
  * [Nested resources](#nested-resources)
389
422
 
390
- #### Collection
423
+ #### Index
391
424
 
392
425
  Request:
393
426
 
@@ -457,7 +490,7 @@ Content-Type: application/vnd.api+json
457
490
  }
458
491
  ```
459
492
 
460
- #### Collection (options)
493
+ #### Index (options)
461
494
 
462
495
  Request:
463
496
 
@@ -542,7 +575,7 @@ Content-Type: application/vnd.api+json
542
575
  }
543
576
  ```
544
577
 
545
- #### Single record
578
+ #### Show
546
579
 
547
580
  Request:
548
581
 
@@ -582,7 +615,7 @@ Content-Type: application/vnd.api+json
582
615
  }
583
616
  ```
584
617
 
585
- #### Single record (options)
618
+ #### Show (options)
586
619
 
587
620
  Request:
588
621
 
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "jsonapi/utils"
3
+ require 'bundler/setup'
4
+ require 'jsonapi/utils'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "jsonapi/utils"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
data/lib/jsonapi/utils.rb CHANGED
@@ -1,12 +1,8 @@
1
-
2
1
  require 'jsonapi-resources'
3
2
  require 'jsonapi/utils/version'
4
3
  require 'jsonapi/utils/exceptions'
5
4
  require 'jsonapi/utils/request'
6
5
  require 'jsonapi/utils/response'
7
- require 'jsonapi/utils/support/filter/custom'
8
-
9
- JSONAPI::Resource.extend JSONAPI::Utils::Support::Filter::Custom
10
6
 
11
7
  module JSONAPI
12
8
  module Utils
@@ -1,87 +1,47 @@
1
- module JSONAPI::Utils
2
- module Request
3
- # Setup and check request before action gets actually evaluated.
4
- #
5
- # @api public
6
- def jsonapi_request_handling
7
- setup_request
8
- check_request
9
- end
10
-
11
- # Instantiate the request object.
12
- #
13
- # @return [JSONAPI::RequestParser]
14
- #
15
- # @api public
16
- def setup_request
17
- @request ||= JSONAPI::RequestParser.new(
18
- params,
19
- context: context,
20
- key_formatter: key_formatter,
21
- server_error_callbacks: (self.class.server_error_callbacks || [])
22
- )
23
- end
24
-
25
- # Render an error response if the parsed request got any error.
26
- #
27
- # @api public
28
- def check_request
29
- @request.errors.blank? || jsonapi_render_errors(json: @request)
30
- end
1
+ module JSONAPI
2
+ module Utils
3
+ module Request
4
+ def jsonapi_request_handling
5
+ setup_request
6
+ check_request
7
+ end
31
8
 
32
- # Override the JSONAPI::ActsAsResourceController#process_request method.
33
- #
34
- # It might be removed when the following line on JR is fixed:
35
- # https://github.com/cerebris/jsonapi-resources/blob/release-0-8/lib/jsonapi/acts_as_resource_controller.rb#L62
36
- #
37
- # @return [String]
38
- #
39
- # @api public
40
- def process_request
41
- process_operations
42
- render_results(@operation_results)
43
- rescue => e
44
- handle_exceptions(e)
45
- end
9
+ def setup_request
10
+ @request ||=
11
+ JSONAPI::RequestParser.new(
12
+ params.dup,
13
+ context: context,
14
+ key_formatter: key_formatter,
15
+ server_error_callbacks: (self.class.server_error_callbacks || [])
16
+ )
17
+ end
46
18
 
47
- # Helper to get params for the main resource.
48
- #
49
- # @return [Hash]
50
- #
51
- # @api public
52
- def resource_params
53
- build_params_for(:resource)
54
- end
19
+ def check_request
20
+ @request.errors.blank? || jsonapi_render_errors(json: @request)
21
+ end
55
22
 
56
- # Helper to get params for relationship params.
57
- #
58
- # @return [Hash]
59
- #
60
- # @api public
61
- def relationship_params
62
- build_params_for(:relationship)
63
- end
23
+ def resource_params
24
+ build_params_for(:resource)
25
+ end
64
26
 
65
- private
27
+ def relationship_params
28
+ build_params_for(:relationship)
29
+ end
66
30
 
67
- # Extract params from request and build a Hash with params
68
- # for either the main resource or relationships.
69
- #
70
- # @return [Hash]
71
- #
72
- # @api private
73
- def build_params_for(param_type)
74
- return {} if @request.operations.empty?
31
+ private
75
32
 
76
- keys = %i(attributes to_one to_many)
77
- operation = @request.operations.find { |e| e.options[:data].keys & keys == keys }
33
+ def build_params_for(param_type)
34
+ return {} if @request.operations.empty?
78
35
 
79
- if operation.nil?
80
- {}
81
- elsif param_type == :relationship
82
- operation.options[:data].values_at(:to_one, :to_many).compact.reduce(&:merge)
83
- else
84
- operation.options[:data][:attributes]
36
+ keys = %i(attributes to_one to_many)
37
+ operation = @request.operations.find { |e| e.options[:data].keys & keys == keys }
38
+ if operation.nil?
39
+ {}
40
+ elsif param_type == :relationship
41
+ operation.options[:data].values_at(:to_one, :to_many).compact.reduce(&:merge)
42
+ else
43
+ operation.options[:data][:attributes]
44
+ end
85
45
  end
86
46
  end
87
47
  end
@@ -1,14 +1,14 @@
1
- require 'jsonapi/utils/support/error'
2
- require 'jsonapi/utils/support/filter/default'
1
+ require 'jsonapi/utils/support/filter'
3
2
  require 'jsonapi/utils/support/pagination'
4
3
  require 'jsonapi/utils/support/sort'
4
+ require 'jsonapi/utils/support/error'
5
5
 
6
6
  module JSONAPI
7
7
  module Utils
8
8
  module Response
9
9
  module Support
10
10
  include ::JSONAPI::Utils::Support::Error
11
- include ::JSONAPI::Utils::Support::Filter::Default
11
+ include ::JSONAPI::Utils::Support::Filter
12
12
  include ::JSONAPI::Utils::Support::Pagination
13
13
  include ::JSONAPI::Utils::Support::Sort
14
14
 
@@ -19,9 +19,8 @@ module JSONAPI
19
19
  @_filter_params ||=
20
20
  case params[:filter]
21
21
  when Hash, ActionController::Parameters
22
- default_filters.each_with_object({}) do |field, hash|
23
- unformatted_field = @request.unformat_key(field)
24
- hash[unformatted_field] = params[:filter][field]
22
+ params[:filter].keys.each_with_object({}) do |resource, hash|
23
+ hash[resource] = params[:filter][resource]
25
24
  end
26
25
  end
27
26
  end
@@ -2,133 +2,64 @@ module JSONAPI
2
2
  module Utils
3
3
  module Support
4
4
  module Pagination
5
- # Apply proper pagination to the records.
6
- #
7
- # @param records [ActiveRecord::Relation, Array] collection of records
8
- # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
9
- #
10
- # @param options [Hash] JU's options
11
- # e.g.: { resource: V2::UserResource, count: 100 }
12
- #
13
- # @return [ActiveRecord::Relation, Array]
14
- #
15
- # @api public
16
5
  def apply_pagination(records, options = {})
17
6
  return records unless apply_pagination?(options)
18
- records.is_a?(Array) ? records[paginate_with(:range)] : paginate_with(:paginator).apply(records, nil)
19
- end
20
-
21
- # Mount pagination params for JSONAPI::ResourcesOperationResult.
22
- # It can also be used anywhere else as a helper method.
23
- #
24
- # @param records [ActiveRecord::Relation, Array] collection of records
25
- # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
26
- #
27
- # @param options [Hash] JU's options
28
- # e.g.: { resource: V2::UserResource, count: 100 }
29
- #
30
- # @return [Hash]
31
- # e.g.: {"first"=>{"number"=>1, "size"=>2}, "next"=>{"number"=>2, "size"=>2}, "last"=>{"number"=>2, "size"=>2}}
32
- #
33
- # @api public
34
- def pagination_params(records, options)
35
- return {} unless JSONAPI.configuration.top_level_links_include_pagination
36
- paginator.links_page_params(record_count: count_records(records, options))
37
- end
38
-
39
- private
40
7
 
41
- # Define the paginator object to be used in the response's pagination.
42
- #
43
- # @return [PagedPaginator, OffsetPaginator]
44
- #
45
- # @api private
46
- def paginator
47
- @paginator ||= paginator_klass.new(page_params)
48
- end
8
+ pagination = set_pagination
49
9
 
50
- # Returns the paginator class to be used in the response's pagination.
51
- #
52
- # @return [Paginator]
53
- #
54
- # @api private
55
- def paginator_klass
56
- "#{JSONAPI.configuration.default_paginator}_paginator".classify.constantize
10
+ records =
11
+ if records.is_a?(Array)
12
+ records[pagination[:range]]
13
+ else
14
+ pagination[:paginator].apply(records, nil)
15
+ end
57
16
  end
58
17
 
59
- # Check whether pagination should be applied to the response.
60
- #
61
- # @return [Boolean]
62
- #
63
- # @api private
64
18
  def apply_pagination?(options)
65
19
  JSONAPI.configuration.default_paginator != :none &&
66
20
  (options[:paginate].nil? || options[:paginate])
67
21
  end
68
22
 
69
- # Creates an instance of ActionController::Parameters for page params.
70
- #
71
- # @return [ActionController::Parameters]
72
- #
73
- # @api private
74
- def page_params
75
- @page_params ||= begin
76
- page = @request.params.to_unsafe_hash['page'] || {}
77
- ActionController::Parameters.new(page)
23
+ def pagination_params(records, options)
24
+ @paginator ||= paginator(params)
25
+ if @paginator && JSONAPI.configuration.top_level_links_include_pagination
26
+ options = {}
27
+ @paginator.class.requires_record_count &&
28
+ options[:record_count] = count_records(records, options)
29
+ @paginator.links_page_params(options)
30
+ else
31
+ {}
78
32
  end
79
33
  end
80
34
 
81
- # Define the paginator or range according to the pagination strategy.
82
- #
83
- # @param kind [Symbol] pagination object's kind
84
- # e.g.: :paginator or :range
85
- #
86
- # @return [PagedPaginator, OffsetPaginator, Range]
87
- # e.g.: #<PagedPaginator:0x00561ed06dc5a0 @number=1, @size=2>
88
- # 0..9
89
- #
90
- # @api private
91
- def paginate_with(kind)
92
- @pagination ||=
93
- case kind
94
- when :paginator then paginator
95
- when :range then pagination_range
35
+ def paginator(params)
36
+ page_params = ActionController::Parameters.new(params[:page] || {})
37
+
38
+ @paginator ||=
39
+ if JSONAPI.configuration.default_paginator == :paged
40
+ PagedPaginator.new(page_params)
41
+ elsif JSONAPI.configuration.default_paginator == :offset
42
+ OffsetPaginator.new(page_params)
96
43
  end
97
44
  end
98
45
 
99
- # Define a pagination range for objects which quack like Arrays.
100
- #
101
- # @return [Range]
102
- # e.g.: 0..9
103
- #
104
- # @api private
105
- def pagination_range
106
- case JSONAPI.configuration.default_paginator
107
- when :paged
46
+ def set_pagination
47
+ page_params = ActionController::Parameters.new(@request.params[:page] || {})
48
+ if JSONAPI.configuration.default_paginator == :paged
49
+ @_paginator ||= PagedPaginator.new(page_params)
108
50
  number = page_params['number'].to_i.nonzero? || 1
109
51
  size = page_params['size'].to_i.nonzero? || JSONAPI.configuration.default_page_size
110
- (number - 1) * size..number * size - 1
111
- when :offset
52
+ { paginator: @_paginator, range: (number - 1) * size..number * size - 1 }
53
+ elsif JSONAPI.configuration.default_paginator == :offset
54
+ @_paginator ||= OffsetPaginator.new(page_params)
112
55
  offset = page_params['offset'].to_i.nonzero? || 0
113
56
  limit = page_params['limit'].to_i.nonzero? || JSONAPI.configuration.default_page_size
114
- offset..offset + limit - 1
57
+ { paginator: @_paginator, range: offset..offset + limit - 1 }
115
58
  else
116
- paginator.pagination_range(page_params)
59
+ {}
117
60
  end
118
61
  end
119
62
 
120
- # Count records in order to build a proper pagination and to fill up the "record_count" response's member.
121
- #
122
- # @param records [ActiveRecord::Relation, Array] collection of records
123
- # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
124
- #
125
- # @param options [Hash] JU's options
126
- # e.g.: { resource: V2::UserResource, count: 100 }
127
- #
128
- # @return [Integer]
129
- # e.g.: 42
130
- #
131
- # @api private
132
63
  def count_records(records, options)
133
64
  if options[:count].present?
134
65
  options[:count]
@@ -1,53 +1,36 @@
1
- module JSONAPI::Utils::Support
2
- module Sort
3
- # Apply sort on result set (ascending by default).
4
- # e.g.: User.order(:first_name)
5
- #
6
- # @param records [ActiveRecord::Relation, Array] collection of records
7
- # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
8
- #
9
- # @return [ActiveRecord::Relation, Array]
10
- #
11
- # @api public
12
- def apply_sort(records)
13
- return records unless params[:sort].present?
1
+ module JSONAPI
2
+ module Utils
3
+ module Support
4
+ module Sort
5
+ def apply_sort(records)
6
+ return records unless params[:sort].present?
14
7
 
15
- if records.is_a?(Array)
16
- records.sort { |a, b| comp = 0; eval(sort_criteria) }
17
- elsif records.respond_to?(:order)
18
- records.order(sort_params)
19
- end
20
- end
8
+ if records.is_a?(Array)
9
+ records.sort { |a, b| comp = 0; eval(sort_criteria) }
10
+ elsif records.respond_to?(:order)
11
+ records.order(sort_params)
12
+ end
13
+ end
21
14
 
22
- # Build the criteria to be evaluated wthen applying sort
23
- # on Array of Hashes (ascending by default).
24
- #
25
- # @return [String]
26
- #
27
- # @api public
28
- def sort_criteria
29
- @sort_criteria ||=
30
- sort_params.reduce('') do |sum, (key, value)|
31
- comparables = ["a[:#{key}]", "b[:#{key}]"]
32
- comparables.reverse! if value == :desc
33
- sum + "comp = comp == 0 ? #{comparables.join(' <=> ')} : comp; "
15
+ def sort_criteria
16
+ @sort_criteria ||=
17
+ sort_params.reduce('') do |sum, (key, value)|
18
+ comparables = ["a[:#{key}]", "b[:#{key}]"]
19
+ comparables.reverse! if value == :desc
20
+ sum + "comp = comp == 0 ? #{comparables.join(' <=> ')} : comp; "
21
+ end
34
22
  end
35
- end
36
23
 
37
- # Build a Hash with the sort criteria.
38
- #
39
- # @return [Hash, NilClass]
40
- #
41
- # @api public
42
- def sort_params
43
- @_sort_params ||=
44
- if params[:sort].present?
45
- params[:sort].split(',').each_with_object({}) do |field, hash|
46
- unformatted_field = @request.unformat_key(field)
47
- desc, field = unformatted_field.to_s.match(/^([-_])?(\w+)$/i)[1..2]
48
- hash[field] = desc.present? ? :desc : :asc
49
- end
24
+ def sort_params
25
+ @_sort_params ||=
26
+ if params[:sort].present?
27
+ params[:sort].split(',').each_with_object({}) do |criteria, hash|
28
+ order, field = criteria.match(/(\-?)(\w+)/i)[1..2]
29
+ hash[field] = order == '-' ? :desc : :asc
30
+ end
31
+ end
50
32
  end
33
+ end
51
34
  end
52
35
  end
53
36
  end
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Utils
3
- VERSION = '0.4.9'
3
+ VERSION = '0.5.0.beta1'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.5.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Guedes
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-03-12 00:00:00.000000000 Z
12
+ date: 2016-08-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: jsonapi-resources
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 0.8.0
20
+ version: 0.8.0.beta1
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 0.8.0
27
+ version: 0.8.0.beta1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: bundler
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -174,8 +174,6 @@ files:
174
174
  - lib/jsonapi/utils/response/support.rb
175
175
  - lib/jsonapi/utils/support/error.rb
176
176
  - lib/jsonapi/utils/support/filter.rb
177
- - lib/jsonapi/utils/support/filter/custom.rb
178
- - lib/jsonapi/utils/support/filter/default.rb
179
177
  - lib/jsonapi/utils/support/pagination.rb
180
178
  - lib/jsonapi/utils/support/sort.rb
181
179
  - lib/jsonapi/utils/version.rb
@@ -194,14 +192,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
192
  version: '0'
195
193
  required_rubygems_version: !ruby/object:Gem::Requirement
196
194
  requirements:
197
- - - ">="
195
+ - - ">"
198
196
  - !ruby/object:Gem::Version
199
- version: '0'
197
+ version: 1.3.1
200
198
  requirements: []
201
199
  rubyforge_project:
202
- rubygems_version: 2.6.7
200
+ rubygems_version: 2.6.2
203
201
  signing_key:
204
202
  specification_version: 4
205
203
  summary: JSON::Utils is a simple way to get a full-featured JSON API serialization
206
204
  for your controller's responses.
207
205
  test_files: []
206
+ has_rdoc:
@@ -1,18 +0,0 @@
1
- module JSONAPI::Utils::Support::Filter
2
- module Custom
3
- def _custom_filters
4
- @_allowed_custom_filters || []
5
- end
6
-
7
- def custom_filters(*attrs)
8
- attrs.each { |attr| custom_filter(attr) }
9
- end
10
-
11
- def custom_filter(attr)
12
- attr = attr.to_sym
13
- @_allowed_filters[attr] = {}
14
- @_allowed_custom_filters ||= []
15
- @_allowed_custom_filters |= [attr]
16
- end
17
- end
18
- end
@@ -1,66 +0,0 @@
1
- module JSONAPI::Utils::Support::Filter
2
- module Default
3
- # Apply default equality filters.
4
- # e.g.: User.where(name: 'Foobar')
5
- #
6
- # @param records [ActiveRecord::Relation, Array] collection of records
7
- # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
8
- #
9
- # @param options [Hash] JU's options
10
- # e.g.: { filter: false, paginate: false }
11
- #
12
- # @return [ActiveRecord::Relation, Array]
13
- #
14
- # @api public
15
- def apply_filter(records, options = {})
16
- if apply_filter?(records, options)
17
- records.where(filter_params)
18
- else
19
- records
20
- end
21
- end
22
-
23
- # Check whether default filters should be applied.
24
- #
25
- # @param records [ActiveRecord::Relation, Array] collection of records
26
- # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
27
- #
28
- # @param options [Hash] JU's options
29
- # e.g.: { filter: false, paginate: false }
30
- #
31
- # @return [Boolean]
32
- #
33
- # @api public
34
- def apply_filter?(records, options = {})
35
- params[:filter].present? && records.respond_to?(:where) &&
36
- (options[:filter].nil? || options[:filter])
37
- end
38
-
39
- # Build a Hash with the default filters.
40
- #
41
- # @return [Hash, NilClass]
42
- #
43
- # @api public
44
- def filter_params
45
- @_filter_params ||=
46
- case params[:filter]
47
- when Hash, ActionController::Parameters
48
- default_filters.each_with_object({}) do |field, hash|
49
- unformatted_field = @request.unformat_key(field)
50
- hash[unformatted_field] = params[:filter][field]
51
- end
52
- end
53
- end
54
-
55
- private
56
-
57
- # Take all allowed filters and remove the custom ones.
58
- #
59
- # @return [Array]
60
- #
61
- # @api private
62
- def default_filters
63
- params[:filter].keys.map(&:to_sym) - @request.resource_klass._custom_filters
64
- end
65
- end
66
- end