paginated 1.0.3 → 1.0.4.1

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
  SHA256:
3
- metadata.gz: 76e2b8888c610c376b97da4c118067cf4d6d1ac8d63e02fc11971638b9ad0595
4
- data.tar.gz: a5fc2020f8d9a3adf16816e0d03d2e2419ed3128d806d23a5ce3d20a6831e442
3
+ metadata.gz: 60256c0f7c8df7e2fd347f31b5b713b6a878aa4554017a2aa074e05ffc9b5900
4
+ data.tar.gz: 3daaacf9ba025b0ce2b47d0990aa72b29e45037dde4c8461fb913bc21aa28f94
5
5
  SHA512:
6
- metadata.gz: a3aa8e4b873a0498720d727d3517cb9576eb1b97a96884cdf2c8336b92f56a0016db99e1d6c3c49875bede9fc73dbd91d902180b05253e7079d9970504f9b01a
7
- data.tar.gz: 7ad52eb2f7a3b3c3356781d7703f156f14ef4cec04d00dc14e825e0c6dd4ef10b868b9325b18ab2405d740d0ddc2d70072f09d4e91cc12f398548344ed66ce02
6
+ metadata.gz: d3a615e433b61937db50ccacea1c96857b263e7cf680cfe29c9e0feb4f678cd988a2ac34cfb24dc693884f525406262dd7bfbe60e0859ee8e6e93ae50b23f24a
7
+ data.tar.gz: 3ffafc39efb627cdfbf2bbff6f9c273421694fcc8abe6984260453cca1893ed8a65cd190740fcec7fcba0d459b4af1a0a2f7eb4374273e651f9ce4c9cb580215
data/README.md CHANGED
@@ -20,7 +20,7 @@ bundle
20
20
 
21
21
  Использование с помощью вызова метода `.collection` и передачи в него необходимых опций:
22
22
  ```
23
- Paginated.new.collection()
23
+ Paginated.collection()
24
24
  ```
25
25
 
26
26
  Опции (с примерами):
@@ -40,7 +40,7 @@ Paginated.new.collection()
40
40
  Например:
41
41
 
42
42
  ```
43
- Paginated.new.collection(
43
+ Paginated.collection(
44
44
  model: 'User',
45
45
  fields: %i[
46
46
  email
@@ -5,9 +5,9 @@ module Search
5
5
  private
6
6
 
7
7
  def search
8
- @attrs[:search]&.each do |field|
8
+ @search_fields&.each do |field|
9
9
  # коллекция записей для дальнейшей фильтрации
10
- entity = @objects || @model.unscoped.merge(@scopes)
10
+ list = @objects || @model.unscoped.merge(@scopes)
11
11
 
12
12
  # оператор и значение для поиска
13
13
  operator, value = search_operands(field)
@@ -20,7 +20,7 @@ module Search
20
20
  # название скоупа из модели, который нужно применить
21
21
  scope_name = operator.split('.')[1]
22
22
  # применение скоупа
23
- @objects = entity.send(scope_name, value)
23
+ @objects = list.send(scope_name, value)
24
24
  @objects_count = @objects.count
25
25
  next
26
26
  end
@@ -32,16 +32,16 @@ module Search
32
32
 
33
33
  if field.include?('.')
34
34
  # нужно приджойнить таблицу
35
- join_association, field = field.split('.')
36
- table = join_association.tableize
37
- entity = entity.joins(join_association.to_sym)
35
+ join_assoc, field = field.split('.')
36
+ table = join_assoc.tableize
37
+ list = list.joins(join_assoc.to_sym)
38
38
  else
39
39
  table = @model.table_name
40
40
  field = field.split('|')[0]
41
41
  end
42
42
 
43
43
  query = where_query(table, field, operator, value)
44
- @objects = entity.where(query)
44
+ @objects = list.where(query)
45
45
  @objects_count = @objects.count
46
46
  end
47
47
  end
@@ -52,10 +52,10 @@ module Search
52
52
  # WHERE query operator
53
53
  operator = field.split('|').size > 1 ? field.split('|').last : '='
54
54
 
55
- # check for ILIKE operator
55
+ # условие для поиска ILIKE
56
56
  value = "%#{value}%" if operator == 'ilike' && value.present?
57
57
 
58
- # check if multi-filter search enabled
58
+ # проверка мульти-поиска по параметру с массивом
59
59
  if operator == 'multi' && !value.blank?
60
60
  operator = 'IN'
61
61
  value = "(#{value.join(', ')})"
@@ -63,13 +63,13 @@ module Search
63
63
 
64
64
  # проверка диапазона (MIN/MAX)
65
65
  if %w[min max].include?(operator)
66
- range_field = field.split('.').last.split(':')[0].try { |p| p.split('|')[0] }
66
+ range_field = field.split('.').last.split(':')[0].try { |i| i.split('|')[0] }
67
67
  value = @params["#{range_field}_#{operator}"]
68
68
  operator = operator == 'min' ? '>=' : '<='
69
69
  end
70
70
 
71
71
  # check array operator
72
- if operator == 'array' && !value.blank?
72
+ if operator == 'array' && value.present?
73
73
  operator = '='
74
74
  value = "{#{value}}"
75
75
  end
@@ -78,24 +78,14 @@ module Search
78
78
  end
79
79
 
80
80
  def default_param_value(field)
81
- key =
82
- if field.include?('|')
83
- # название ключа-поля без оператора (напр. ilike)
84
- field.split('|')[0]
85
- else
86
- field
87
- end
81
+ # название ключа-поля без оператора (напр. ilike)
82
+ key = field.split('|')[0]
88
83
 
89
84
  @params[key]
90
85
  end
91
86
 
92
87
  def where_query(table, field, operator, value)
93
- if field.include?('_at')
94
- # фильтрация по дате/времени
95
- "EXTRACT(epoch FROM #{field}) #{operator} #{value}"
96
- else
97
- "#{table}.#{field} #{operator} #{value}"
98
- end
88
+ "#{table}.#{field} #{operator} #{value}"
99
89
  end
100
90
 
101
91
  def quotations_formatting(string)
@@ -6,20 +6,15 @@ module Serialization
6
6
 
7
7
  def serialize
8
8
  # коллекция записей / сущность для применения аггрегирования
9
- entity = @objects || @model.unscoped.merge(@scopes)
9
+ list = @objects || @model.unscoped.merge(@scopes)
10
10
 
11
- # применение сортировки и пагинации (если необходимо) к коллекции записей
12
- @objects =
13
- if @paginate
14
- entity.offset(@offset).merge(sort_proc).limit(@limit)
15
- else
16
- entity.merge(sort_proc)
17
- end
11
+ # применение сортировки и пагинации к коллекции записей
12
+ @objects = list.offset(@offset).merge(sort_proc).limit(@limit)
18
13
 
19
14
  # сериализация с помощью переданных полей или сериалайзера
20
15
  if @fields
21
16
  serialize_with_fields
22
- elsif @attrs[:entity]
17
+ elsif @grape_entity
23
18
  serialize_with_entity
24
19
  end
25
20
  end
@@ -36,8 +31,7 @@ module Serialization
36
31
  end
37
32
 
38
33
  def serialize_with_entity
39
- entity = @attrs[:entity].constantize
40
- @objects = @objects.map { |i| entity.represent(i, current_user: @current_user).as_json }
34
+ @objects = @objects.map { |i| @grape_entity.represent(i, current_user: @current_user).as_json }
41
35
  end
42
36
 
43
37
  def sort_proc
@@ -72,8 +66,8 @@ module Serialization
72
66
  end
73
67
  end
74
68
 
75
- def obtain_fields_values(object)
76
- @fields.map { |f| object.send(f) }
69
+ def obtain_fields_values(record)
70
+ @fields.map { |i| record.send(i) }
77
71
  end
78
72
 
79
73
  end
data/lib/paginated.rb CHANGED
@@ -6,21 +6,16 @@ class Paginated
6
6
  include Search
7
7
  include Serialization
8
8
 
9
- def collection(**attrs)
10
- @attrs = attrs
11
- @params = attrs[:serialization_scope].params.stringify_keys
12
- @current_user = attrs[:serialization_scope].current_user
13
- @fields = attrs[:fields]
14
- @scopes = attrs[:scopes] || {}
15
- @offset = @params['offset'].to_i
16
- @limit = @params['limit'] || 20
17
- @order = attrs[:order] || :id
18
- @sort = attrs[:sort]
19
- @model = attrs[:model].constantize
20
- @root = @params.key?('root') ? @params['root'] : false
21
- @paginate = @params.key?('paginate') ? @params['paginate'].to_s == 'true' : true
22
- @objects_count = records_count(attrs[:model])
9
+ def initialize(**args)
10
+ # обработка переданных аргументов
11
+ handle_args(**args)
12
+ end
13
+
14
+ def self.collection(**args)
15
+ new(**args).collection
16
+ end
23
17
 
18
+ def collection
24
19
  if @objects_count > 0
25
20
  search
26
21
  serialize
@@ -28,32 +23,56 @@ class Paginated
28
23
  @objects = []
29
24
  end
30
25
 
31
- if @root
32
- # записи в корне
33
- @objects
34
- else
35
- # результат с пагинацией
36
- { count: @objects_count, objects: @objects }
37
- end
26
+ # результат с пагинацией
27
+ { count: @objects_count, objects: @objects }
38
28
  end
39
29
 
40
- private
30
+ def handle_args(**args)
31
+ # обрабатываемая Rails модель
32
+ @model = args[:model]
33
+
34
+ # параметры запроса и текущий пользователь
35
+ serialization_scope = args[:serialization_scope]
36
+ @params = serialization_scope.params.stringify_keys
37
+ @current_user = serialization_scope.current_user
38
+
39
+ # поля, по которым возможен поиск
40
+ @search_fields = args[:search]
41
+
42
+ # сериализация - через Grape Entity или список полей
43
+ @grape_entity = args[:entity]
44
+ @fields = args[:fields]
45
+
46
+ # Rails scopes для применения
47
+ @scopes = args[:scopes] || {}
48
+
49
+ # offset / limit
50
+ @offset = @params['offset'].to_i
51
+ @limit = @params['limit'] || 20
52
+
53
+ # сортировка
54
+ @order = args[:order] || :id
55
+ @sort = args[:sort]
56
+
57
+ # подсчет кол-ва записей
58
+ @objects_count = records_count
59
+ end
41
60
 
42
- def records_count(model_name)
61
+ def records_count
43
62
  # получение кол-ва записей из кеша
44
- cache_key = "#{model_name}_records_count"
45
- cached_value = Rails.cache.read(cache_key)
46
- return cached_value if cached_value
63
+ cache_key = "#{@model}_records_count"
64
+ cached = Rails.cache.read(cache_key)
65
+ return cached if cached
47
66
 
48
67
  # получение кол-ва записей из запроса к БД
49
- db_value = @model.merge(@scopes).count(:id)
68
+ count = @model.merge(@scopes).count(:id)
50
69
 
51
70
  # кеширование кол-ва записей при превышении порогового значения
52
- if db_value >= 1_000
53
- Rails.cache.write(cache_key, db_value, expires_in: 30.minutes)
71
+ if count >= 1_000
72
+ Rails.cache.write(cache_key, count, expires_in: 30.minutes)
54
73
  end
55
74
 
56
- db_value
75
+ count
57
76
  end
58
77
 
59
78
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paginated
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Павел Бабин
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-17 00:00:00.000000000 Z
11
+ date: 2024-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubygems_version: 3.0.6
84
+ rubygems_version: 3.4.10
85
85
  signing_key:
86
86
  specification_version: 4
87
87
  summary: Пагинация для Rails-приложений