jsonapi-utils 0.4.1 → 0.4.2

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: 4adff6c61b1c3f166099b6819c3de30bf3b3199d
4
- data.tar.gz: c9f896c24d1b6d4efce89ec9807596e377f46790
3
+ metadata.gz: d6eff0a7e2d11caccf5abf5a536e44169a753848
4
+ data.tar.gz: 28548fd3c87c86c5812af6b98ab7211f85161cd0
5
5
  SHA512:
6
- metadata.gz: 8904573999d64b34e6969529fbb9afeb50b3e7b6e5b04abeea63eaae7384527d80eddd3d039ab007f2c83bebb9e67e4322897d069bea38388d5b08f65833a9b1
7
- data.tar.gz: 08fb3c7497a3fb367eafb2ae02c95ef946675d24af58a588da11cd525655559d062e2e17efb69e97b9dd21fd543713c68a4f91355c9bbdc7702f88c34643f07e
6
+ metadata.gz: b25decbe1f936d4f47699941abbc6967f52d390bd83f760a975cc2eca02004205c908d64de1be152bd692969a9f4233ff0f4269f7c3339fbd1aeb35c0df7bad3
7
+ data.tar.gz: 7ed12c4c431e2d4693e28e00b0cfe617dc17bb8088dd75946b04dc278d308227f0405e21be22b8218c7448a0e7d2f2d8b52b25da4ae8bede7431c5cb70ea993b
@@ -21,13 +21,9 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_development_dependency 'bundler', '~> 1.10'
23
23
  spec.add_development_dependency 'rake', '~> 10.0'
24
- spec.add_development_dependency 'rspec'
25
24
  spec.add_development_dependency 'rspec-rails'
26
- spec.add_development_dependency 'smart_rspec'
27
- spec.add_development_dependency 'pry'
28
25
  spec.add_development_dependency 'sqlite3'
29
26
  spec.add_development_dependency 'factory_girl', '~> 4.5'
30
27
  spec.add_development_dependency 'jsonapi-resources', '~> 0.7.0'
31
-
32
- spec.add_dependency 'rails', '>= 4.0'
28
+ spec.add_development_dependency 'rails', '>= 4.0'
33
29
  end
data/lib/jsonapi/utils.rb CHANGED
@@ -41,9 +41,9 @@ module JSONAPI
41
41
  jsonapi_render_errors(::JSONAPI::Utils::Exceptions::BadRequest.new)
42
42
  end
43
43
 
44
- def jsonapi_render_not_found
44
+ def jsonapi_render_not_found(exception)
45
45
  setup_request
46
- id = extract_ids(@request.params)
46
+ id = exception.message.match(/=(\d+)/)[1]
47
47
  jsonapi_render_errors(JSONAPI::Exceptions::RecordNotFound.new(id))
48
48
  end
49
49
 
@@ -59,11 +59,11 @@ module JSONAPI
59
59
 
60
60
  if records.respond_to?(:to_ary)
61
61
  records = fix_when_hash(records, options) if needs_to_be_fixed?(records)
62
- @resources = build_collection(records, options)
63
- results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, @resources, result_options(options)))
62
+ @_records = build_collection(records, options)
63
+ results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, @_records, result_options(records, options)))
64
64
  else
65
- @resource = turn_into_resource(records, options)
66
- results.add_result(JSONAPI::ResourceOperationResult.new(:ok, @resource))
65
+ @_record = turn_into_resource(records, options)
66
+ results.add_result(JSONAPI::ResourceOperationResult.new(:ok, @_record))
67
67
  end
68
68
 
69
69
  create_response_document(results).contents
@@ -71,11 +71,6 @@ module JSONAPI
71
71
 
72
72
  private
73
73
 
74
- def extract_ids(hash)
75
- ids = hash.keys.select { |e| e =~ /id$/i }.map { |e| hash[e] }
76
- ids.first rescue '(id not identified)'
77
- end
78
-
79
74
  def fix_request_options(params, records)
80
75
  return if request.method !~ /get/i ||
81
76
  params.nil? ||
@@ -88,26 +83,25 @@ module JSONAPI
88
83
  records.is_a?(Array) && records.all? { |e| e.is_a?(Hash) }
89
84
  end
90
85
 
91
- def result_options(options)
92
- hash = {}
93
-
94
- if JSONAPI.configuration.top_level_links_include_pagination
95
- hash[:pagination_params] = pagination_params(options)
96
- end
86
+ def result_options(records, options)
87
+ {}.tap do |data|
88
+ if JSONAPI.configuration.default_paginator != :none &&
89
+ JSONAPI.configuration.top_level_links_include_pagination
90
+ data[:pagination_params] = pagination_params(records, options)
91
+ end
97
92
 
98
- if JSONAPI.configuration.top_level_meta_include_record_count
99
- hash[:record_count] = count_records(@resources, options)
93
+ if JSONAPI.configuration.top_level_meta_include_record_count
94
+ data[:record_count] = count_records(records, options)
95
+ end
100
96
  end
101
-
102
- hash
103
97
  end
104
98
 
105
- def pagination_params(options)
99
+ def pagination_params(records, options)
106
100
  @paginator ||= paginator(params)
107
101
  if @paginator && JSONAPI.configuration.top_level_links_include_pagination
108
102
  options = {}
109
103
  @paginator.class.requires_record_count &&
110
- options[:record_count] = count_records(@resources, options)
104
+ options[:record_count] = count_records(records, options)
111
105
  @paginator.links_page_params(options)
112
106
  else
113
107
  {}
@@ -126,9 +120,9 @@ module JSONAPI
126
120
  end
127
121
 
128
122
  def build_collection(records, options = {})
129
- unless JSONAPI.configuration.default_paginator == :none
130
- records = paginator(@request.params).apply(records, nil)
131
- end
123
+ records = apply_filter(records, options)
124
+ records = apply_pagination(records, options)
125
+ records = apply_sort(records)
132
126
  records.respond_to?(:to_ary) ? records.map { |record| turn_into_resource(record, options) } : []
133
127
  end
134
128
 
@@ -140,24 +134,103 @@ module JSONAPI
140
134
  end
141
135
  end
142
136
 
137
+ def apply_filter(records, options = {})
138
+ if apply_filter?(records, options)
139
+ records.where(filter_params)
140
+ else
141
+ records
142
+ end
143
+ end
144
+
145
+ def apply_filter?(records, options = {})
146
+ params[:filter].present? && records.respond_to?(:where) &&
147
+ (options[:filter].nil? || options[:filter])
148
+ end
149
+
150
+ def filter_params
151
+ @_filter_params ||=
152
+ params[:filter].keys.each_with_object({}) do |resource, hash|
153
+ hash[resource] = params[:filter][resource]
154
+ end
155
+ end
156
+
157
+ def apply_pagination(records, options = {})
158
+ return records unless apply_pagination?(options)
159
+ pagination = set_pagination(options)
160
+
161
+ records =
162
+ if records.is_a?(Array)
163
+ records[pagination[:range]]
164
+ else
165
+ pagination[:paginator].apply(records, nil)
166
+ end
167
+ end
168
+
169
+ def apply_sort(records)
170
+ return records unless params[:sort].present?
171
+
172
+ if records.is_a?(Array)
173
+ records.sort { |a, b| comp = 0; eval(sort_criteria) }
174
+ elsif records.respond_to?(:order)
175
+ records.order(sort_params)
176
+ end
177
+ end
178
+
179
+ def sort_criteria
180
+ sort_params.reduce('') do |sum, hash|
181
+ foo = ["a[:#{hash[0]}]", "b[:#{hash[0]}]"]
182
+ foo.reverse! if hash[1] == :desc
183
+ sum + "comp = comp == 0 ? #{foo.join(' <=> ')} : comp; "
184
+ end
185
+ end
186
+
187
+ def sort_params
188
+ @_sort_params ||=
189
+ params[:sort].split(',').each_with_object({}) do |criteria, hash|
190
+ order, field = criteria.match(/(\-?)(\w+)/i)[1..2]
191
+ hash[field] = order == '-' ? :desc : :asc
192
+ end
193
+ end
194
+
195
+ def set_pagination(options)
196
+ page_params = ActionController::Parameters.new(@request.params[:page])
197
+ if JSONAPI.configuration.default_paginator == :paged
198
+ @_paginator ||= PagedPaginator.new(page_params)
199
+ number = page_params['number'].to_i.nonzero? || 1
200
+ size = page_params['size'].to_i.nonzero? || JSONAPI.configuration.default_page_size
201
+ { paginator: @_paginator, range: (number - 1) * size..number * size - 1 }
202
+ elsif JSONAPI.configuration.default_paginator == :offset
203
+ @_paginator ||= OffsetPaginator.new(page_params)
204
+ offset = page_params['offset'].to_i.nonzero? || 0
205
+ limit = page_params['limit'].to_i.nonzero? || JSONAPI.configuration.default_page_size
206
+ { paginator: @_paginator, range: offset..offset + limit - 1 }
207
+ else
208
+ {}
209
+ end
210
+ end
211
+
212
+ def apply_pagination?(options)
213
+ JSONAPI.configuration.default_paginator != :none &&
214
+ (options[:paginate].nil? || options[:paginate])
215
+ end
216
+
143
217
  def fix_when_hash(records, options)
144
218
  return [] unless options[:model]
145
219
  records.map { |hash| options[:model].new(hash) }
146
- rescue
220
+ rescue ActiveRecord::UnknownAttributeError
147
221
  ids = records.map { |e| e[:id] || e['id'] }
148
222
  scope = options[:scope] ? options[:model].send(options[:scope]) : options[:model]
149
223
  scope.where(id: ids)
150
224
  end
151
225
 
152
226
  def count_records(records, options)
153
- if records.size.zero? then 0
154
- elsif options[:count] then options[:count]
155
- elsif options[:model] && options[:scope] then options[:model].send(options[:scope]).count
156
- elsif options[:model] then options[:model].count
227
+ if options[:count].present?
228
+ options[:count]
229
+ elsif records.is_a?(Array)
230
+ records.length
157
231
  else
158
- record = records.first
159
- model = record.try(:model) || record.try(:_model)
160
- model.class.count
232
+ records = apply_filter(records, options) if params[:filter].present?
233
+ records.except(:group, :order).count("DISTINCT #{records.table.name}.id")
161
234
  end
162
235
  end
163
236
 
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Utils
3
- VERSION = '0.4.1'
3
+ VERSION = '0.4.2'
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.1
4
+ version: 0.4.2
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: 2016-03-30 00:00:00.000000000 Z
12
+ date: 2016-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -39,20 +39,6 @@ dependencies:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: '10.0'
42
- - !ruby/object:Gem::Dependency
43
- name: rspec
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
42
  - !ruby/object:Gem::Dependency
57
43
  name: rspec-rails
58
44
  requirement: !ruby/object:Gem::Requirement
@@ -67,34 +53,6 @@ dependencies:
67
53
  - - ">="
68
54
  - !ruby/object:Gem::Version
69
55
  version: '0'
70
- - !ruby/object:Gem::Dependency
71
- name: smart_rspec
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: '0'
77
- type: :development
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: '0'
84
- - !ruby/object:Gem::Dependency
85
- name: pry
86
- requirement: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- type: :development
92
- prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- version: '0'
98
56
  - !ruby/object:Gem::Dependency
99
57
  name: sqlite3
100
58
  requirement: !ruby/object:Gem::Requirement
@@ -144,7 +102,7 @@ dependencies:
144
102
  - - ">="
145
103
  - !ruby/object:Gem::Version
146
104
  version: '4.0'
147
- type: :runtime
105
+ type: :development
148
106
  prerelease: false
149
107
  version_requirements: !ruby/object:Gem::Requirement
150
108
  requirements: