jsonapi-utils 0.4.9 → 0.5.0.beta1

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