jsonapi-utils 0.3.4 → 0.3.5

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: e0600b0456c3a82eead45d6b278f6edd3a0eaf69
4
- data.tar.gz: f7ae630485129ae7f4ed320b2b66a43b4988be2b
3
+ metadata.gz: 1e857579e82b9b5550ec7224bd1c2659b4e06e9f
4
+ data.tar.gz: 468183964c826b06cff256ccfd2b4305b43f68bb
5
5
  SHA512:
6
- metadata.gz: 17a24aeb6bd942161301874c84c290d6214382a89f6d459b3c27a2c0e8036c6a24671e780cebe0e575ef699a0e1d86144839e7b626423f4c2803f267772b6a2c
7
- data.tar.gz: 90a95d43903965f646c5b2be1679b01bab64d6868785d245bffd008e65e6ee8e5c62c30f8c6ebe090234e0890c98a728494e0012caae26807a4a028904eb5f2b
6
+ metadata.gz: 597e131379f735cda8fb5f980256966089d0dacc4d5a552709a20524f30e4b5ab94e8ee01a3a0a22f861911bbeefa470341c35c5946badbc0319437353c34e02
7
+ data.tar.gz: 9715af2a8aeae7cda56d8f24e8f43f982774ab9db0d64e0c15aef2ada82a9f7714f4556895adfc06583a8a76539cd5dc2bee0a9b8df4c97d9d8beab8d0711510
@@ -19,7 +19,11 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.10"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec"
22
+ spec.add_development_dependency 'bundler', '~> 1.10'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec-rails'
25
+ spec.add_development_dependency 'sqlite3'
26
+ spec.add_development_dependency 'factory_girl', '~> 4.5'
27
+ spec.add_development_dependency 'jsonapi-resources', '~> 0.5.7'
28
+ spec.add_development_dependency 'rails', '>= 4.0'
25
29
  end
data/lib/jsonapi/utils.rb CHANGED
@@ -33,8 +33,8 @@ module JSONAPI
33
33
  jsonapi_render_errors(::JSONAPI::Utils::Exceptions::BadRequest.new)
34
34
  end
35
35
 
36
- def jsonapi_render_not_found
37
- id = extract_ids(@request.params)
36
+ def jsonapi_render_not_found(exception)
37
+ id = exception.message.match(/=(\d+)/)[1]
38
38
  jsonapi_render_errors(JSONAPI::Exceptions::RecordNotFound.new(id))
39
39
  end
40
40
 
@@ -48,12 +48,12 @@ module JSONAPI
48
48
  fix_request_options(params, records)
49
49
 
50
50
  if records.respond_to?(:to_ary)
51
- records = fix_when_hash(records, options) if needs_to_be_fixed?(records)
52
- @resources = build_collection(records, options)
53
- results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, @resources, result_options(options)))
51
+ records = fix_when_hash(records, options) if needs_to_be_fixed?(records)
52
+ @_records = build_collection(records, options)
53
+ results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, @_records, result_options(records, options)))
54
54
  else
55
- @resource = turn_into_resource(records, options)
56
- results.add_result(JSONAPI::ResourceOperationResult.new(:ok, @resource))
55
+ @_record = turn_into_resource(records, options)
56
+ results.add_result(JSONAPI::ResourceOperationResult.new(:ok, @_record))
57
57
  end
58
58
 
59
59
  create_response_document(results).contents
@@ -61,11 +61,6 @@ module JSONAPI
61
61
 
62
62
  private
63
63
 
64
- def extract_ids(hash)
65
- ids = hash.keys.select { |e| e =~ /id$/i }.map { |e| hash[e] }
66
- ids.first rescue '(id not identified)'
67
- end
68
-
69
64
  def fix_request_options(params, records)
70
65
  return if request.method !~ /get/i ||
71
66
  params.nil? ||
@@ -78,33 +73,33 @@ module JSONAPI
78
73
  records.is_a?(Array) && records.all? { |e| e.is_a?(Hash) }
79
74
  end
80
75
 
81
- def result_options(options)
82
- hash = {}
83
-
84
- if JSONAPI.configuration.top_level_links_include_pagination
85
- hash[:pagination_params] = pagination_params(options)
86
- end
76
+ def result_options(records, options)
77
+ {}.tap do |data|
78
+ if JSONAPI.configuration.top_level_links_include_pagination
79
+ data[:pagination_params] = pagination_params(records, options)
80
+ end
87
81
 
88
- if JSONAPI.configuration.top_level_meta_include_record_count
89
- hash[:record_count] = count_records(@resources, options)
82
+ if JSONAPI.configuration.top_level_meta_include_record_count
83
+ data[:record_count] = count_records(records, options)
84
+ end
90
85
  end
91
-
92
- hash
93
86
  end
94
87
 
95
- def pagination_params(options)
96
- if @paginator && JSONAPI.configuration.top_level_links_include_pagination
97
- options = {}
98
- @paginator.class.requires_record_count &&
99
- options[:record_count] = count_records(@resources, options)
100
- return @paginator.links_page_params(options)
88
+ def pagination_params(records, options)
89
+ data = {}
90
+ if @_paginator && JSONAPI.configuration.top_level_links_include_pagination
91
+ @_paginator.class.requires_record_count &&
92
+ data[:record_count] = count_records(records, options)
93
+ @_paginator.links_page_params(data)
101
94
  else
102
- return {}
95
+ data
103
96
  end
104
97
  end
105
98
 
106
99
  def build_collection(records, options = {})
107
- records = paginate(records, options)
100
+ records = apply_filter(records, options)
101
+ records = apply_pagination(records, options)
102
+ records = apply_sort(records)
108
103
  records.respond_to?(:to_ary) ? records.map { |record| turn_into_resource(record, options) } : []
109
104
  end
110
105
 
@@ -116,8 +111,28 @@ module JSONAPI
116
111
  end
117
112
  end
118
113
 
119
- def paginate(records, options = {})
120
- return records if pagination_disabled?(options)
114
+ def apply_filter(records, options = {})
115
+ if apply_filter?(records, options)
116
+ records.where(filter_params)
117
+ else
118
+ records
119
+ end
120
+ end
121
+
122
+ def apply_filter?(records, options = {})
123
+ params[:filter].present? && records.respond_to?(:where) &&
124
+ (options[:filter].nil? || options[:filter])
125
+ end
126
+
127
+ def filter_params
128
+ @_filter_params =
129
+ params[:filter].keys.each_with_object({}) do |resource, hash|
130
+ hash[resource] = params[:filter][resource]
131
+ end
132
+ end
133
+
134
+ def apply_pagination(records, options = {})
135
+ return records unless apply_pagination?(options)
121
136
  pagination = set_pagination(options)
122
137
 
123
138
  records =
@@ -128,43 +143,71 @@ module JSONAPI
128
143
  end
129
144
  end
130
145
 
146
+ def apply_sort(records)
147
+ return records unless params[:sort].present?
148
+
149
+ if records.is_a?(Array)
150
+ records.sort { |a, b| comp = 0; eval(sort_criteria) }
151
+ elsif records.respond_to?(:order)
152
+ records.order(sort_params)
153
+ end
154
+ end
155
+
156
+ def sort_criteria
157
+ sort_params.reduce('') do |sum, hash|
158
+ foo = ["a[:#{hash[0]}]", "b[:#{hash[0]}]"]
159
+ foo.reverse! if hash[1] == :desc
160
+ sum + "comp = comp == 0 ? #{foo.join(' <=> ')} : comp; "
161
+ end
162
+ end
163
+
164
+ def sort_params
165
+ @_sort_params ||=
166
+ params[:sort].split(',').each_with_object({}) do |criteria, hash|
167
+ order, field = criteria.match(/(\-?)(\w+)/i)[1..2]
168
+ hash[field] = order == '-' ? :desc : :asc
169
+ end
170
+ end
171
+
131
172
  def set_pagination(options)
132
173
  page_params = ActionController::Parameters.new(@request.params[:page])
133
174
  if JSONAPI.configuration.default_paginator == :paged
134
- @paginator ||= PagedPaginator.new(page_params)
135
- n = page_params['number'].to_i.nonzero? || 1
136
- s = page_params['size'].to_i.nonzero? || JSONAPI.configuration.default_page_size
137
- { paginator: @paginator, range: (n - 1) * s..n * s - 1 }
175
+ @_paginator ||= PagedPaginator.new(page_params)
176
+ number = page_params['number'].to_i.nonzero? || 1
177
+ size = page_params['size'].to_i.nonzero? || JSONAPI.configuration.default_page_size
178
+ { paginator: @_paginator, range: (number - 1) * size..number * size - 1 }
138
179
  elsif JSONAPI.configuration.default_paginator == :offset
139
- @paginator ||= OffsetPaginator.new(page_params)
140
- o = page_params['offset'].to_i.nonzero? || 0
141
- l = page_params['limit'].to_i.nonzero? || JSONAPI.configuration.default_page_size
142
- { paginator: @paginator, range: o..o + l - 1 }
180
+ @_paginator ||= OffsetPaginator.new(page_params)
181
+ offset = page_params['offset'].to_i.nonzero? || 0
182
+ limit = page_params['limit'].to_i.nonzero? || JSONAPI.configuration.default_page_size
183
+ { paginator: @_paginator, range: offset..offset + limit - 1 }
143
184
  else
144
185
  {}
145
186
  end
146
187
  end
147
188
 
148
- def pagination_disabled?(options)
149
- JSONAPI.configuration.default_paginator == :none ||
150
- !options[:paginate].nil? && !options[:paginate]
189
+ def apply_pagination?(options)
190
+ JSONAPI.configuration.default_paginator != :none &&
191
+ (options[:paginate].nil? || options[:paginate])
151
192
  end
152
193
 
153
194
  def fix_when_hash(records, options)
154
195
  return [] unless options[:model]
155
196
  records.map { |hash| options[:model].new(hash) }
156
- rescue
197
+ rescue ActiveRecord::UnknownAttributeError
157
198
  ids = records.map { |e| e[:id] || e['id'] }
158
199
  scope = options[:scope] ? options[:model].send(options[:scope]) : options[:model]
159
200
  scope.where(id: ids)
160
201
  end
161
202
 
162
203
  def count_records(records, options)
163
- if records.size.zero? then 0
164
- elsif options[:count] then options[:count]
165
- elsif options[:model] && options[:scope] then options[:model].send(options[:scope]).count
166
- elsif options[:model] then options[:model].count
167
- else records.first.model.class.count
204
+ if options[:count].present?
205
+ options[:count]
206
+ elsif records.is_a?(Array)
207
+ records.length
208
+ else
209
+ records = apply_filter(records, options) if params[:filter].present?
210
+ records.except(:group, :order).count("DISTINCT #{records.table.name}.id")
168
211
  end
169
212
  end
170
213
  end
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Utils
3
- VERSION = '0.3.4'
3
+ VERSION = '0.3.5'
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.3.4
4
+ version: 0.3.5
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-29 00:00:00.000000000 Z
12
+ date: 2016-04-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -40,7 +40,7 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '10.0'
42
42
  - !ruby/object:Gem::Dependency
43
- name: rspec
43
+ name: rspec-rails
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
@@ -53,6 +53,62 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: sqlite3
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: factory_girl
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '4.5'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '4.5'
84
+ - !ruby/object:Gem::Dependency
85
+ name: jsonapi-resources
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.5.7
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.5.7
98
+ - !ruby/object:Gem::Dependency
99
+ name: rails
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '4.0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '4.0'
56
112
  description: A Rails way to get your API's data following the JSON API's specs (http://jsosapi.org)
57
113
  email:
58
114
  - tiagopog@gmail.com
@@ -95,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
151
  version: '0'
96
152
  requirements: []
97
153
  rubyforge_project:
98
- rubygems_version: 2.4.5.1
154
+ rubygems_version: 2.6.2
99
155
  signing_key:
100
156
  specification_version: 4
101
157
  summary: JSON::Utils is a simple way to get a full-featured JSON API serialization