pureapi 0.1.0
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 +7 -0
- data/bin/pureapi +4 -0
- data/lib/pureapi/controller.rb +484 -0
- data/lib/pureapi/model.rb +128 -0
- data/lib/pureapi.rb +16 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 29f9ce1d05cb751dbf596027db202822a3673eaa
|
4
|
+
data.tar.gz: f3166e0119282f230f7250782153cf83a4bb884e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c0e73f3029f3d785c960599c23cc6d71f5041044eaa9e80c205246bf1b100178fe2345bf5e91720cc467a92e310bb9e703bf8f88ed2ad3a33f3b55c2365e327a
|
7
|
+
data.tar.gz: a4b8f0a24ef52c14f16e34d884ca3b9a3447d2703c383d9cd32f558962ffaa7d0e652856a99b5fea6d1cc5ef20718bd65327119085de4288f085556dd1fbcf4d
|
data/bin/pureapi
ADDED
@@ -0,0 +1,484 @@
|
|
1
|
+
# Implement methods use for handle with table records like
|
2
|
+
# 1. Pagination
|
3
|
+
# 2. Sort
|
4
|
+
# 3. Search
|
5
|
+
# 4. Include
|
6
|
+
module Pureapi::Controller
|
7
|
+
# extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
# Define constants of regex table and column name
|
10
|
+
FIELD_NAME = '[a-z_][a-z0-9_]*'
|
11
|
+
NAME_REGEX = /#{FIELD_NAME}/
|
12
|
+
FULLBEFORE_REGEX = /#{FIELD_NAME}\{/
|
13
|
+
BEFORE_REGEX = /\{/
|
14
|
+
AFTER_REGEX = /\}/
|
15
|
+
|
16
|
+
### Begin 3 main API for GET data
|
17
|
+
# Filter list objects contain search, sort, paginate
|
18
|
+
def default_index_filter(objects)
|
19
|
+
# 1. search
|
20
|
+
# 2. sort and default sort is id.desc
|
21
|
+
objects = default_sort_filter(objects)
|
22
|
+
# 3. conditions
|
23
|
+
objects = default_cond_filter(objects)
|
24
|
+
objects = default_incond_filter(objects)
|
25
|
+
# 4. paginate
|
26
|
+
objects = paging_standard(objects)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Filter list objects contain search, sort, limit
|
30
|
+
def default_report_filter(objects)
|
31
|
+
# 1. search
|
32
|
+
# 2. sort and default sort is id.desc
|
33
|
+
# 3. conditions
|
34
|
+
objects = default_cond_filter(objects)
|
35
|
+
objects = default_incond_filter(objects)
|
36
|
+
# 4. limit similar paginate
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return json for index action
|
40
|
+
def records_json(criterias, includes_deep_level = 2)
|
41
|
+
options = {}
|
42
|
+
includes = criterias.default_includes
|
43
|
+
|
44
|
+
if params.permit(:fields)[:fields]
|
45
|
+
jsons = parse_includes(params.permit(:fields)[:fields], criterias, includes_deep_level)
|
46
|
+
|
47
|
+
includes += jsons[:includes] if !jsons[:includes].blank?
|
48
|
+
options = jsons[:as_json] if !jsons[:as_json].blank?
|
49
|
+
end
|
50
|
+
|
51
|
+
params[:fields] = deparse_fields(options)
|
52
|
+
options[:methods] = criterias.json_methods
|
53
|
+
options[:only] = options[:only].blank? ? criterias.default_onlyasjsons : options[:only]
|
54
|
+
criterias = criterias.includes(includes) if !includes.blank?
|
55
|
+
criterias.as_json(options)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return json for show action
|
59
|
+
def record_json(model, includes_deep_level = 2)
|
60
|
+
options = {}
|
61
|
+
|
62
|
+
if params.permit(:fields)[:fields]
|
63
|
+
jsons = parse_includes(params.permit(:fields)[:fields], model.class, includes_deep_level)
|
64
|
+
|
65
|
+
options = jsons[:as_json] if !jsons[:as_json].blank?
|
66
|
+
end
|
67
|
+
|
68
|
+
options[:only] = options[:only].blank? ? model.class.default_onlyasjsons : options[:only]
|
69
|
+
options[:methods] = model.class.json_methods
|
70
|
+
model.as_json(options)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return json for index action
|
74
|
+
def records_asjson(criterias)
|
75
|
+
options = {}
|
76
|
+
includes = []
|
77
|
+
|
78
|
+
if params.permit(:fields)[:fields]
|
79
|
+
jsons = parse_includes(params.permit(:fields)[:fields], criterias)
|
80
|
+
|
81
|
+
includes += jsons[:includes] if !jsons[:includes].blank?
|
82
|
+
options = jsons[:as_json] if !jsons[:as_json].blank?
|
83
|
+
end
|
84
|
+
|
85
|
+
params[:fields] = deparse_fields(options)
|
86
|
+
options[:only] = options[:only].blank? ? criterias.default_onlyasjsons : options[:only]
|
87
|
+
includes += criterias.json_method_includes.slice(*options[:methods]).values if !options[:methods].blank?
|
88
|
+
|
89
|
+
criterias.includes(includes.uniq).as_json(options)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return json for show action
|
93
|
+
def record_asjson(model)
|
94
|
+
options = {}
|
95
|
+
|
96
|
+
if params.permit(:fields)[:fields]
|
97
|
+
jsons = parse_includes(params.permit(:fields)[:fields], model.class)
|
98
|
+
|
99
|
+
options = jsons[:as_json] if !jsons[:as_json].blank?
|
100
|
+
end
|
101
|
+
|
102
|
+
options[:only] = options[:only].blank? ? model.class.default_onlyasjsons : options[:only]
|
103
|
+
model.as_json(options)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Define json filters for params in render json api
|
107
|
+
def filter_jsons
|
108
|
+
{
|
109
|
+
paging: {
|
110
|
+
page: params[:page],
|
111
|
+
per_page: params[:per_page],
|
112
|
+
page_total: params[:page_total],
|
113
|
+
record_total: params[:record_total],
|
114
|
+
next: params[:page] < params[:page_total] ? (params[:page] + 1) : nil,
|
115
|
+
prev: params[:page] > 1 ? (params[:page] - 1) : nil,
|
116
|
+
},
|
117
|
+
orders: params[:orders] || [],
|
118
|
+
searches: params[:searches] || {},
|
119
|
+
compconds: params[:compconds] || {},
|
120
|
+
logics: params[:logics] || {},
|
121
|
+
fields: params[:fields] || ''
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def report_filter_jsons
|
126
|
+
{
|
127
|
+
searches: params[:searches] || {},
|
128
|
+
compconds: params[:compconds] || {},
|
129
|
+
logics: params[:logics] || {},
|
130
|
+
}
|
131
|
+
end
|
132
|
+
### End 3 main API for GET data
|
133
|
+
|
134
|
+
### Begin options API for GET data
|
135
|
+
# Filter list objects contain search, sort, paginate
|
136
|
+
def standard_index_filter(objects)
|
137
|
+
# 1. search
|
138
|
+
objects = default_search_filter(objects)
|
139
|
+
# 2. sort and default sort is id.desc
|
140
|
+
objects = default_sort_filter(objects)
|
141
|
+
# 3. conditions
|
142
|
+
objects = default_cond_filter(objects)
|
143
|
+
objects = default_incond_filter(objects)
|
144
|
+
# 4. paginate
|
145
|
+
objects = paging_standard(objects)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Filter list objects contain search, sort
|
149
|
+
def without_paging_index_filter(objects)
|
150
|
+
# 1. search
|
151
|
+
objects = default_search_filter(objects)
|
152
|
+
# 2. sort and default sort is id.desc
|
153
|
+
objects = default_sort_filter(objects)
|
154
|
+
# 3. conditions
|
155
|
+
objects = default_cond_filter(objects)
|
156
|
+
objects = default_incond_filter(objects)
|
157
|
+
end
|
158
|
+
### End options API for GET data
|
159
|
+
|
160
|
+
### Begin setup of default_search_filter
|
161
|
+
# Filter searchs of object criteria
|
162
|
+
def default_search_filter(objects)
|
163
|
+
params[:searches] = search_params
|
164
|
+
advanced_search_params.each{|k, v| params[:searches][k] = v}
|
165
|
+
|
166
|
+
objects = objects.full_search(search_params, advanced_search_params)
|
167
|
+
end
|
168
|
+
### End setup of default_search_filter
|
169
|
+
|
170
|
+
### Begin setup of default_sort_filter (.order asc|desc)
|
171
|
+
# Filter orders of object criteria
|
172
|
+
def default_sort_filter(objects)
|
173
|
+
orders = parse_orders(params.permit(orders: [])[:orders], objects.column_names)
|
174
|
+
orders[:id] = :desc if orders.blank?
|
175
|
+
params[:orders] = orders.map{|field, order_type| "#{field}.#{order_type}"}.uniq
|
176
|
+
objects.order(orders)
|
177
|
+
end
|
178
|
+
|
179
|
+
# array orders contains field.asc or field
|
180
|
+
# array column_names contains valid fields
|
181
|
+
# return hash of field => sort type (asc, desc)
|
182
|
+
def parse_orders(orders = [], column_names = [])
|
183
|
+
results = {}
|
184
|
+
|
185
|
+
orders.map do |order|
|
186
|
+
matchs = /(#{FIELD_NAME})\.(asc|desc)/.match(order) || /(#{FIELD_NAME})/i.match(order)
|
187
|
+
results[matchs[1]] = matchs[2] || 'asc' if matchs && column_names.include?(matchs[1])
|
188
|
+
end unless orders.blank?
|
189
|
+
|
190
|
+
results
|
191
|
+
end
|
192
|
+
### End setup of default_sort_filter
|
193
|
+
|
194
|
+
### Begin setup of feature comparison conditions
|
195
|
+
# Filter conditions of object criteria
|
196
|
+
# Need upgrade calculate compcond_params
|
197
|
+
def default_cond_filter(objects)
|
198
|
+
compcond_params = []
|
199
|
+
|
200
|
+
objects.compcond_columns.each do |column_name|
|
201
|
+
Constants::COMPARISON_OPERATORS.each do |key, value|
|
202
|
+
compcond_params << [column_name, key].join('.')
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
compconds = parse_compconds(params.permit(compconds: compcond_params)[:compconds].to_h, objects.column_names)
|
207
|
+
params[:compconds] = {}
|
208
|
+
|
209
|
+
compconds.each do |compcond|
|
210
|
+
params[:compconds]["#{compcond[:f]}.#{Constants::COMPARISON_OPERATORS_INVERT[compcond[:o]]}"] = compcond[:v]
|
211
|
+
end
|
212
|
+
|
213
|
+
objects.compconds(compconds)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Not use under code because lte => lt
|
217
|
+
# matchs = /([a-z0-9_]+)\.(#{Constants::COMPARISON_OPERATORS.keys.join('|')})/.match(key)
|
218
|
+
# if matchs && column_names.include?(matchs[1])
|
219
|
+
# results << {f: matchs[1], o: Constants::COMPARISON_OPERATORS[matchs[2].to_sym], v: value}
|
220
|
+
# end
|
221
|
+
def parse_compconds(compconds = {}, column_names = [])
|
222
|
+
results = []
|
223
|
+
|
224
|
+
compconds.map do |key, value|
|
225
|
+
splits = key.split('.')
|
226
|
+
|
227
|
+
if splits.length == 2 && column_names.include?(splits[0])
|
228
|
+
if splits[1].to_sym == :eq && Constants::NULL_OPERATOR_KEYS.include?(value)
|
229
|
+
results << {
|
230
|
+
f: splits[0],
|
231
|
+
o: Constants::COMPARISON_OPERATORS[splits[1].to_sym],
|
232
|
+
v: Constants::NULL_OPERATORS[value]}
|
233
|
+
else
|
234
|
+
results << {f: splits[0], o: Constants::COMPARISON_OPERATORS[splits[1].to_sym], v: value}
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end unless compconds.blank?
|
238
|
+
|
239
|
+
results
|
240
|
+
end
|
241
|
+
### End setup of feature comparison conditions
|
242
|
+
|
243
|
+
### Begin setup of feature in conditions (logical)
|
244
|
+
# Filter conditions of object criteria
|
245
|
+
# Need upgrade calculate compcond_params
|
246
|
+
def default_incond_filter(objects)
|
247
|
+
logic_params = []
|
248
|
+
|
249
|
+
objects.incond_columns.each do |column_name|
|
250
|
+
logic_params << {[column_name, :in].join('.') => []}
|
251
|
+
end
|
252
|
+
|
253
|
+
logics = parse_logicconds(params.permit(logics: logic_params)[:logics].to_h, objects.column_names)
|
254
|
+
params[:logics] = {}
|
255
|
+
|
256
|
+
logics.each do |logic|
|
257
|
+
params[:logics]["#{logic[:f]}.#{Constants::LOGICAL_OPERATORS_INVERT[logic[:o]]}"] = logic[:v]
|
258
|
+
end
|
259
|
+
|
260
|
+
objects.logicconds(logics)
|
261
|
+
end
|
262
|
+
|
263
|
+
# References from parse_compconds methods
|
264
|
+
# Upgrade results.push(!value.blank?) >> +parse_compconds+
|
265
|
+
def parse_logicconds(compconds = {}, column_names = [])
|
266
|
+
results = []
|
267
|
+
|
268
|
+
compconds.map do |key, value|
|
269
|
+
next if value.blank?
|
270
|
+
|
271
|
+
splits = key.split('.')
|
272
|
+
|
273
|
+
if splits.length == 2 && column_names.include?(splits[0])
|
274
|
+
results << {f: splits[0], o: Constants::LOGICAL_OPERATORS[splits[1].to_sym], v: value}
|
275
|
+
end
|
276
|
+
end unless compconds.blank?
|
277
|
+
|
278
|
+
results
|
279
|
+
end
|
280
|
+
### End setup of feature comparison conditions
|
281
|
+
|
282
|
+
### Begin setup of paging_standard. If not use will_paginate, write in mode class
|
283
|
+
# Method validate page number (like page params)
|
284
|
+
def validate_page(page, page_total)
|
285
|
+
page.blank? || page <= 0 ? 1 : (page > page_total ? page_total : page)
|
286
|
+
end
|
287
|
+
|
288
|
+
# Paging standard
|
289
|
+
# Criteria model that will be pagination
|
290
|
+
# Return criteria_model.paginate and params[:page, :per_page, :page_total]
|
291
|
+
def paging_standard(criteria_model)
|
292
|
+
per_page = [paging_params[:per_page].try(:to_i) || Constants::Pagination::DEFAULT_PER_PAGE, 1].max
|
293
|
+
|
294
|
+
# Paging standard
|
295
|
+
record_total = criteria_model.count
|
296
|
+
per_page = record_total if paging_params[:per_page] == Constants::Pagination::INFINITE_PER_PAGE\
|
297
|
+
&& record_total > 0
|
298
|
+
page_total = (record_total.to_f / per_page).ceil
|
299
|
+
page = validate_page(paging_params[:page].try(:to_i) || 1, page_total)
|
300
|
+
page = [page, 1].max
|
301
|
+
|
302
|
+
# Assign paging params to params helper
|
303
|
+
params[:page] = page
|
304
|
+
params[:per_page] = per_page
|
305
|
+
params[:page_total] = page_total
|
306
|
+
params[:record_total] = record_total
|
307
|
+
|
308
|
+
criteria_model.paginate(page: page, per_page: per_page)
|
309
|
+
end
|
310
|
+
### End setup of paging_standard
|
311
|
+
|
312
|
+
### Begin feature records_json and record_json which render format json
|
313
|
+
# Methods return hash contain full params use for ActiveRecord includes()
|
314
|
+
# and ActiveModel::Serializers::JSON as_json()
|
315
|
+
def parse_includes(fields, model, includes_deep_level = 2)
|
316
|
+
_fields = parse_fields(fields, includes_deep_level)
|
317
|
+
|
318
|
+
if _fields[:only].is_a?(Array) && !_fields[:only].blank?
|
319
|
+
_fields[:methods] = _fields[:only] & model.json_methods
|
320
|
+
_fields[:only] = _fields[:only] & model.column_names.map(&:to_sym)
|
321
|
+
end
|
322
|
+
|
323
|
+
if _fields[:include].is_a?(Hash) && !_fields[:include].blank?
|
324
|
+
_fields[:include] = merge_includes(_fields[:include], model.asjson_fields)
|
325
|
+
end
|
326
|
+
|
327
|
+
{
|
328
|
+
includes: include_relations(_fields),
|
329
|
+
as_json: _fields.delete_if { |k, v| v.blank? }
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
# Methods parse string fields user for as_json
|
334
|
+
# Example str = "a,b, c,d,e,f,g{k,l,h{b,i}},w{n, m},j,t{ww, gh, l{bb}}, f{k, mm}, vv"
|
335
|
+
# return result = {:only=>["a", "b", "c", "d", "e", "f", "j", "vv"],
|
336
|
+
# :include=>{"g"=>{:only=>["k", "l"], :include=>{"h"=>{:only=>["b", "i"]}}},
|
337
|
+
# "w"=>{:only=>["n", "m"]}, "t"=>{:only=>["ww", "gh"], :include=>{"l"=>{:only=>["bb"]}}},
|
338
|
+
# "f"=>{:only=>["k", "mm"]}}}
|
339
|
+
def parse_fields(str, deep = 2)
|
340
|
+
result = { only: [], include: {} }
|
341
|
+
|
342
|
+
fullbefore = substr_index(str, FULLBEFORE_REGEX)
|
343
|
+
after = substr_index(str, AFTER_REGEX)
|
344
|
+
|
345
|
+
if fullbefore.length == after.length
|
346
|
+
if fullbefore.length == 0
|
347
|
+
result[:only] = str.scan(NAME_REGEX)
|
348
|
+
else
|
349
|
+
kvs = openandclose(fullbefore, after)
|
350
|
+
_kvs = openandclose(substr_index(str, BEFORE_REGEX), after).invert
|
351
|
+
s = 0
|
352
|
+
|
353
|
+
kvs.each do |k, v|
|
354
|
+
if s < k
|
355
|
+
result[:only] += str[s..(k - 1)].scan(NAME_REGEX)
|
356
|
+
s = v + 1
|
357
|
+
elsif
|
358
|
+
s = v + 1
|
359
|
+
end
|
360
|
+
|
361
|
+
if k < v && deep > 0
|
362
|
+
result[:include][str[k..v][NAME_REGEX].to_sym] =\
|
363
|
+
parse_fields(str[(_kvs[v] + 1)..(v - 1)], deep - 1)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
if s < (str.length - 1)
|
368
|
+
result[:only] += str[s..-1].scan(NAME_REGEX)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
result[:only] = result[:only].map(&:to_sym)
|
374
|
+
return result.delete_if { |k, v| v.blank? }
|
375
|
+
end
|
376
|
+
|
377
|
+
# Hash +fields+
|
378
|
+
# return String is params query
|
379
|
+
def deparse_fields(fields)
|
380
|
+
return '' unless fields.is_a? Hash
|
381
|
+
|
382
|
+
_arr = []
|
383
|
+
|
384
|
+
if fields[:only].is_a? Array
|
385
|
+
_arr += fields[:only]
|
386
|
+
end
|
387
|
+
|
388
|
+
if fields[:methods].is_a? Array
|
389
|
+
_arr += fields[:methods]
|
390
|
+
end
|
391
|
+
|
392
|
+
if fields[:include].is_a?(Hash) && !fields[:include].blank?
|
393
|
+
fields[:include].each do |k, v|
|
394
|
+
_arr << "#{k}{#{deparse_fields(v)}}"
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
_arr.join(',')
|
399
|
+
end
|
400
|
+
|
401
|
+
# Require length of before and after is equal
|
402
|
+
# +before.length == after.length > 1+
|
403
|
+
def openandclose(before, after)
|
404
|
+
results = {}
|
405
|
+
|
406
|
+
index = 0
|
407
|
+
results[before[index]] = after[index]
|
408
|
+
before.each_with_index do |value, i|
|
409
|
+
if results[before[index]] > value
|
410
|
+
results[before[index]] = after[i]
|
411
|
+
else
|
412
|
+
index = i
|
413
|
+
results[before[index]] = after[index]
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
return results
|
418
|
+
end
|
419
|
+
|
420
|
+
# return Array all index of sub_str in str
|
421
|
+
def substr_index(str, sub_str)
|
422
|
+
i = 0
|
423
|
+
all = []
|
424
|
+
while (i = str.index(sub_str, i)).is_a? Integer
|
425
|
+
all << i
|
426
|
+
i += str[i..-1][sub_str].length
|
427
|
+
end
|
428
|
+
all
|
429
|
+
end
|
430
|
+
|
431
|
+
# return all relations be included by fields
|
432
|
+
def include_relations(fields)
|
433
|
+
result = []
|
434
|
+
|
435
|
+
if fields[:include].is_a? Hash
|
436
|
+
fields[:include].each do |k, v|
|
437
|
+
if (v.is_a? Hash) && (v[:include].is_a? Hash)
|
438
|
+
result << { k => include_relations(v)}
|
439
|
+
else
|
440
|
+
result << k
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
result
|
446
|
+
end
|
447
|
+
|
448
|
+
def merge_includes(target ,source)
|
449
|
+
result = {}
|
450
|
+
|
451
|
+
target.each do |k, v|
|
452
|
+
result[k] = {}
|
453
|
+
|
454
|
+
if v.is_a?(Hash) && source[k].is_a?(Hash)
|
455
|
+
if source[k][:only].is_a?(Array)
|
456
|
+
result[k][:only] = v[:only].is_a?(Array) ? (v[:only] & source[k][:only]) : source[k][:only]
|
457
|
+
end
|
458
|
+
|
459
|
+
if v[:include].is_a?(Hash) && source[k][:include].is_a?(Hash)
|
460
|
+
result[k][:include] = merge_includes(v[:include], source[k][:include])
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
result.delete_if { |k, v| v.blank? }
|
466
|
+
end
|
467
|
+
### End feature records_json and record_json
|
468
|
+
|
469
|
+
### Begin declare strong parameters
|
470
|
+
def paging_params
|
471
|
+
params.permit(:page, :per_page)
|
472
|
+
end
|
473
|
+
|
474
|
+
# Strong parameters for default search query
|
475
|
+
def search_params
|
476
|
+
params.permit()
|
477
|
+
end
|
478
|
+
|
479
|
+
# Strong parameters for default advanced search query
|
480
|
+
def advanced_search_params
|
481
|
+
params.permit()
|
482
|
+
end
|
483
|
+
### End declare strong parameters
|
484
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# Implement methods use for handle with table records like
|
2
|
+
# 1. Methods in as_json
|
3
|
+
# 2.
|
4
|
+
module Pureapi::Model
|
5
|
+
# return default array contains methods for as_json
|
6
|
+
# Eg. [:status_name, :path_detail, :restrictions, :channel_course_code]
|
7
|
+
def json_methods
|
8
|
+
[]
|
9
|
+
end
|
10
|
+
|
11
|
+
# return default criterias for advanced_search
|
12
|
+
# Eg.
|
13
|
+
# User .where({}) to fix case return self
|
14
|
+
# def advanced_search(advanced_params)
|
15
|
+
# criterias = self
|
16
|
+
|
17
|
+
# # search by list course_ids
|
18
|
+
# criterias = advanced_params[:course_ids].blank? ?
|
19
|
+
# criterias : criterias.where(course_id: advanced_params[:course_ids])
|
20
|
+
|
21
|
+
# # search by list channel_ids
|
22
|
+
# criterias = advanced_params[:channel_ids].blank? ?
|
23
|
+
# criterias : criterias.where(channel_id: advanced_params[:channel_ids])
|
24
|
+
|
25
|
+
# # search by code
|
26
|
+
# criterias = advanced_params[:code].blank? ?
|
27
|
+
# criterias : criterias.where(
|
28
|
+
# "`channel_courses`.`code` LIKE ?",
|
29
|
+
# "%#{advanced_params[:code]}%"
|
30
|
+
# )
|
31
|
+
|
32
|
+
# return criterias.where({})
|
33
|
+
# end
|
34
|
+
def advanced_search(advanced_params)
|
35
|
+
return self.where({})
|
36
|
+
end
|
37
|
+
|
38
|
+
# Provide search function 2 type: normal and advanced
|
39
|
+
# Required setup advanced_search methods
|
40
|
+
#
|
41
|
+
# ActionController::Parameters +_params+, contain fields use .where()
|
42
|
+
# ActionController::Parameters +_advanced_params+, detail in advanced_search method
|
43
|
+
# Or
|
44
|
+
# Hash +_params+, contain fields use .where()
|
45
|
+
# Hash +_advanced_params+, detail in advanced_search method
|
46
|
+
def full_search(params, advanced_params)
|
47
|
+
_params = params.delete_if { |k, v| v.blank? }
|
48
|
+
|
49
|
+
criterias = self
|
50
|
+
criterias = _params.blank? ? criterias : criterias.where(_params.to_h)
|
51
|
+
criterias = advanced_params.blank? ? criterias : criterias.advanced_search(advanced_params.to_h)
|
52
|
+
|
53
|
+
return criterias.where({})
|
54
|
+
end
|
55
|
+
|
56
|
+
# Comparsion operator conditions method
|
57
|
+
# Array +params+ contains hash = {f, o, v}
|
58
|
+
# :f is column name
|
59
|
+
# :o is comparsion operator
|
60
|
+
# :v is value
|
61
|
+
def compconds(params = [])
|
62
|
+
criterias = self
|
63
|
+
|
64
|
+
params.each do |param|
|
65
|
+
if param[:o] == '='
|
66
|
+
criterias = criterias.where(param[:f] => param[:v])
|
67
|
+
else
|
68
|
+
criterias = criterias.where("`#{self.table_name}`.`#{param[:f]}` #{param[:o]} ?", param[:v])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
return criterias.where({})
|
73
|
+
end
|
74
|
+
|
75
|
+
# Comparsion operator conditions method
|
76
|
+
# Array +params+ contains hash = {f, o, v}
|
77
|
+
# :f is column name
|
78
|
+
# :o is comparsion operator
|
79
|
+
# :v is value
|
80
|
+
def logicconds(params = [])
|
81
|
+
criterias = self
|
82
|
+
|
83
|
+
params.each do |param|
|
84
|
+
if param[:o] == 'IN'
|
85
|
+
criterias = criterias.where(param[:f] => param[:v])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
return criterias.where({})
|
90
|
+
end
|
91
|
+
|
92
|
+
# Define array of columns use for comparison conditions
|
93
|
+
# E.g [:id, :name, :channel_course_id, :status]
|
94
|
+
def compcond_columns
|
95
|
+
[:id]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Define array of columns use for in conditions (logical)
|
99
|
+
# E.g [:id, :name, :channel_course_id, :status]
|
100
|
+
def incond_columns
|
101
|
+
[:id]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Define default includes of active records
|
105
|
+
# E.g [:channel, :course]
|
106
|
+
def default_includes
|
107
|
+
[]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Define default fields use for asjson on includes
|
111
|
+
# E.g
|
112
|
+
# {
|
113
|
+
# channel: {only: [:id, :code, :name], include: Channel.asjson_fields},
|
114
|
+
# course: {only: [:id, :code, :name]}
|
115
|
+
# }
|
116
|
+
def asjson_fields
|
117
|
+
{}
|
118
|
+
end
|
119
|
+
|
120
|
+
def json_method_includes
|
121
|
+
{}
|
122
|
+
end
|
123
|
+
|
124
|
+
# Define default fields use for as_jsons
|
125
|
+
def default_onlyasjsons
|
126
|
+
self.column_names.map(&:to_sym)
|
127
|
+
end
|
128
|
+
end
|
data/lib/pureapi.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Pureapi
|
2
|
+
class << self
|
3
|
+
# Say hi to you & talk about gem!
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# >> Pureapi.about("spanish")
|
7
|
+
# => hello spanish
|
8
|
+
#
|
9
|
+
# Arguments:
|
10
|
+
# yourname: (String)
|
11
|
+
|
12
|
+
def about yourname
|
13
|
+
"hello #{yourname}. This is a library for pure api"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pureapi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dieu Pham
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A simple concern in model & controller for api
|
14
|
+
email: dieupv@topica.edu.vn
|
15
|
+
executables:
|
16
|
+
- pureapi
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/pureapi
|
21
|
+
- lib/pureapi.rb
|
22
|
+
- lib/pureapi/controller.rb
|
23
|
+
- lib/pureapi/model.rb
|
24
|
+
homepage: http://rubygems.org/gems/pureapi
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.6.8
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Pure API
|
48
|
+
test_files: []
|