grape-listing 1.1.0 → 1.1.2

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: f7ada8749162c0e09f2a0dad2712dbd31e3296d302266449e4c5edd7cea9b1d6
4
- data.tar.gz: 51afe0e601ad9e8f5d22d4c0d07031078cc9b6d1161cfd092a15dfb18265cd8b
3
+ metadata.gz: 475f3252f68c43b45789964dbfa412320f83dc4f23e60a51e084ce4c85fe2472
4
+ data.tar.gz: fb085471aab7e821f270b34643b479dddf686a294bc4830162b8e06015999422
5
5
  SHA512:
6
- metadata.gz: ff72f5cf03c2394347d8745e8c68429d85f793ce64f29eddc7d808f6b75fb81c4a4cb6d12bf5af8f707a999e2fe90d5269b4b310ebd6794819d65d0bfbeb7fe0
7
- data.tar.gz: 98e6cec6b17f9efa1fcbd1890a3d376539d2662240e6dfddb107ae729a96b1f8e2aea569f2adb183fb52639945159a3dcc7b0b24ce7e5ada098d055c2d1b1066
6
+ metadata.gz: e5e60e6c6e94d7dd830f05cccebef438e14590b576119b038a4f8255b90fb14f74de6f1d8d1cb67986ab85c0581c8a3ae47f08a85b8fe6fa792d0732df464481
7
+ data.tar.gz: 368098c1f481f028f0d3eaf31681c42e0f721e62c98bfe9c8ccbce28756cdc939960efcc49663acb193a3756be503bd6c3ad48d81e019422ee821b3d71123db9
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Grape Listing
2
- [![Gem Version](https://badge.fury.io/rb/paginated.svg)](https://badge.fury.io/rb/paginated)
2
+ [![Gem Version](https://badge.fury.io/rb/grape-listing.svg)](https://badge.fury.io/rb/grape-listing)
3
3
 
4
4
  Гем для пагинации и фильтрации записей с возможностью формирования электронных таблиц (XLSX) на базе Grape.
5
5
 
data/lib/grape/dsl.rb CHANGED
@@ -19,8 +19,8 @@ module Grape
19
19
  opts = { model:, entity:, scopes:, search:, params:, current_user: }
20
20
 
21
21
  # требуемый список полей (+стандартные) для фильтрации в Grape Entity
22
- if params[:columns] && !params[:spreadsheet]
23
- opts[:only_columns] = params[:columns] + %w[id deleted_at]
22
+ if params[:columns]
23
+ opts[:only_columns] = params[:spreadsheet] ? params[:columns] : params[:columns] + ['deleted_at']
24
24
  end
25
25
 
26
26
  opts
data/lib/grape_listing.rb CHANGED
@@ -4,4 +4,9 @@ require 'grape_listing/configuration'
4
4
  require 'grape_listing_service'
5
5
 
6
6
  module GrapeListing
7
+
8
+ def self.cache
9
+ @cache ||= ActiveSupport::Cache.lookup_store(:mem_cache_store)
10
+ end
11
+
7
12
  end
@@ -1,14 +1,16 @@
1
1
  require 'listing_service/args_handling'
2
- require 'listing_service/collection'
2
+ require 'listing_service/pagination'
3
3
  require 'listing_service/search'
4
+ require 'listing_service/serialization'
4
5
  require 'listing_service/sorting'
5
6
  require 'listing_service/spreadsheet'
6
7
 
7
8
  class GrapeListingService
8
9
 
9
10
  include GrapeListing::ArgsHandling
10
- include GrapeListing::Collection
11
+ include GrapeListing::Pagination
11
12
  include GrapeListing::Search
13
+ include GrapeListing::Serialization
12
14
  include GrapeListing::Sorting
13
15
  include GrapeListing::Spreadsheet
14
16
 
@@ -4,7 +4,7 @@ module GrapeListing
4
4
  private
5
5
 
6
6
  def handle_args(**args)
7
- # обрабатываемая Rails модель
7
+ # обрабатываемая модель
8
8
  @model = args[:model]
9
9
 
10
10
  # параметры запроса и текущий пользователь
@@ -18,7 +18,7 @@ module GrapeListing
18
18
  @grape_entity = args[:entity]
19
19
  @fields = args[:fields]
20
20
 
21
- # Rails scopes для применения
21
+ # scopes для применения
22
22
  @scopes = args[:scopes] || {}
23
23
 
24
24
  # offset / limit
@@ -47,7 +47,7 @@ module GrapeListing
47
47
  def records_count
48
48
  # получение кол-ва записей из кеша
49
49
  cache_key = "#{@model}_records_count"
50
- cached = Rails.cache.read(cache_key)
50
+ cached = GrapeListing.cache.read(cache_key)
51
51
  return cached if cached
52
52
 
53
53
  # получение кол-ва записей из запроса к БД
@@ -55,7 +55,7 @@ module GrapeListing
55
55
 
56
56
  # кеширование кол-ва записей при превышении порогового значения
57
57
  if count >= 1_000
58
- Rails.cache.write(cache_key, count, expires_in: 30.minutes)
58
+ GrapeListing.cache.write(cache_key, count, expires_in: 30.minutes)
59
59
  end
60
60
 
61
61
  count
@@ -0,0 +1,30 @@
1
+ module GrapeListing
2
+ module Pagination
3
+
4
+ def paginated
5
+ if @objects_count > 0
6
+ search
7
+ paginate
8
+ else
9
+ @objects = []
10
+ end
11
+
12
+ # результат с пагинацией
13
+ { count: @objects_count, objects: @objects }
14
+ end
15
+
16
+ private
17
+
18
+ def paginate
19
+ # коллекция записей ActiveRecord для применения аггрегирования
20
+ list = @objects || @model.unscoped.merge(@scopes)
21
+
22
+ # применение сортировки и пагинации к коллекции записей
23
+ @objects = list.offset(@offset).merge(sort_proc).limit(@limit)
24
+
25
+ # сериализация с помощью переданных полей или сериалайзера
26
+ @objects = serialize(@objects)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module GrapeListing
2
+ module Serialization
3
+
4
+ private
5
+
6
+ def serialize(records)
7
+ if @fields
8
+ serialize_with_fields(records)
9
+ elsif @grape_entity
10
+ serialize_with_entity(records)
11
+ end
12
+ end
13
+
14
+ def serialize_with_fields(records)
15
+ # добавление ID в список полей по умолчанию
16
+ @fields.push(:id)
17
+
18
+ # список массивов значений
19
+ records = records.map { |i| obtain_fields_values(i) }
20
+
21
+ # трансформация массивов значений в объекты (ключ-значение)
22
+ records.map { |i| @fields.zip(i).to_h }
23
+ end
24
+
25
+ def serialize_with_entity(records)
26
+ opts = { current_user: @current_user }
27
+
28
+ # требуемый список полей (если был передан)
29
+ opts[:only] = @only_columns if @only_columns
30
+
31
+ # опция для идентификации формирования эл. таблицы
32
+ opts[:spreadsheet] = true if @params['spreadsheet']
33
+
34
+ records.map { |i| @grape_entity.represent(i, opts).as_json }
35
+ end
36
+
37
+ def obtain_fields_values(record)
38
+ @fields.map { |i| record.send(i) }
39
+ end
40
+
41
+ end
42
+ end
@@ -4,6 +4,8 @@ module GrapeListing
4
4
  module Spreadsheet
5
5
 
6
6
  def spreadsheet
7
+ @spreadsheet_cols = @params['columns'].map(&:to_sym)
8
+
7
9
  # поиск и фильтрация
8
10
  search
9
11
 
@@ -13,13 +15,16 @@ module GrapeListing
13
15
  # ограничение записей
14
16
  records = records.order(:id).offset(@offset).limit(@limit)
15
17
 
18
+ # сериализация записей и превращение в объекты
19
+ objects = serialize(records)
20
+
16
21
  # формирования файла эл. таблицы
17
- generate_spreadsheet(records)
22
+ generate_spreadsheet(objects)
18
23
  end
19
24
 
20
25
  private
21
26
 
22
- def generate_spreadsheet(records)
27
+ def generate_spreadsheet(objects)
23
28
  filepath = "#{@tempdir}/#{Time.now.strftime('%Y%m%d_%H%M%S')}.xlsx"
24
29
 
25
30
  # создание таблицы и ее конфигурация
@@ -40,9 +45,8 @@ module GrapeListing
40
45
  worksheet.append_row(spreadsheet_titles, bold)
41
46
 
42
47
  # содержимое
43
- cols = spreadsheet_columns
44
- records.each do |record|
45
- values = cols.map { |col| record.send_chain(col) }
48
+ objects.each do |object|
49
+ values = object.slice(*@spreadsheet_cols).values
46
50
  worksheet.append_row(values)
47
51
  end
48
52
 
@@ -54,23 +58,30 @@ module GrapeListing
54
58
  end
55
59
 
56
60
  def spreadsheet_titles
57
- model_cols = @model.columns.to_h { |i| [i.name, i] }
61
+ values = []
62
+ entity_doc = @grape_entity.documentation
63
+ model_cols = @model.columns.to_h { |i| [i.name.to_sym, i] }
58
64
 
59
- @params['columns'].map do |column|
65
+ @spreadsheet_cols.each do |column|
66
+ # поиск описания среди комментариев к таблице БД
60
67
  db_col = model_cols[column]
61
-
62
- db_col.comment || column
68
+ if db_col&.comment&.present?
69
+ values << db_col.comment
70
+ next
71
+ end
72
+
73
+ # поиск описания среди комментариев к полям Grape Entity
74
+ doc = entity_doc[column]
75
+ if doc && doc[:desc]
76
+ values << doc[:desc]
77
+ next
78
+ end
79
+
80
+ # ничего из вышеперечисленного не найдено, заголовок - название самой колонки
81
+ values << column.upcase
63
82
  end
64
- end
65
83
 
66
- def spreadsheet_columns
67
- entity_doc = @grape_entity.documentation
68
-
69
- @params['columns'].map do |column|
70
- doc = entity_doc[column.to_sym]
71
-
72
- doc && doc[:sheet_method] ? doc[:sheet_method].split('.') : column
73
- end
84
+ values
74
85
  end
75
86
 
76
87
  end
metadata CHANGED
@@ -1,72 +1,100 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-listing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Павел Бабин
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-07 00:00:00.000000000 Z
11
+ date: 2024-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: fast_excel
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.5.0
19
+ version: '7.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.5.0
26
+ version: '7.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: grape
28
+ name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.0.0
33
+ version: '2.8'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.0.0
40
+ version: '2.8'
41
41
  - !ruby/object:Gem::Dependency
42
- name: grape-entity
42
+ name: dalli
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.0.0
47
+ version: 3.2.6
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.0.0
54
+ version: 3.2.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: fast_excel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.5.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: grape
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.0.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.0.0
55
83
  - !ruby/object:Gem::Dependency
56
- name: rails
84
+ name: grape-entity
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '7.0'
89
+ version: 1.0.0
62
90
  type: :runtime
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '7.0'
69
- description: Простая пагинация, поиск и формирование эл. таблиц для API на базе Grape
96
+ version: 1.0.0
97
+ description: Фильтрация, пагинация и формирование эл. таблиц на базе Grape
70
98
  email: babin359@gmail.com
71
99
  executables: []
72
100
  extensions: []
@@ -80,8 +108,9 @@ files:
80
108
  - lib/grape_listing/configuration.rb
81
109
  - lib/grape_listing_service.rb
82
110
  - lib/listing_service/args_handling.rb
83
- - lib/listing_service/collection.rb
111
+ - lib/listing_service/pagination.rb
84
112
  - lib/listing_service/search.rb
113
+ - lib/listing_service/serialization.rb
85
114
  - lib/listing_service/sorting.rb
86
115
  - lib/listing_service/spreadsheet.rb
87
116
  homepage:
@@ -104,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
133
  - !ruby/object:Gem::Version
105
134
  version: '0'
106
135
  requirements: []
107
- rubygems_version: 3.0.6
136
+ rubygems_version: 3.4.10
108
137
  signing_key:
109
138
  specification_version: 4
110
139
  summary: Формирование списков записей для API на базе Grape
@@ -1,58 +0,0 @@
1
- module GrapeListing
2
- module Collection
3
-
4
- def paginated
5
- if @objects_count > 0
6
- search
7
- serialize
8
- else
9
- @objects = []
10
- end
11
-
12
- # результат с пагинацией
13
- { count: @objects_count, objects: @objects }
14
- end
15
-
16
- private
17
-
18
- def serialize
19
- # коллекция записей ActiveRecord для применения аггрегирования
20
- list = @objects || @model.unscoped.merge(@scopes)
21
-
22
- # применение сортировки и пагинации к коллекции записей
23
- @objects = list.offset(@offset).merge(sort_proc).limit(@limit)
24
-
25
- # сериализация с помощью переданных полей или сериалайзера
26
- if @fields
27
- serialize_with_fields
28
- elsif @grape_entity
29
- serialize_with_entity
30
- end
31
- end
32
-
33
- def serialize_with_fields
34
- # добавление ID в список полей по умолчанию
35
- @fields.push(:id)
36
-
37
- # список массивов значений
38
- @objects = @objects.map { |i| obtain_fields_values(i) }
39
-
40
- # трансформация массивов значений в объекты (ключ-значение)
41
- @objects = @objects.map { |i| @fields.zip(i).to_h }
42
- end
43
-
44
- def serialize_with_entity
45
- opts = { current_user: @current_user }
46
-
47
- # требуемый список полей (если был передан)
48
- opts[:only] = @only_columns if @only_columns
49
-
50
- @objects = @objects.map { |i| @grape_entity.represent(i, opts).as_json }
51
- end
52
-
53
- def obtain_fields_values(record)
54
- @fields.map { |i| record.send(i) }
55
- end
56
-
57
- end
58
- end