grape-listing 1.1.3.2 → 1.1.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
  SHA256:
3
- metadata.gz: 25983a60808ce493ed6c1ed4bd878f775f8d1774d59237b5ff7e67c4604093eb
4
- data.tar.gz: c0a525c0d05080d2a6bb465790883d1909d0ca93fe6fbe9b003f2a572e42b2b2
3
+ metadata.gz: ebde4f181db7c89e1def2eeb1af0fe820da5f89b0921dc88080d0b793f3d01ac
4
+ data.tar.gz: 5f077bb264dcf16c617be8a22c78e0769a1270af387ee2f171b78be398a35baa
5
5
  SHA512:
6
- metadata.gz: 760336dd3ddbd1eefb129d69f9667e278e8f3dff5818470b47d4ac5a20737493bf88a51f358e37151bccbaab8cde2f5dc6d13cc703b7e7fee204935f2ec13cec
7
- data.tar.gz: d03755555bd12a587dd9bf4d5de76c16f644bb2acaa220ddff1de5877a705debb0254f962dbd65513f22a290e75596def586ceecd6f28bdf0fd6ab60c2e9008b
6
+ metadata.gz: 0cc783b3c30a87083033d825a7d80624af8d513c55989b6cd572a9dea1786caa72bc1306f50bf1a5f6ca6f136e9008b4c08a6b93713d4e5da58b12e06684500d
7
+ data.tar.gz: dde882747da769a523f0c31b4862327d8b959f667a14e5b151b92dca8de9b609204467c2b9bfbfc79e19b75a2b27b49243184ac434bb7ee858a496371b6c6c78
data/README.md CHANGED
@@ -44,6 +44,8 @@ end
44
44
 
45
45
  `search: %w[...]` - список полей, по которым должна осуществляться фильтрация (поиск).
46
46
 
47
+ `paginate: false` - отдавать результат без пагинации, сразу всей коллекцией (по умолчанию - с пагинацией)
48
+
47
49
  ## Параметры HTTP запроса
48
50
 
49
51
  Некоторые функции, такие, как поиск (фильтрация), сортировка и формирование эл. таблиц осуществляется путем обработки параметров HTTP запроса.
data/lib/grape/dsl.rb CHANGED
@@ -2,21 +2,28 @@ module Grape
2
2
  module DSL
3
3
  module InsideRoute
4
4
 
5
- def listing(model:, entity:, scopes: nil, search: nil)
6
- opts = listing_opts(model, entity, scopes, search)
5
+ def listing(model:, entity:, scopes: nil, search: nil, paginate: true, caching: false)
6
+ # параметры запроса API
7
+ request_method = request.env['REQUEST_METHOD']
8
+ request_uri = request.env['REQUEST_URI']
9
+
10
+ # опции для сервиса
11
+ opts = listing_opts(model, entity, scopes, search, caching, request_method, request_uri)
7
12
 
8
13
  if params[:spreadsheet]
9
14
  listing_spreadsheet(**opts)
10
- else
15
+ elsif paginate
11
16
  GrapeListingService.paginated(**opts)
17
+ else
18
+ GrapeListingService.listed(**opts)
12
19
  end
13
20
  end
14
21
 
15
22
  private
16
23
 
17
- def listing_opts(model, entity, scopes, search)
24
+ def listing_opts(model, entity, scopes, search, caching, request_method, request_uri)
18
25
  # стандартные опции
19
- opts = { model:, entity:, scopes:, search:, params:, current_user: }
26
+ opts = { model:, entity:, scopes:, search:, params:, current_user:, caching:, request_method:, request_uri: }
20
27
 
21
28
  # требуемый список полей (+стандартные) для фильтрации в Grape Entity
22
29
  if params[:columns]
@@ -1,4 +1,5 @@
1
1
  require 'listing_service/args_handling'
2
+ require 'listing_service/listing'
2
3
  require 'listing_service/pagination'
3
4
  require 'listing_service/search'
4
5
  require 'listing_service/serialization'
@@ -8,6 +9,7 @@ require 'listing_service/spreadsheet'
8
9
  class GrapeListingService
9
10
 
10
11
  include GrapeListing::ArgsHandling
12
+ include GrapeListing::Listing
11
13
  include GrapeListing::Pagination
12
14
  include GrapeListing::Search
13
15
  include GrapeListing::Serialization
@@ -18,6 +20,10 @@ class GrapeListingService
18
20
  handle_args(**args)
19
21
  end
20
22
 
23
+ def self.listed(**args)
24
+ new(**args).listed
25
+ end
26
+
21
27
  def self.paginated(**args)
22
28
  new(**args).paginated
23
29
  end
@@ -7,6 +7,10 @@ module GrapeListing
7
7
  # обрабатываемая модель
8
8
  @model = args[:model]
9
9
 
10
+ # параметры адреса запроса API
11
+ @request_method = args[:request_method]
12
+ @request_uri = args[:request_uri]
13
+
10
14
  # параметры запроса и текущий пользователь
11
15
  @params = args[:params].stringify_keys
12
16
  @current_user = args[:current_user]
@@ -42,12 +46,15 @@ module GrapeListing
42
46
 
43
47
  # временная директория (для генерации файлов)
44
48
  @tempdir = args[:tempdir]
49
+
50
+ # кеширование результатов обработки Grape Entity
51
+ @caching = args[:caching]
45
52
  end
46
53
 
47
54
  def records_count
48
55
  # получение кол-ва записей из кеша
49
- cache_key = "#{@model}_records_count"
50
- cached = GrapeListing.cache.read(cache_key)
56
+ key = count_cache_key
57
+ cached = GrapeListing.cache.read(key)
51
58
  return cached if cached
52
59
 
53
60
  # получение кол-ва записей из запроса к БД
@@ -55,11 +62,19 @@ module GrapeListing
55
62
 
56
63
  # кеширование кол-ва записей при превышении порогового значения
57
64
  if count >= 1_000
58
- GrapeListing.cache.write(cache_key, count, expires_in: 30.minutes)
65
+ GrapeListing.cache.write(key, count, expires_in: 30.minutes)
59
66
  end
60
67
 
61
68
  count
62
69
  end
63
70
 
71
+ def count_cache_key
72
+ # пример: "GET api/v1/users?active=true"
73
+ body = "#{@request_method} #{@request_uri}"
74
+
75
+ enc = Digest::MD5.hexdigest(body)
76
+ "listing_cached_count_#{enc}"
77
+ end
78
+
64
79
  end
65
80
  end
@@ -0,0 +1,30 @@
1
+ module GrapeListing
2
+ module Listing
3
+
4
+ def listed
5
+ if @objects_count > 0
6
+ search
7
+ list
8
+ else
9
+ @objects = []
10
+ end
11
+
12
+ # результат
13
+ @objects
14
+ end
15
+
16
+ private
17
+
18
+ def list
19
+ # коллекция записей ActiveRecord для применения аггрегирования
20
+ list = @objects || @model.merge(@scopes)
21
+
22
+ # применение сортировки к коллекции записей
23
+ @objects = list.merge(sort_proc)
24
+
25
+ # сериализация с помощью переданных полей или сериалайзера
26
+ @objects = serialize(@objects)
27
+ end
28
+
29
+ end
30
+ end
@@ -23,20 +23,35 @@ module GrapeListing
23
23
  end
24
24
 
25
25
  def serialize_with_entity(records)
26
- opts = { params: @params, current_user: @current_user }
26
+ @entity_opts = { params: @params, current_user: @current_user }
27
27
 
28
28
  # требуемый список полей (если был передан)
29
- opts[:only] = @only_columns if @only_columns
29
+ @entity_opts[:only] = @only_columns if @only_columns
30
30
 
31
31
  # опция для идентификации формирования эл. таблицы
32
- opts[:spreadsheet] = true if @params['spreadsheet']
33
-
34
- records.map { |i| @grape_entity.represent(i, opts).as_json }
32
+ @entity_opts[:spreadsheet] = true if @params['spreadsheet']
33
+
34
+ # обработка результатов
35
+ records.map do |record|
36
+ if @caching
37
+ caching_entity_representation(record)
38
+ else
39
+ @grape_entity.represent(record, @entity_opts).as_json
40
+ end
41
+ end
35
42
  end
36
43
 
37
44
  def obtain_fields_values(record)
38
45
  @fields.map { |i| record.send(i) }
39
46
  end
40
47
 
48
+ def caching_entity_representation(record)
49
+ key = "#{@grape_entity}:#{record.id}"
50
+
51
+ GrapeListing.cache.fetch(key) do
52
+ @grape_entity.represent(record, @entity_opts).as_json
53
+ end
54
+ end
55
+
41
56
  end
42
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-listing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3.2
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Павел Бабин
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-25 00:00:00.000000000 Z
11
+ date: 2024-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -107,6 +107,7 @@ files:
107
107
  - lib/grape_listing/configuration.rb
108
108
  - lib/grape_listing_service.rb
109
109
  - lib/listing_service/args_handling.rb
110
+ - lib/listing_service/listing.rb
110
111
  - lib/listing_service/pagination.rb
111
112
  - lib/listing_service/search.rb
112
113
  - lib/listing_service/serialization.rb