jsonapi-utils 0.7.2 → 0.7.3

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
- SHA1:
3
- metadata.gz: 81b9858b8125f047d7c6b26ed950d98072c6af8b
4
- data.tar.gz: b7436b63bbc441f6592f6ada45cedace0633fa9c
2
+ SHA256:
3
+ metadata.gz: 56b5970b70c6944e7c5c536f0b92c2bd8d2503d5447886862b72bfabcf85e943
4
+ data.tar.gz: c07bf056d10c8550c511bdd180dec8393858e45a5de37450ef323367bcc243aa
5
5
  SHA512:
6
- metadata.gz: 1285cd935d1acab08e5f950290c2eabb744420aeac9312877e856ee1a9a16e0dace61d6797b60ed8b48994e67860fbc2f299c0a2169a48ef1939c9a52565425c
7
- data.tar.gz: 9ab8279a639f27b412c8b7aec1857f4c4db9e7f928487950b6118afe6c30c5ecd40b9b97e2035f706e9eea4557d6e5772776dff848ddc424c382e676fc6df999
6
+ metadata.gz: 4aa949f97e9e0795dc6686d393767c4a1ad6c9084815a4f1aa10c0f912fc5901192b194204510936cb55a8136ef3467534aaa76132f334dd7f9127920281bc32
7
+ data.tar.gz: 26e1483f33628891ab311e6e9e3b71e88de5c3e5a9da4d3ae425ae62ea7efd7496acf0a99707de58db4a04d4b3bf33e911d4e11ec8996ba9e9f519e7ffd74c3b
data/README.md CHANGED
@@ -54,7 +54,7 @@ end
54
54
  Support:
55
55
 
56
56
  * Ruby 1.9+ with Rails 4
57
- * Ruby 2.3+ with Rails 5
57
+ * Ruby 2.4+ with Rails 5
58
58
 
59
59
  For Rails 4 add this to your application's Gemfile:
60
60
 
@@ -62,10 +62,10 @@ For Rails 4 add this to your application's Gemfile:
62
62
  gem 'jsonapi-utils', '~> 0.4.9'
63
63
  ```
64
64
 
65
- For Rails 5:
65
+ For Rails 5+:
66
66
 
67
67
  ```ruby
68
- gem 'jsonapi-utils', '~> 0.7.2'
68
+ gem 'jsonapi-utils', '~> 0.7.3'
69
69
  ```
70
70
 
71
71
  And then execute:
@@ -225,12 +225,12 @@ class CustomPaginator < JSONAPI::Paginator
225
225
  end
226
226
  ```
227
227
 
228
- And then it can be either set at the resource class level (e.g. UserResource.paginator :custom_paginator) or via config initializer:
228
+ And then it can be either set at the resource class level (e.g. UserResource.paginator :custom) or via config initializer:
229
229
 
230
230
  ```ruby
231
231
  # config/initializers/jsonapi_resources.rb
232
232
  JSONAPI.configure do |config|
233
- config.default_paginator = :custom_paginator
233
+ config.default_paginator = :custom
234
234
  end
235
235
  ```
236
236
 
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rspec' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
@@ -6,6 +6,11 @@ module JSONAPI::Utils
6
6
  def jsonapi_request_handling
7
7
  setup_request
8
8
  check_request
9
+ rescue JSONAPI::Exceptions::InvalidResource,
10
+ JSONAPI::Exceptions::InvalidField,
11
+ JSONAPI::Exceptions::InvalidInclude,
12
+ JSONAPI::Exceptions::InvalidSortCriteria => err
13
+ jsonapi_render_errors(json: err)
9
14
  end
10
15
 
11
16
  # Instantiate the request object.
@@ -15,6 +15,11 @@ module JSONAPI
15
15
  # @option options [JSONAPI::Resource] resource: it tells the formatter which resource
16
16
  # class to be used rather than use an infered one (default behaviour)
17
17
  #
18
+ # @option options [JSONAPI::Resource] source: it tells the formatter that this response is from a related resource
19
+ # and the result should be interpreted as a related resources response
20
+ #
21
+ # @option options [String, Symbol] relationship_type: it tells that the formatter which relationship the data is from
22
+ #
18
23
  # @option options [ActiveRecord::Base] model: ActiveRecord model class to be instantiated
19
24
  # when a Hash or Array of Hashes is passed as the "object" argument
20
25
  #
@@ -27,7 +32,7 @@ module JSONAPI
27
32
  # @api public
28
33
  def jsonapi_format(object, options = {})
29
34
  if object.is_a?(Hash)
30
- hash = object.with_indifferent_access
35
+ hash = object.with_indifferent_access
31
36
  object = hash_to_active_record(hash[:data], options[:model])
32
37
  end
33
38
  fix_custom_request_options(object)
@@ -51,7 +56,7 @@ module JSONAPI
51
56
  # @api public
52
57
  def jsonapi_format_errors(object)
53
58
  if active_record_obj?(object)
54
- object = JSONAPI::Utils::Exceptions::ActiveRecord.new(object, @request.resource_klass, context)
59
+ object = JSONAPI::Utils::Exceptions::ActiveRecord.new(object, @request.resource_klass, context)
55
60
  end
56
61
  errors = object.respond_to?(:errors) ? object.errors : object
57
62
  JSONAPI::Utils::Support::Error.sanitize(errors).uniq
@@ -77,12 +82,15 @@ module JSONAPI
77
82
  # Build the full response document.
78
83
  #
79
84
  # @param object [ActiveRecord::Base, ActiveRecord::Relation, Hash, Array<Hash>]
80
- # Object to be formatted into JSON
81
- # e.g.: User.first, User.all, { data: { id: 1, first_name: 'Tiago' } },
82
- # [{ data: { id: 1, first_name: 'Tiago' } }]
85
+ # Object to be formatted into JSON.
83
86
  #
84
- # @option options [JSONAPI::Resource] resource: it tells the builder which resource
85
- # class to be used rather than use an infered one (default behaviour)
87
+ # @option options [JSONAPI::Resource] :resource which resource class to be used
88
+ # rather than using the default one (inferred)
89
+ #
90
+ # @option options [ActiveRecord::Base, JSONAPI::Resource] :source source of related resource,
91
+ # the result should be interpreted as a related resources response
92
+ #
93
+ # @option options [String, Symbol] :relationship which relationship the data is from
86
94
  #
87
95
  # @option options [Integer] count: if it's rendering a collection of resources, the default
88
96
  # gem's counting method can be bypassed by the use of this options. It's shows then the total
@@ -95,8 +103,7 @@ module JSONAPI
95
103
  results = JSONAPI::OperationResults.new
96
104
 
97
105
  if object.respond_to?(:to_ary)
98
- records = build_collection(object, options)
99
- results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, records, result_options(object, options)))
106
+ results.add_result(build_collection_result(object, options))
100
107
  else
101
108
  record = turn_into_resource(object, options)
102
109
  results.add_result(JSONAPI::ResourceOperationResult.new(:ok, record))
@@ -105,6 +112,68 @@ module JSONAPI
105
112
  @_response_document = create_response_document(results)
106
113
  end
107
114
 
115
+ # Build the result operation object for collection actions.
116
+ #
117
+ # @param object [ActiveRecord::Relation, Array<Hash>]
118
+ # Object to be formatted into JSON.
119
+ #
120
+ # @option options [JSONAPI::Resource] :resource which resource class to be used
121
+ # rather than using the default one (inferred)
122
+ #
123
+ # @option options [ActiveRecord::Base, JSONAPI::Resource] :source parent model/resource
124
+ # of the related resource
125
+ #
126
+ # @option options [String, Symbol] :relationship which relationship the data is from
127
+ #
128
+ # @option options [Integer] count: if it's rendering a collection of resources, the default
129
+ # gem's counting method can be bypassed by the use of this options. It's shows then the total
130
+ # records resulting from that request and also calculates the pagination.
131
+ #
132
+ # @return [JSONAPI::ResourcesOperationResult, JSONAPI::RelatedResourcesOperationResult]
133
+ #
134
+ # @api private
135
+ def build_collection_result(object, options)
136
+ records = build_collection(object, options)
137
+ result_options = result_options(object, options)
138
+
139
+ if related_resource_operation?(options)
140
+ source_resource = turn_source_into_resource(options[:source])
141
+ relationship_type = get_source_relationship(options)
142
+
143
+ JSONAPI::RelatedResourcesOperationResult.new(
144
+ :ok,
145
+ source_resource,
146
+ relationship_type,
147
+ records,
148
+ result_options
149
+ )
150
+ else
151
+ JSONAPI::ResourcesOperationResult.new(:ok, records, result_options)
152
+ end
153
+ end
154
+
155
+ # Is this a request for related resources?
156
+ #
157
+ # In order to answer that it needs to check for some {options}
158
+ # controller params like {params[:source]} and {params[:relationship]}.
159
+ #
160
+ # @option options [Boolean] :related when true, jsonapi-utils infers the parent and
161
+ # related resources from controller's {params} values.
162
+ #
163
+ # @option options [ActiveRecord::Base, JSONAPI::Resource] :source parent model/resource
164
+ # of the related resource
165
+ #
166
+ # @option options [String, Symbol] :relationship which relationship the data is from
167
+ #
168
+ # @return [Boolean]
169
+ #
170
+ # @api private
171
+ def related_resource_operation?(options)
172
+ (options[:related] || options[:source].present?) &&
173
+ params[:source].present? &&
174
+ params[:relationship].present?
175
+ end
176
+
108
177
  # Apply a proper action setup for custom requests/actions.
109
178
  #
110
179
  # @note The setup_(index|show)_action comes from JSONAPI::Resources' API.
@@ -134,10 +203,9 @@ module JSONAPI
134
203
  # Objects to be instantiated as JSONAPI::Resource ones.
135
204
  # e.g.: User.all, [{ data: { id: 1, first_name: 'Tiago' } }]
136
205
  #
137
- # @option options [JSONAPI::Resource] resource: it tells the buider which resource
138
- # class to be used rather than use an infered one (default behaviour)
206
+ # @option options [JSONAPI::Resource] :resource it resource class to be used rather than default one (infered)
139
207
  #
140
- # @option options [Integer] count: if it's rendering a collection of resources, the default
208
+ # @option options [Integer] :count if it's rendering a collection of resources, the default
141
209
  # gem's counting method can be bypassed by the use of this options. It's shows then the total
142
210
  # records resulting from that request and also calculates the pagination.
143
211
  #
@@ -171,6 +239,30 @@ module JSONAPI
171
239
  end
172
240
  end
173
241
 
242
+ # Get JSONAPI::Resource for source object
243
+ #
244
+ # @param record [ActiveRecord::Base, JSONAPI::Resource]
245
+ #
246
+ # @return [JSONAPI::Resource]
247
+ #
248
+ # @api private
249
+ def turn_source_into_resource(record)
250
+ return record if record.kind_of?(JSONAPI::Resource)
251
+ @request.source_klass.new(record, context)
252
+ end
253
+
254
+ # Get relationship type of source object
255
+ #
256
+ # @option options [Symbol] relationship: it tells which relationship
257
+ # to be used rather than use an infered one (default behaviour)
258
+ #
259
+ # @return [Symbol]
260
+ #
261
+ # @api private
262
+ def get_source_relationship(options)
263
+ options[:relationship]&.to_sym || @request.resource_klass._type
264
+ end
265
+
174
266
  # Apply some result options like pagination params and record count to collection responses.
175
267
  #
176
268
  # @param records [ActiveRecord::Relation, Hash, Array<Hash>]
@@ -186,8 +278,7 @@ module JSONAPI
186
278
  # @api private
187
279
  def result_options(records, options)
188
280
  {}.tap do |data|
189
- if JSONAPI.configuration.default_paginator != :none &&
190
- JSONAPI.configuration.top_level_links_include_pagination
281
+ if include_pagination_links?
191
282
  data[:pagination_params] = pagination_params(records, options)
192
283
  end
193
284
 
@@ -195,7 +286,7 @@ module JSONAPI
195
286
  data[:record_count] = record_count_for(records, options)
196
287
  end
197
288
 
198
- if JSONAPI.configuration.top_level_meta_include_page_count
289
+ if include_page_count?
199
290
  data[:page_count] = page_count_for(data[:record_count])
200
291
  end
201
292
  end
@@ -14,6 +14,11 @@ module JSONAPI
14
14
  #
15
15
  # @option options [JSONAPI::Resource] resource: it tells the render which resource
16
16
  # class to be used rather than use an infered one (default behaviour)
17
+ #
18
+ # @option options [JSONAPI::Resource] source_resource: it tells the render that this response is from a related resource
19
+ # and the result should be interpreted as a related resources response
20
+ #
21
+ # @option options [String, Symbol] relationship_type: it tells that the render which relationship the data is from
17
22
  #
18
23
  # @option options [ActiveRecord::Base] model: ActiveRecord model class to be instantiated
19
24
  # when a Hash or Array of Hashes is passed to the "json" key argument
@@ -4,20 +4,40 @@ module JSONAPI
4
4
  module Pagination
5
5
  RecordCountError = Class.new(ArgumentError)
6
6
 
7
+ # Check whether pagination links should be included.
8
+ #
9
+ # @api public
10
+ # @return [Boolean]
11
+ def include_pagination_links?
12
+ JSONAPI.configuration.default_paginator != :none &&
13
+ JSONAPI.configuration.top_level_links_include_pagination
14
+ end
15
+
16
+ # Check whether pagination's page count should be included
17
+ # on the "meta" key.
18
+ #
19
+ # @api public
20
+ # @return [Boolean]
21
+ def include_page_count?
22
+ JSONAPI.configuration.top_level_meta_include_page_count
23
+ end
24
+
7
25
  # Apply proper pagination to the records.
8
26
  #
9
27
  # @param records [ActiveRecord::Relation, Array] collection of records
10
28
  # e.g.: User.all or [{ id: 1, name: 'Tiago' }, { id: 2, name: 'Doug' }]
11
29
  #
12
- # @param options [Hash] JU's options
30
+ # @param options [Hash] JSONAPI::Utils' options
13
31
  # e.g.: { resource: V2::UserResource, count: 100 }
14
32
  #
15
33
  # @return [ActiveRecord::Relation, Array]
16
34
  #
17
35
  # @api public
18
36
  def apply_pagination(records, options = {})
19
- return records unless apply_pagination?(options)
20
- records.is_a?(Array) ? records[paginate_with(:range)] : paginate_with(:paginator).apply(records, nil)
37
+ if !apply_pagination?(options) then records
38
+ elsif records.is_a?(Array) then records[paginate_with(:range)]
39
+ else paginate_with(:paginator).apply(records, nil)
40
+ end
21
41
  end
22
42
 
23
43
  # Mount pagination params for JSONAPI::ResourcesOperationResult.
@@ -32,9 +52,10 @@ module JSONAPI
32
52
  # @return [Hash]
33
53
  # e.g.: {"first"=>{"number"=>1, "size"=>2}, "next"=>{"number"=>2, "size"=>2}, "last"=>{"number"=>2, "size"=>2}}
34
54
  #
55
+ #
35
56
  # @api public
36
57
  def pagination_params(records, options)
37
- return {} unless JSONAPI.configuration.top_level_links_include_pagination
58
+ return {} unless include_pagination_links?
38
59
  paginator.links_page_params(record_count: record_count_for(records, options))
39
60
  end
40
61
 
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Utils
3
- VERSION = '0.7.2'.freeze
3
+ VERSION = '0.7.3'.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.7.2
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Guedes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-04-25 00:00:00.000000000 Z
12
+ date: 2020-04-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: jsonapi-resources
@@ -17,98 +17,122 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 0.9.0
20
+ version: 0.9.11
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.9.0
27
+ version: 0.9.11
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: bundler
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '1.10'
34
+ version: '1.14'
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '1.14'
35
38
  type: :development
36
39
  prerelease: false
37
40
  version_requirements: !ruby/object:Gem::Requirement
38
41
  requirements:
39
42
  - - "~>"
40
43
  - !ruby/object:Gem::Version
41
- version: '1.10'
44
+ version: '1.14'
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '1.14'
42
48
  - !ruby/object:Gem::Dependency
43
49
  name: rake
44
50
  requirement: !ruby/object:Gem::Requirement
45
51
  requirements:
46
52
  - - "~>"
47
53
  - !ruby/object:Gem::Version
48
- version: '10.0'
54
+ version: '12.3'
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 12.3.3
49
58
  type: :development
50
59
  prerelease: false
51
60
  version_requirements: !ruby/object:Gem::Requirement
52
61
  requirements:
53
62
  - - "~>"
54
63
  - !ruby/object:Gem::Version
55
- version: '10.0'
64
+ version: '12.3'
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 12.3.3
56
68
  - !ruby/object:Gem::Dependency
57
69
  name: rails
58
70
  requirement: !ruby/object:Gem::Requirement
59
71
  requirements:
60
72
  - - "~>"
61
73
  - !ruby/object:Gem::Version
62
- version: '5.1'
74
+ version: '5.2'
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 5.2.4
63
78
  type: :development
64
79
  prerelease: false
65
80
  version_requirements: !ruby/object:Gem::Requirement
66
81
  requirements:
67
82
  - - "~>"
68
83
  - !ruby/object:Gem::Version
69
- version: '5.1'
84
+ version: '5.2'
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 5.2.4
70
88
  - !ruby/object:Gem::Dependency
71
89
  name: sqlite3
72
90
  requirement: !ruby/object:Gem::Requirement
73
91
  requirements:
74
- - - ">="
92
+ - - "~>"
75
93
  - !ruby/object:Gem::Version
76
- version: '0'
94
+ version: '1.4'
77
95
  type: :development
78
96
  prerelease: false
79
97
  version_requirements: !ruby/object:Gem::Requirement
80
98
  requirements:
81
- - - ">="
99
+ - - "~>"
82
100
  - !ruby/object:Gem::Version
83
- version: '0'
101
+ version: '1.4'
84
102
  - !ruby/object:Gem::Dependency
85
103
  name: rspec-rails
86
104
  requirement: !ruby/object:Gem::Requirement
87
105
  requirements:
88
106
  - - "~>"
89
107
  - !ruby/object:Gem::Version
90
- version: '3.1'
108
+ version: '3.9'
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: 3.9.0
91
112
  type: :development
92
113
  prerelease: false
93
114
  version_requirements: !ruby/object:Gem::Requirement
94
115
  requirements:
95
116
  - - "~>"
96
117
  - !ruby/object:Gem::Version
97
- version: '3.1'
118
+ version: '3.9'
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: 3.9.0
98
122
  - !ruby/object:Gem::Dependency
99
- name: factory_girl
123
+ name: factory_bot
100
124
  requirement: !ruby/object:Gem::Requirement
101
125
  requirements:
102
126
  - - "~>"
103
127
  - !ruby/object:Gem::Version
104
- version: '4.8'
128
+ version: '5.1'
105
129
  type: :development
106
130
  prerelease: false
107
131
  version_requirements: !ruby/object:Gem::Requirement
108
132
  requirements:
109
133
  - - "~>"
110
134
  - !ruby/object:Gem::Version
111
- version: '4.8'
135
+ version: '5.1'
112
136
  - !ruby/object:Gem::Dependency
113
137
  name: smart_rspec
114
138
  requirement: !ruby/object:Gem::Requirement
@@ -129,28 +153,40 @@ dependencies:
129
153
  requirements:
130
154
  - - "~>"
131
155
  - !ruby/object:Gem::Version
132
- version: 0.10.3
156
+ version: '0.12'
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: 0.12.2
133
160
  type: :development
134
161
  prerelease: false
135
162
  version_requirements: !ruby/object:Gem::Requirement
136
163
  requirements:
137
164
  - - "~>"
138
165
  - !ruby/object:Gem::Version
139
- version: 0.10.3
166
+ version: '0.12'
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: 0.12.2
140
170
  - !ruby/object:Gem::Dependency
141
171
  name: pry-byebug
142
172
  requirement: !ruby/object:Gem::Requirement
143
173
  requirements:
174
+ - - "~>"
175
+ - !ruby/object:Gem::Version
176
+ version: '3.7'
144
177
  - - ">="
145
178
  - !ruby/object:Gem::Version
146
- version: '0'
179
+ version: 3.7.0
147
180
  type: :development
148
181
  prerelease: false
149
182
  version_requirements: !ruby/object:Gem::Requirement
150
183
  requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '3.7'
151
187
  - - ">="
152
188
  - !ruby/object:Gem::Version
153
- version: '0'
189
+ version: 3.7.0
154
190
  description: Build JSON API-compliant APIs on Rails with no (or less) learning curve.
155
191
  email:
156
192
  - tiagopog@gmail.com
@@ -163,6 +199,7 @@ files:
163
199
  - LICENSE.txt
164
200
  - README.md
165
201
  - bin/console
202
+ - bin/rspec
166
203
  - bin/setup
167
204
  - lib/jsonapi/utils.rb
168
205
  - lib/jsonapi/utils/exceptions.rb
@@ -199,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
236
  version: '0'
200
237
  requirements: []
201
238
  rubyforge_project:
202
- rubygems_version: 2.5.2
239
+ rubygems_version: 2.7.7
203
240
  signing_key:
204
241
  specification_version: 4
205
242
  summary: JSON::Utils is a simple way to get a full-featured JSON API on your Rails