nested_select 0.4.0 → 0.4.4

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.
@@ -0,0 +1,254 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ nested_select (0.4.4)
5
+ activerecord (>= 7)
6
+ activesupport (>= 7)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (8.0.2)
12
+ actionpack (= 8.0.2)
13
+ activesupport (= 8.0.2)
14
+ nio4r (~> 2.0)
15
+ websocket-driver (>= 0.6.1)
16
+ zeitwerk (~> 2.6)
17
+ actionmailbox (8.0.2)
18
+ actionpack (= 8.0.2)
19
+ activejob (= 8.0.2)
20
+ activerecord (= 8.0.2)
21
+ activestorage (= 8.0.2)
22
+ activesupport (= 8.0.2)
23
+ mail (>= 2.8.0)
24
+ actionmailer (8.0.2)
25
+ actionpack (= 8.0.2)
26
+ actionview (= 8.0.2)
27
+ activejob (= 8.0.2)
28
+ activesupport (= 8.0.2)
29
+ mail (>= 2.8.0)
30
+ rails-dom-testing (~> 2.2)
31
+ actionpack (8.0.2)
32
+ actionview (= 8.0.2)
33
+ activesupport (= 8.0.2)
34
+ nokogiri (>= 1.8.5)
35
+ rack (>= 2.2.4)
36
+ rack-session (>= 1.0.1)
37
+ rack-test (>= 0.6.3)
38
+ rails-dom-testing (~> 2.2)
39
+ rails-html-sanitizer (~> 1.6)
40
+ useragent (~> 0.16)
41
+ actiontext (8.0.2)
42
+ actionpack (= 8.0.2)
43
+ activerecord (= 8.0.2)
44
+ activestorage (= 8.0.2)
45
+ activesupport (= 8.0.2)
46
+ globalid (>= 0.6.0)
47
+ nokogiri (>= 1.8.5)
48
+ actionview (8.0.2)
49
+ activesupport (= 8.0.2)
50
+ builder (~> 3.1)
51
+ erubi (~> 1.11)
52
+ rails-dom-testing (~> 2.2)
53
+ rails-html-sanitizer (~> 1.6)
54
+ activejob (8.0.2)
55
+ activesupport (= 8.0.2)
56
+ globalid (>= 0.3.6)
57
+ activemodel (8.0.2)
58
+ activesupport (= 8.0.2)
59
+ activerecord (8.0.2)
60
+ activemodel (= 8.0.2)
61
+ activesupport (= 8.0.2)
62
+ timeout (>= 0.4.0)
63
+ activestorage (8.0.2)
64
+ actionpack (= 8.0.2)
65
+ activejob (= 8.0.2)
66
+ activerecord (= 8.0.2)
67
+ activesupport (= 8.0.2)
68
+ marcel (~> 1.0)
69
+ activesupport (8.0.2)
70
+ base64
71
+ benchmark (>= 0.3)
72
+ bigdecimal
73
+ concurrent-ruby (~> 1.0, >= 1.3.1)
74
+ connection_pool (>= 2.2.5)
75
+ drb
76
+ i18n (>= 1.6, < 2)
77
+ logger (>= 1.4.2)
78
+ minitest (>= 5.1)
79
+ securerandom (>= 0.3)
80
+ tzinfo (~> 2.0, >= 2.0.5)
81
+ uri (>= 0.13.1)
82
+ amazing_print (1.7.2)
83
+ appraisal (2.5.0)
84
+ bundler
85
+ rake
86
+ thor (>= 0.14.0)
87
+ ast (2.4.3)
88
+ base64 (0.2.0)
89
+ benchmark (0.4.0)
90
+ bigdecimal (3.1.9)
91
+ builder (3.3.0)
92
+ byebug (12.0.0)
93
+ concurrent-ruby (1.3.5)
94
+ connection_pool (2.5.3)
95
+ crass (1.0.6)
96
+ date (3.4.1)
97
+ drb (2.2.1)
98
+ erubi (1.13.1)
99
+ globalid (1.2.1)
100
+ activesupport (>= 6.1)
101
+ i18n (1.14.7)
102
+ concurrent-ruby (~> 1.0)
103
+ io-console (0.8.0)
104
+ irb (1.15.2)
105
+ pp (>= 0.6.0)
106
+ rdoc (>= 4.0.0)
107
+ reline (>= 0.4.2)
108
+ json (2.11.3)
109
+ language_server-protocol (3.17.0.4)
110
+ lint_roller (1.1.0)
111
+ logger (1.7.0)
112
+ loofah (2.24.0)
113
+ crass (~> 1.0.2)
114
+ nokogiri (>= 1.12.0)
115
+ mail (2.8.1)
116
+ mini_mime (>= 0.1.1)
117
+ net-imap
118
+ net-pop
119
+ net-smtp
120
+ marcel (1.0.4)
121
+ mini_mime (1.1.5)
122
+ minitest (5.25.5)
123
+ net-imap (0.5.8)
124
+ date
125
+ net-protocol
126
+ net-pop (0.1.2)
127
+ net-protocol
128
+ net-protocol (0.2.2)
129
+ timeout
130
+ net-smtp (0.5.1)
131
+ net-protocol
132
+ niceql (0.6.1)
133
+ nio4r (2.7.4)
134
+ nokogiri (1.18.8-x86_64-linux-gnu)
135
+ racc (~> 1.4)
136
+ parallel (1.27.0)
137
+ parser (3.3.8.0)
138
+ ast (~> 2.4.1)
139
+ racc
140
+ pp (0.6.2)
141
+ prettyprint
142
+ prettyprint (0.2.0)
143
+ prism (1.4.0)
144
+ psych (5.2.4)
145
+ date
146
+ stringio
147
+ racc (1.8.1)
148
+ rack (3.1.13)
149
+ rack-session (2.1.0)
150
+ base64 (>= 0.1.0)
151
+ rack (>= 3.0.0)
152
+ rack-test (2.2.0)
153
+ rack (>= 1.3)
154
+ rackup (2.2.1)
155
+ rack (>= 3)
156
+ rails (8.0.2)
157
+ actioncable (= 8.0.2)
158
+ actionmailbox (= 8.0.2)
159
+ actionmailer (= 8.0.2)
160
+ actionpack (= 8.0.2)
161
+ actiontext (= 8.0.2)
162
+ actionview (= 8.0.2)
163
+ activejob (= 8.0.2)
164
+ activemodel (= 8.0.2)
165
+ activerecord (= 8.0.2)
166
+ activestorage (= 8.0.2)
167
+ activesupport (= 8.0.2)
168
+ bundler (>= 1.15.0)
169
+ railties (= 8.0.2)
170
+ rails-dom-testing (2.2.0)
171
+ activesupport (>= 5.0.0)
172
+ minitest
173
+ nokogiri (>= 1.6)
174
+ rails-html-sanitizer (1.6.2)
175
+ loofah (~> 2.21)
176
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
177
+ rails-i18n (8.0.1)
178
+ i18n (>= 0.7, < 2)
179
+ railties (>= 8.0.0, < 9)
180
+ rails_sql_prettifier (7.0.7)
181
+ activerecord (>= 7)
182
+ niceql (~> 0.6)
183
+ railties (8.0.2)
184
+ actionpack (= 8.0.2)
185
+ activesupport (= 8.0.2)
186
+ irb (~> 1.13)
187
+ rackup (>= 1.0.0)
188
+ rake (>= 12.2)
189
+ thor (~> 1.0, >= 1.2.2)
190
+ zeitwerk (~> 2.6)
191
+ rainbow (3.1.1)
192
+ rake (13.2.1)
193
+ rdoc (6.13.1)
194
+ psych (>= 4.0.0)
195
+ regexp_parser (2.10.0)
196
+ reline (0.6.1)
197
+ io-console (~> 0.5)
198
+ rubocop (1.75.4)
199
+ json (~> 2.3)
200
+ language_server-protocol (~> 3.17.0.2)
201
+ lint_roller (~> 1.1.0)
202
+ parallel (~> 1.10)
203
+ parser (>= 3.3.0.2)
204
+ rainbow (>= 2.2.2, < 4.0)
205
+ regexp_parser (>= 2.9.3, < 3.0)
206
+ rubocop-ast (>= 1.44.0, < 2.0)
207
+ ruby-progressbar (~> 1.7)
208
+ unicode-display_width (>= 2.4.0, < 4.0)
209
+ rubocop-ast (1.44.1)
210
+ parser (>= 3.3.7.2)
211
+ prism (~> 1.4)
212
+ rubocop-shopify (2.17.0)
213
+ rubocop (~> 1.62)
214
+ ruby-progressbar (1.13.0)
215
+ securerandom (0.4.1)
216
+ sqlite3 (2.6.0-x86_64-linux-gnu)
217
+ stringio (3.1.7)
218
+ stubberry (0.3.0)
219
+ thor (1.3.2)
220
+ timeout (0.4.3)
221
+ tzinfo (2.0.6)
222
+ concurrent-ruby (~> 1.0)
223
+ unicode-display_width (3.1.4)
224
+ unicode-emoji (~> 4.0, >= 4.0.4)
225
+ unicode-emoji (4.0.4)
226
+ uri (1.0.3)
227
+ useragent (0.16.11)
228
+ websocket-driver (0.7.7)
229
+ base64
230
+ websocket-extensions (>= 0.1.0)
231
+ websocket-extensions (0.1.5)
232
+ zeitwerk (2.7.2)
233
+
234
+ PLATFORMS
235
+ x86_64-linux-gnu
236
+
237
+ DEPENDENCIES
238
+ amazing_print
239
+ appraisal
240
+ bundler (>= 1.11)
241
+ byebug
242
+ minitest (~> 5.16)
243
+ nested_select!
244
+ rails (>= 8)
245
+ rails-i18n (>= 4)
246
+ rails_sql_prettifier
247
+ rake (~> 13.0)
248
+ rubocop (~> 1.21)
249
+ rubocop-shopify
250
+ sqlite3
251
+ stubberry
252
+
253
+ BUNDLED WITH
254
+ 2.5.11
@@ -7,22 +7,12 @@ module NestedSelect
7
7
  merge!(other.except(*keys))
8
8
  merge!(other.slice(*keys).map{ |key, value| [key, [self[key], value].flatten.deep_combine_elements]}.to_h )
9
9
  end
10
-
11
- def relation_nesting_depth
12
- 1 + [*values.grep(Hash), *values.grep(Array)].map(&:relation_nesting_depth).max.to_i
13
- end
14
10
  end
15
11
 
16
12
  refine Array do
17
13
  def deep_combine_elements
18
14
  [*grep_v(Hash), grep(Hash).inject(&:deep_combine)].uniq.compact
19
15
  end
20
- # in terms of relation/selection nesting every array node
21
- # should not add +1 to depth, that mean that array nesting
22
- # does not count as nesting [[[]]] has depth equal 0.
23
- def relation_nesting_depth
24
- [*grep(Hash), *grep(Array)].map(&:relation_nesting_depth).max.to_i
25
- end
26
16
  end
27
17
  end
28
18
  end
@@ -4,17 +4,27 @@ module NestedSelect
4
4
  attr_reader :nested_select_values
5
5
 
6
6
  def build_scope
7
- nested_select_values.blank? ? super :
8
- super.select(*nested_select_values.grep_v(Hash).map{_1.try(:to_s) }.uniq)
7
+ association_nested_select_values.blank? ? super : super.select(association_nested_select_values)
9
8
  end
10
9
 
11
10
  def apply_nested_select_values(partial_select_values)
11
+ @nested_select_values = [*partial_select_values]
12
+ ensure_nesting_selection_integrity!(association_nested_select_values)
13
+ end
14
+ def reflection_relation_keys_attributes
12
15
  foreign_key = reflection.foreign_key unless reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection)
13
- @nested_select_values = [*partial_select_values, *foreign_key, *reflection.klass.primary_key]
14
- ensure_nesting_selection_integrity!
16
+ [*foreign_key, *reflection.klass.primary_key].map(&:to_s)
17
+ end
18
+
19
+ def association_nested_select_values
20
+ this_association_select_values = nested_select_values&.grep_v(Hash)&.map {_1.try(:to_s) }
21
+ return if this_association_select_values.blank?
22
+
23
+ [*this_association_select_values, *reflection_relation_keys_attributes].uniq
15
24
  end
16
25
 
17
- def ensure_nesting_selection_integrity!
26
+ # ensure that different preloading branches will match nested selected attributes
27
+ def ensure_nesting_selection_integrity!(nested_select_final_values)
18
28
  single_owner = owners.first
19
29
  # do nothing unless not yet loaded
20
30
  return unless single_owner.association(reflection.name).loaded?
@@ -25,7 +35,7 @@ module NestedSelect
25
35
  single_reflection_record = single_reflection_record.first if single_reflection_record.is_a?(Enumerable)
26
36
 
27
37
  attributes_loaded = single_reflection_record.attributes.keys.map(&:to_s)
28
- current_selection = @nested_select_values.grep_v(Hash).map(&:to_s)
38
+ current_selection = nested_select_final_values.grep_v(Hash).map(&:to_s)
29
39
 
30
40
  basic_attributes_matched = (attributes_loaded & reflection.klass.column_names).tally ==
31
41
  (current_selection & reflection.klass.column_names).tally
@@ -23,7 +23,7 @@ module NestedSelect
23
23
 
24
24
  raise ActiveModel::MissingAttributeError, <<~ERR
25
25
  Parent reflection #{parent.association} was missing foreign key #{reflection.foreign_key} in nested selection,
26
- while trying to preload belongs_to reflection named #{reflection.name}.
26
+ while trying to preload belongs_to reflection named #{reflection.name}.
27
27
  Hint: didn't you forgot to add #{reflection.foreign_key} inside #{parent.nested_select_values}?
28
28
  ERR
29
29
  end
@@ -1,20 +1,6 @@
1
1
  module NestedSelect
2
2
  module Preloader
3
3
  module ThroughAssociation
4
- # this preloader root will preload intermediate records, so here we should apply 'through'
5
- # selection limitation AS A BASIC nested selection and it wuold be either __minimize_through_selection sym OR
6
- # nested_selection tree
7
- # def source_preloaders
8
- # @source_preloaders ||= ActiveRecord::Associations::Preloader.new(
9
- # records: middle_records,
10
- # associations: source_reflection.name,
11
- # scope: scope,
12
- # associate_by_default: false
13
- # ).tap {
14
- # byebug
15
- # _1.apply_nested_select_values([*@limit_through_selection])
16
- # }.loaders
17
- # end
18
4
  def through_preloaders
19
5
  @through_preloaders ||= ActiveRecord::Associations::Preloader.new(
20
6
  records: owners,
@@ -22,62 +8,14 @@ module NestedSelect
22
8
  scope: through_scope,
23
9
  associate_by_default: false,
24
10
  ).tap do
25
- _1.apply_nested_select_values(nested_select_values.grep(Hash))
11
+ _1.apply_nested_select_values(nested_select_values&.grep(Hash))
26
12
  end.loaders
27
13
  end
28
14
 
29
- # def through_scope
30
- # if @limit_through_selection.present?
31
- # # through_selection is either __minimize_through_selection symbol, or an array
32
- # through_selection = [*@limit_through_selection]
33
- # through_selection = [*through_selection.grep_v(Hash),
34
- # *through_selection.grep(Hash).first&.dig(through_reflection.source_reflection_name)]
35
- # through_selection << through_reflection.foreign_key
36
- # through_selection << through_reflection.klass.primary_key
37
- # super.select(through_selection)
38
- # else
39
- # super
40
- # end
41
- # end
42
-
43
- # def through_scope
44
- # if @limit_through_selection.present?
45
- # super.select(through_reflection.foreign_key.to_sym, through_reflection.klass.primary_key.to_sym)
46
- # else
47
- # super
48
- # end
49
- # end
50
- # def through_selection_nesting
51
- # return if @limit_through_selection.blank?
52
- # through_limit_selection = [through_reflection.foreign_key.to_sym, through_reflection.klass.primary_key.to_sym]
53
- # through_limit_selection << :__minimize_through_selection if through_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
54
- # through_limit_selection
55
- # end
56
-
57
- def apply_nested_select_values(partial_select_values)
58
-
59
- if reflection.parent_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
60
- # when parent reflection is a HasAndBelongsToManyReflection,
61
- # then we don't need foreign_key to be included, as it does in super
62
- @nested_select_values = partial_select_values
63
- else
64
- @limit_through_selection = partial_select_values.delete(:__minimize_through_selection)
65
- super(partial_select_values)
66
- end
15
+ def reflection_relation_keys_attributes
16
+ foreign_key = reflection.foreign_key unless reflection.parent_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
17
+ [*foreign_key, *reflection.klass.primary_key].map(&:to_s)
67
18
  end
68
- # def exract_through_selections(partial_select_values)
69
- # # __minimize_through_selection: [ :user_id, user_profile: [] ]
70
- # # there should not be more than one such limitation definition
71
- # through_selection_rules, cleaned_partial_select_values = partial_select_values&.partition do
72
- # _1 == :__minimize_through_selection || _1.is_a?(Hash) && _1[:__minimize_through_selection].present?
73
- # end
74
- # @limit_through_selection = through_selection_rules.map do
75
- # _1.is_a?(Hash) && _1[:__minimize_through_selection] || _1
76
- # end.first
77
- #
78
- # byebug
79
- # cleaned_partial_select_values
80
- # end
81
19
 
82
20
  end
83
21
  end
@@ -18,13 +18,6 @@ module NestedSelect
18
18
  distribute_nested_select_over_loading_tree(@tree, nested_select_values)
19
19
  end
20
20
 
21
- # this one either subtree roots only when its first, OR current branch selection root
22
- # + its branches in array
23
- # 1) [:__minimize_through_selection, ...]
24
- # 2) []
25
- # Логика следующая:
26
- # если мы передаем __minimize_through_selection как символ, то его надо пробросить до всех бранчей, они с этим разберутся, там где надо
27
- # если у нас там хеш, то его надо оставить на текущем уровне и дальше если это through, то оно превратит это в нестед селект для вложенных
28
21
  def distribute_nested_select_over_loading_tree(sub_tree, nested_select_values)
29
22
  # nested_select_values = [:id, :title, comments: [:id, :body], cover: [:id, img: [:url]]]
30
23
  return if nested_select_values.blank?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NestedSelect
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.4"
5
5
  end
data/lib/nested_select.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require "logger" # Fix concurrent-ruby removing logger dependency which Rails itself does not have
2
3
  require_relative "nested_select/version"
3
4
 
4
5
  module NestedSelect
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nested_select
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - alekseyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-09 00:00:00.000000000 Z
11
+ date: 2025-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: appraisal
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
181
195
  description: ActiveRecord improved select on nested models, allows partial instantiation
182
196
  on nested models, easy one step improvements on performance and memory
183
197
  email:
@@ -186,21 +200,25 @@ executables: []
186
200
  extensions: []
187
201
  extra_rdoc_files: []
188
202
  files:
189
- - ".idea/.gitignore"
190
- - ".idea/inspectionProfiles/profiles_settings.xml"
191
- - ".idea/misc.xml"
192
- - ".idea/modules.xml"
193
- - ".idea/nested_select.iml"
194
- - ".idea/vcs.xml"
195
203
  - ".rubocop.yml"
196
204
  - ABOUT_NESTED_SELECT.md
205
+ - Appraisals
197
206
  - CHANGELOG.md
198
207
  - CODE_OF_CONDUCT.md
199
208
  - Dockerfile
209
+ - Dockerfile_apprsl
200
210
  - LICENSE.txt
201
211
  - README.md
202
212
  - Rakefile
203
213
  - docker-compose.yml
214
+ - gemfiles/rails_7.0.gemfile
215
+ - gemfiles/rails_7.0.gemfile.lock
216
+ - gemfiles/rails_7.1.gemfile
217
+ - gemfiles/rails_7.1.gemfile.lock
218
+ - gemfiles/rails_7.2.gemfile
219
+ - gemfiles/rails_7.2.gemfile.lock
220
+ - gemfiles/rails_8.gemfile
221
+ - gemfiles/rails_8.gemfile.lock
204
222
  - lib/nested_select.rb
205
223
  - lib/nested_select/deep_merger.rb
206
224
  - lib/nested_select/preloader.rb
@@ -210,7 +228,6 @@ files:
210
228
  - lib/nested_select/relation.rb
211
229
  - lib/nested_select/version.rb
212
230
  - sig/nested_select.rbs
213
- - test_habtm_reflections.rb
214
231
  homepage: https://github.com/alekseyl/nested_select
215
232
  licenses:
216
233
  - MIT
data/.idea/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- # Default ignored files
2
- /shelf/
3
- /workspace.xml
4
- # Editor-based HTTP Client requests
5
- /httpRequests/
6
- # Datasource local storage ignored files
7
- /dataSources/
8
- /dataSources.local.xml
@@ -1,5 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <settings>
3
- <option name="PROJECT_PROFILE" />
4
- </settings>
5
- </component>
data/.idea/misc.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="NodePackageJsonFileManager">
4
- <packageJsonPaths />
5
- </component>
6
- </project>
data/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/nested_select.iml" filepath="$PROJECT_DIR$/.idea/nested_select.iml" />
6
- </modules>
7
- </component>
8
- </project>