deep_pluck 1.1.5 → 1.1.6

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: 542e1ba086c4b2a8df7fb4efbf916c3448f207824717272e67bbba581154b3dc
4
- data.tar.gz: 6710c826f3ae127d4530863b690541fe048ac6f8b3fc54a18e2da8ecd8629ee4
3
+ metadata.gz: 841be04c39fa82bd474ad84bbe457ba263866dd62ece7ad865665c5dc354287a
4
+ data.tar.gz: 0a8d86976dc2b9992a5b7844649b3feb54d81d8003db4432b89abd5b07b802b4
5
5
  SHA512:
6
- metadata.gz: c8c17c52a55de2a7de18ecf762adefe017f05cef401f4e0098d8ce0b5699898ac97918cbede23f802ed8ff4709c1b5655938d64c3511e72494e9777a2ec98e5e
7
- data.tar.gz: 21aae7d86d41d53d4b05824ba13a5b7e9c7486ae9f83552146891f62397d8b03e5fc7b6b99c71c60837782d608767a8054e4674af72c2c0fbd655a1e324627a1
6
+ metadata.gz: fae5ce13839ec7b5f3b94423a0c80822320191b0232c7b793624ac2b303f2215f00aab05841a0e4f8091a1a7f56ae903e282d7c4b4ecbc90579a568c96a0873e
7
+ data.tar.gz: 69b200b8ffab3981631d41002ecc91731aed9f79a8dbbd5854218778fd9ea18bfb901af9998a62dfc8a526c41fdf8f87f8e343e95d966ab19416d17bde9d060a
data/.github/FUNDING.yml CHANGED
File without changes
@@ -0,0 +1,62 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ paths-ignore:
6
+ - 'README.md'
7
+ - 'CHANGELOG.md'
8
+ pull_request:
9
+ branches: [ master ]
10
+ paths-ignore:
11
+ - 'README.md'
12
+ - 'CHANGELOG.md'
13
+
14
+ jobs:
15
+ test:
16
+ runs-on: ubuntu-latest
17
+ name: Test
18
+ if: "contains(github.event.commits[0].message, '[ci skip]') == false"
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ ruby:
23
+ - 2.2
24
+ - 2.6
25
+ - 2.7
26
+ gemfile:
27
+ - 3.2.gemfile
28
+ - 4.2.gemfile
29
+ - 5.0.gemfile
30
+ - 5.1.gemfile
31
+ - 5.2.gemfile
32
+ - 6.0.gemfile
33
+ - 6.1.gemfile
34
+ exclude:
35
+ - gemfile: 3.2.gemfile
36
+ ruby: 2.6
37
+ - gemfile: 3.2.gemfile
38
+ ruby: 2.7
39
+ - gemfile: 4.2.gemfile
40
+ ruby: 2.7
41
+ - gemfile: 6.0.gemfile
42
+ ruby: 2.2
43
+ - gemfile: 6.1.gemfile
44
+ ruby: 2.2
45
+ env:
46
+ BUNDLE_GEMFILE: "gemfiles/${{ matrix.gemfile }}"
47
+
48
+ steps:
49
+ - name: Checkout
50
+ uses: actions/checkout@v2
51
+ - name: Setup Ruby
52
+ uses: ruby/setup-ruby@v1
53
+ with:
54
+ ruby-version: ${{ matrix.ruby }}
55
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
56
+ - name: Run tests
57
+ run: bundle exec rake
58
+ - name: Publish code coverage
59
+ if: ${{ success() }}
60
+ uses: paambaati/codeclimate-action@v2.7.5
61
+ env:
62
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
data/.gitignore CHANGED
File without changes
data/.rubocop.yml CHANGED
File without changes
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Change Log
2
2
 
3
+ ### [v1.1.5](https://github.com/khiav223577/deep_pluck/compare/v1.1.4...v1.1.5) 2021/01/10
4
+ - [#39](https://github.com/khiav223577/deep_pluck/pull/39) Compatibility with Rails 6.1.1 (@klausbadelt)
5
+ - [#40](https://github.com/khiav223577/deep_pluck/pull/40) Exclude tests from coverage (@klausbadelt)
6
+
3
7
  ### [v1.1.4](https://github.com/khiav223577/deep_pluck/compare/v1.1.3...v1.1.4) 2020/01/13
4
8
  - [#36](https://github.com/khiav223577/deep_pluck/pull/36) A workaround to fix mismatched association named. (@khiav223577)
5
9
  - [#35](https://github.com/khiav223577/deep_pluck/pull/35) Support Ruby 2.7 (@khiav223577)
data/CODE_OF_CONDUCT.md CHANGED
File without changes
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # DeepPluck
2
2
 
3
3
  [![Gem Version](https://img.shields.io/gem/v/deep_pluck.svg?style=flat)](http://rubygems.org/gems/deep_pluck)
4
- [![Build Status](https://travis-ci.org/khiav223577/deep_pluck.svg?branch=master)](https://travis-ci.org/khiav223577/deep_pluck)
4
+ [![Build Status](https://github.com/khiav223577/deep_pluck/workflows/Ruby/badge.svg)](https://github.com/khiav223577/deep_pluck/actions)
5
5
  [![RubyGems](http://img.shields.io/gem/dt/deep_pluck.svg?style=flat)](http://rubygems.org/gems/deep_pluck)
6
6
  [![Code Climate](https://codeclimate.com/github/khiav223577/deep_pluck/badges/gpa.svg)](https://codeclimate.com/github/khiav223577/deep_pluck)
7
7
  [![Test Coverage](https://codeclimate.com/github/khiav223577/deep_pluck/badges/coverage.svg)](https://codeclimate.com/github/khiav223577/deep_pluck/coverage)
data/Rakefile CHANGED
File without changes
data/bin/console CHANGED
File without changes
data/bin/setup CHANGED
File without changes
data/deep_pluck.gemspec CHANGED
@@ -41,5 +41,5 @@ Gem::Specification.new do |spec|
41
41
 
42
42
  spec.add_dependency 'activerecord', '>= 3'
43
43
  spec.add_dependency 'pluck_all', '>= 1.2.3'
44
- spec.add_dependency 'rails_compatibility', '>= 0.0.1'
44
+ spec.add_dependency 'rails_compatibility', '>= 0.0.3'
45
45
  end
data/gemfiles/3.2.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 3.2.0'
4
4
  gem 'pluck_all', '~> 1.2.2'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.3.6'
9
9
  end
10
10
 
data/gemfiles/4.2.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 4.2.0'
4
4
  gem 'pluck_all', '~> 1.2.2'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.3.6'
9
9
  end
10
10
 
data/gemfiles/5.0.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 5.0.0'
4
4
  gem 'pluck_all', '~> 1.2.2'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.3.6'
9
9
  end
10
10
 
data/gemfiles/5.1.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 5.1.0'
4
4
  gem 'pluck_all', '~> 1.2.2'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.3.6'
9
9
  end
10
10
 
data/gemfiles/5.2.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 5.2.0'
4
4
  gem 'pluck_all', '~> 1.2.2'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.3.6'
9
9
  end
10
10
 
data/gemfiles/6.0.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 6.0.0'
4
4
  gem 'pluck_all', '~> 2.0.4'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.4.1'
9
9
  end
10
10
 
data/gemfiles/6.1.gemfile CHANGED
@@ -4,7 +4,7 @@ gem 'activerecord', '~> 6.1.1'
4
4
  gem 'pluck_all', '~> 2.2.1'
5
5
 
6
6
  group :test do
7
- gem 'simplecov'
7
+ gem 'simplecov', '< 0.18'
8
8
  gem 'sqlite3', '~> 1.4.1'
9
9
  end
10
10
 
data/lib/deep_pluck.rb CHANGED
File without changes
File without changes
@@ -1,225 +1,229 @@
1
- require 'rails_compatibility'
2
- require 'rails_compatibility/unscope_where'
3
- require 'deep_pluck/data_combiner'
4
-
5
- module DeepPluck
6
- class Model
7
- # ----------------------------------------------------------------
8
- # ● Initialize
9
- # ----------------------------------------------------------------
10
- def initialize(relation, parent_association_key = nil, parent_model = nil, need_columns: [])
11
- if relation.is_a?(ActiveRecord::Base)
12
- @model = relation
13
- @relation = nil
14
- @klass = @model.class
15
- else
16
- @model = nil
17
- @relation = relation
18
- @klass = @relation.klass
19
- end
20
-
21
- @parent_association_key = parent_association_key
22
- @parent_model = parent_model
23
- @need_columns = need_columns
24
- @associations = {}
25
- end
26
-
27
- # ----------------------------------------------------------------
28
- # ● Reader
29
- # ----------------------------------------------------------------
30
- def get_reflect(association_key)
31
- @klass.reflect_on_association(association_key.to_sym) || # add to_sym since rails 3 only support symbol
32
- fail(ActiveRecord::ConfigurationError, "ActiveRecord::ConfigurationError: Association named \
33
- '#{association_key}' was not found on #{@klass.name}; perhaps you misspelled it?"
34
- )
35
- end
36
-
37
- def with_conditions(reflect, relation)
38
- options = reflect.options
39
- relation = relation.instance_exec(&reflect.scope) if reflect.respond_to?(:scope) and reflect.scope
40
- relation = relation.where(options[:conditions]) if options[:conditions]
41
- return relation
42
- end
43
-
44
- def get_join_table(reflect)
45
- options = reflect.options
46
- return options[:through] if options[:through]
47
- return (options[:join_table] || reflect.send(:derive_join_table)) if reflect.macro == :has_and_belongs_to_many
48
- return nil
49
- end
50
-
51
- def get_primary_key(reflect)
52
- return (reflect.belongs_to? ? reflect.klass : reflect.active_record).primary_key
53
- end
54
-
55
- def get_foreign_key(reflect, reverse: false, with_table_name: false)
56
- reflect = reflect.chain.last
57
- if reverse and (table_name = get_join_table(reflect)) # reverse = parent
58
- key = reflect.chain.last.foreign_key
59
- else
60
- key = (reflect.belongs_to? == reverse ? get_primary_key(reflect) : reflect.foreign_key)
61
- table_name = (reverse ? reflect.klass : reflect.active_record).table_name
62
- end
63
- return "#{table_name}.#{key}" if with_table_name
64
- return key.to_s # key may be symbol if specify foreign_key in association options
65
- end
66
-
67
- def get_association_scope(reflect)
68
- RailsCompatibility.unscope_where(reflect.association_class.new({}, reflect).send(:association_scope))
69
- end
70
-
71
- def use_association_to_query?(reflect)
72
- reflect.through_reflection && reflect.chain.first.macro == :has_one
73
- end
74
-
75
- # ----------------------------------------------------------------
76
- # ● Contruction OPs
77
- # ----------------------------------------------------------------
78
-
79
- private
80
-
81
- def add_need_column(column)
82
- @need_columns << column
83
- end
84
-
85
- def add_association(hash)
86
- hash.each do |key, value|
87
- model = (@associations[key] ||= Model.new(get_reflect(key).klass.where(''), key, self))
88
- model.add(value)
89
- end
90
- end
91
-
92
- public
93
-
94
- def add(args)
95
- return self if args == nil
96
- args = [args] if not args.is_a?(Array)
97
- args.each do |arg|
98
- case arg
99
- when Hash ; add_association(arg)
100
- else ; add_need_column(arg)
101
- end
102
- end
103
- return self
104
- end
105
-
106
- # ----------------------------------------------------------------
107
- # ● Load
108
- # ----------------------------------------------------------------
109
- private
110
-
111
- def do_query(parent, reflect, relation)
112
- parent_key = get_foreign_key(reflect)
113
- relation_key = get_foreign_key(reflect, reverse: true, with_table_name: true)
114
- ids = parent.map{|s| s[parent_key] }
115
- ids.uniq!
116
- ids.compact!
117
- relation = with_conditions(reflect, relation)
118
- query = { relation_key => ids }
119
- query[reflect.type] = reflect.active_record.to_s if reflect.type
120
-
121
- return get_association_scope(reflect).where(query) if use_association_to_query?(reflect)
122
-
123
- join_table = get_join_table(reflect)
124
- join_table = backtrace_possible_association(relation, join_table)
125
-
126
- return relation.joins(join_table).where(query)
127
- end
128
-
129
- # Let city has_many :users, through: :schools
130
- # And the query is: City.deep_pluck('users' => :name)
131
- # We want to get the users data via `User.joins(:school).where(city_id: city_ids)`
132
- # But get_join_table(reflect) returns `:schools` not :school
133
- # No idea how to get the right association, so we try singularize or pluralize it.
134
- def backtrace_possible_association(relation, join_table)
135
- return join_table if relation.reflect_on_association(join_table)
136
- join_table.to_s.singularize.to_sym.tap{|s| return s if relation.reflect_on_association(s) }
137
- join_table.to_s.pluralize.to_sym.tap{|s| return s if relation.reflect_on_association(s) }
138
- return nil
139
- end
140
-
141
- def set_includes_data(parent, column_name, model)
142
- reflect = get_reflect(column_name)
143
- reverse = !reflect.belongs_to?
144
- foreign_key = get_foreign_key(reflect, reverse: reverse)
145
- primary_key = get_foreign_key(reflect, reverse: !reverse)
146
- children = model.load_data{|relation| do_query(parent, reflect, relation) }
147
- # reverse = false: Child.where(:id => parent.pluck(:child_id))
148
- # reverse = true : Child.where(:parent_id => parent.pluck(:id))
149
- return DataCombiner.combine_data(
150
- parent,
151
- children,
152
- primary_key,
153
- column_name,
154
- foreign_key,
155
- reverse,
156
- reflect.collection?,
157
- )
158
- end
159
-
160
- def get_query_columns
161
- if @parent_model
162
- parent_reflect = @parent_model.get_reflect(@parent_association_key)
163
- prev_need_columns = @parent_model.get_foreign_key(parent_reflect, reverse: true, with_table_name: true)
164
- end
165
- next_need_columns = @associations.map{|key, _| get_foreign_key(get_reflect(key), with_table_name: true) }.uniq
166
- return [*prev_need_columns, *next_need_columns, *@need_columns].uniq(&Helper::TO_KEY_PROC)
167
- end
168
-
169
- def pluck_values(columns)
170
- includes_values = @relation.includes_values
171
- @relation.includes_values = []
172
-
173
- result = @relation.pluck_all(*columns)
174
-
175
- @relation.includes_values = includes_values
176
- return result
177
- end
178
-
179
- def loaded_models
180
- return [@model] if @model
181
- return @relation if @relation.loaded
182
- end
183
-
184
- public
185
-
186
- def load_data
187
- columns = get_query_columns
188
- key_columns = columns.map(&Helper::TO_KEY_PROC)
189
- @relation = yield(@relation) if block_given?
190
- @data = loaded_models ? loaded_models.as_json(root: false, only: key_columns) : pluck_values(columns)
191
- if @data.size != 0
192
- # for delete_extra_column_data!
193
- @extra_columns = key_columns - @need_columns.map(&Helper::TO_KEY_PROC)
194
- @associations.each do |key, model|
195
- set_includes_data(@data, key, model)
196
- end
197
- end
198
- return @data
199
- end
200
-
201
- def load_all
202
- load_data
203
- delete_extra_column_data!
204
- return @data
205
- end
206
-
207
- def delete_extra_column_data!
208
- return if @data.blank?
209
- @data.each{|s| s.except!(*@extra_columns) }
210
- @associations.each{|_, model| model.delete_extra_column_data! }
211
- end
212
-
213
- # ----------------------------------------------------------------
214
- # Helper methods
215
- # ----------------------------------------------------------------
216
- module Helper
217
- TO_KEY_PROC = proc{|s| Helper.column_to_key(s) }
218
- def self.column_to_key(key) # user_achievements.user_id => user_id
219
- key = key[/(\w+)[^\w]*\z/]
220
- key.gsub!(/[^\w]+/, '')
221
- return key
222
- end
223
- end
224
- end
225
- end
1
+ require 'rails_compatibility'
2
+ require 'rails_compatibility/unscope_where'
3
+ require 'rails_compatibility/build_joins'
4
+ require 'deep_pluck/data_combiner'
5
+
6
+ module DeepPluck
7
+ class Model
8
+ # ----------------------------------------------------------------
9
+ # ● Initialize
10
+ # ----------------------------------------------------------------
11
+ def initialize(relation, parent_association_key = nil, parent_model = nil, need_columns: [])
12
+ if relation.is_a?(ActiveRecord::Base)
13
+ @model = relation
14
+ @relation = nil
15
+ @klass = @model.class
16
+ else
17
+ @model = nil
18
+ @relation = relation
19
+ @klass = @relation.klass
20
+ end
21
+
22
+ @parent_association_key = parent_association_key
23
+ @parent_model = parent_model
24
+ @need_columns = need_columns
25
+ @associations = {}
26
+ end
27
+
28
+ # ----------------------------------------------------------------
29
+ # ● Reader
30
+ # ----------------------------------------------------------------
31
+ def get_reflect(association_key)
32
+ @klass.reflect_on_association(association_key.to_sym) || # add to_sym since rails 3 only support symbol
33
+ fail(ActiveRecord::ConfigurationError, "ActiveRecord::ConfigurationError: Association named \
34
+ '#{association_key}' was not found on #{@klass.name}; perhaps you misspelled it?"
35
+ )
36
+ end
37
+
38
+ def with_conditions(reflect, relation)
39
+ options = reflect.options
40
+ relation = relation.instance_exec(&reflect.scope) if reflect.respond_to?(:scope) and reflect.scope
41
+ relation = relation.where(options[:conditions]) if options[:conditions]
42
+ return relation
43
+ end
44
+
45
+ def get_join_table(reflect)
46
+ options = reflect.options
47
+ return options[:through] if options[:through]
48
+ return (options[:join_table] || reflect.send(:derive_join_table)) if reflect.macro == :has_and_belongs_to_many
49
+ return nil
50
+ end
51
+
52
+ def get_primary_key(reflect)
53
+ return (reflect.belongs_to? ? reflect.klass : reflect.active_record).primary_key
54
+ end
55
+
56
+ def get_foreign_key(reflect, reverse: false, with_table_name: false)
57
+ reflect = reflect.chain.last
58
+ if reverse and (table_name = get_join_table(reflect)) # reverse = parent
59
+ key = reflect.chain.last.foreign_key
60
+ else
61
+ key = (reflect.belongs_to? == reverse ? get_primary_key(reflect) : reflect.foreign_key)
62
+ table_name = (reverse ? reflect.klass : reflect.active_record).table_name
63
+ end
64
+ return "#{table_name}.#{key}" if with_table_name
65
+ return key.to_s # key may be symbol if specify foreign_key in association options
66
+ end
67
+
68
+ def get_association_scope(reflect)
69
+ RailsCompatibility.unscope_where(reflect.association_class.new({}, reflect).send(:association_scope))
70
+ end
71
+
72
+ def use_association_to_query?(reflect)
73
+ reflect.through_reflection && reflect.chain.first.macro == :has_one
74
+ end
75
+
76
+ # ----------------------------------------------------------------
77
+ # ● Contruction OPs
78
+ # ----------------------------------------------------------------
79
+
80
+ private
81
+
82
+ def add_need_column(column)
83
+ @need_columns << column
84
+ end
85
+
86
+ def add_association(hash)
87
+ hash.each do |key, value|
88
+ model = (@associations[key] ||= Model.new(get_reflect(key).klass.where(''), key, self))
89
+ model.add(value)
90
+ end
91
+ end
92
+
93
+ public
94
+
95
+ def add(args)
96
+ return self if args == nil
97
+ args = [args] if not args.is_a?(Array)
98
+ args.each do |arg|
99
+ case arg
100
+ when Hash ; add_association(arg)
101
+ else ; add_need_column(arg)
102
+ end
103
+ end
104
+ return self
105
+ end
106
+
107
+ # ----------------------------------------------------------------
108
+ # ● Load
109
+ # ----------------------------------------------------------------
110
+ private
111
+
112
+ def do_query(parent, reflect, relation)
113
+ parent_key = get_foreign_key(reflect)
114
+ relation_key = get_foreign_key(reflect, reverse: true, with_table_name: true)
115
+ ids = parent.map{|s| s[parent_key] }
116
+ ids.uniq!
117
+ ids.compact!
118
+ relation = with_conditions(reflect, relation)
119
+ query = { relation_key => ids }
120
+ query[reflect.type] = reflect.active_record.to_s if reflect.type
121
+
122
+ return get_association_scope(reflect).where(query) if use_association_to_query?(reflect)
123
+
124
+ joins = if reflect.macro == :has_and_belongs_to_many
125
+ RailsCompatibility.build_joins(reflect, relation)[0]
126
+ else
127
+ backtrace_possible_association(relation, get_join_table(reflect))
128
+ end
129
+
130
+ return relation.joins(joins).where(query)
131
+ end
132
+
133
+ # Let city has_many :users, through: :schools
134
+ # And the query is: City.deep_pluck('users' => :name)
135
+ # We want to get the users data via `User.joins(:school).where(city_id: city_ids)`
136
+ # But get_join_table(reflect) returns `:schools` not :school
137
+ # No idea how to get the right association, so we try singularize or pluralize it.
138
+ def backtrace_possible_association(relation, join_table)
139
+ return join_table if relation.reflect_on_association(join_table)
140
+ join_table.to_s.singularize.to_sym.tap{|s| return s if relation.reflect_on_association(s) }
141
+ join_table.to_s.pluralize.to_sym.tap{|s| return s if relation.reflect_on_association(s) }
142
+ return nil
143
+ end
144
+
145
+ def set_includes_data(parent, column_name, model)
146
+ reflect = get_reflect(column_name)
147
+ reverse = !reflect.belongs_to?
148
+ foreign_key = get_foreign_key(reflect, reverse: reverse)
149
+ primary_key = get_foreign_key(reflect, reverse: !reverse)
150
+ children = model.load_data{|relation| do_query(parent, reflect, relation) }
151
+ # reverse = false: Child.where(:id => parent.pluck(:child_id))
152
+ # reverse = true : Child.where(:parent_id => parent.pluck(:id))
153
+ return DataCombiner.combine_data(
154
+ parent,
155
+ children,
156
+ primary_key,
157
+ column_name,
158
+ foreign_key,
159
+ reverse,
160
+ reflect.collection?,
161
+ )
162
+ end
163
+
164
+ def get_query_columns
165
+ if @parent_model
166
+ parent_reflect = @parent_model.get_reflect(@parent_association_key)
167
+ prev_need_columns = @parent_model.get_foreign_key(parent_reflect, reverse: true, with_table_name: true)
168
+ end
169
+ next_need_columns = @associations.map{|key, _| get_foreign_key(get_reflect(key), with_table_name: true) }.uniq
170
+ return [*prev_need_columns, *next_need_columns, *@need_columns].uniq(&Helper::TO_KEY_PROC)
171
+ end
172
+
173
+ def pluck_values(columns)
174
+ includes_values = @relation.includes_values
175
+ @relation.includes_values = []
176
+
177
+ result = @relation.pluck_all(*columns)
178
+
179
+ @relation.includes_values = includes_values
180
+ return result
181
+ end
182
+
183
+ def loaded_models
184
+ return [@model] if @model
185
+ return @relation if @relation.loaded
186
+ end
187
+
188
+ public
189
+
190
+ def load_data
191
+ columns = get_query_columns
192
+ key_columns = columns.map(&Helper::TO_KEY_PROC)
193
+ @relation = yield(@relation) if block_given?
194
+ @data = loaded_models ? loaded_models.as_json(root: false, only: key_columns) : pluck_values(columns)
195
+ if @data.size != 0
196
+ # for delete_extra_column_data!
197
+ @extra_columns = key_columns - @need_columns.map(&Helper::TO_KEY_PROC)
198
+ @associations.each do |key, model|
199
+ set_includes_data(@data, key, model)
200
+ end
201
+ end
202
+ return @data
203
+ end
204
+
205
+ def load_all
206
+ load_data
207
+ delete_extra_column_data!
208
+ return @data
209
+ end
210
+
211
+ def delete_extra_column_data!
212
+ return if @data.blank?
213
+ @data.each{|s| s.except!(*@extra_columns) }
214
+ @associations.each{|_, model| model.delete_extra_column_data! }
215
+ end
216
+
217
+ # ----------------------------------------------------------------
218
+ # Helper methods
219
+ # ----------------------------------------------------------------
220
+ module Helper
221
+ TO_KEY_PROC = proc{|s| Helper.column_to_key(s) }
222
+ def self.column_to_key(key) # user_achievements.user_id => user_id
223
+ key = key[/(\w+)[^\w]*\z/]
224
+ key.gsub!(/[^\w]+/, '')
225
+ return key
226
+ end
227
+ end
228
+ end
229
+ end
@@ -1,3 +1,3 @@
1
1
  module DeepPluck
2
- VERSION = '1.1.5'
2
+ VERSION = '1.1.6'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep_pluck
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - khiav reoy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-10 00:00:00.000000000 Z
11
+ date: 2021-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -106,14 +106,14 @@ dependencies:
106
106
  requirements:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
- version: 0.0.1
109
+ version: 0.0.3
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: 0.0.1
116
+ version: 0.0.3
117
117
  description: 'Use deep_pluck as a shortcut to select one or more attributes and include
118
118
  associated models without loading a bunch of records. And DRY up your code when
119
119
  using #as_json.'
@@ -124,9 +124,9 @@ extensions: []
124
124
  extra_rdoc_files: []
125
125
  files:
126
126
  - ".github/FUNDING.yml"
127
+ - ".github/workflows/ruby.yml"
127
128
  - ".gitignore"
128
129
  - ".rubocop.yml"
129
- - ".travis.yml"
130
130
  - CHANGELOG.md
131
131
  - CODE_OF_CONDUCT.md
132
132
  - LICENSE.txt
@@ -170,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
170
  - !ruby/object:Gem::Version
171
171
  version: '0'
172
172
  requirements: []
173
- rubygems_version: 3.0.3
173
+ rubygems_version: 3.0.6
174
174
  signing_key:
175
175
  specification_version: 4
176
176
  summary: Use deep_pluck as a shortcut to select one or more attributes and include
data/.travis.yml DELETED
@@ -1,42 +0,0 @@
1
- sudo: false
2
- env:
3
- global:
4
- - CC_TEST_REPORTER_ID=29e69e7da6b55678f27b7de2444b6161a6c98e3c4b22e0e017ebab87ada18fd5
5
- language: ruby
6
- rvm:
7
- - 2.2
8
- - 2.6
9
- - 2.7
10
- gemfile:
11
- - gemfiles/3.2.gemfile
12
- - gemfiles/4.2.gemfile
13
- - gemfiles/5.0.gemfile
14
- - gemfiles/5.1.gemfile
15
- - gemfiles/5.2.gemfile
16
- - gemfiles/6.0.gemfile
17
- - gemfiles/6.1.gemfile
18
- matrix:
19
- exclude:
20
- - gemfile: gemfiles/3.2.gemfile
21
- rvm: 2.6
22
- - gemfile: gemfiles/3.2.gemfile
23
- rvm: 2.7
24
- - gemfile: gemfiles/4.2.gemfile
25
- rvm: 2.7
26
- - gemfile: gemfiles/6.0.gemfile
27
- rvm: 2.2
28
- - gemfile: gemfiles/6.1.gemfile
29
- rvm: 2.2
30
- before_install:
31
- - if `ruby -e 'exit(RUBY_VERSION.to_f < 2.7)'`; then
32
- gem i rubygems-update -v '< 3' && update_rubygems;
33
- gem install bundler -v '< 2';
34
- fi
35
- - gem --version
36
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
37
- - chmod +x ./cc-test-reporter
38
- - ./cc-test-reporter before-build
39
- script:
40
- - bundle exec rake test
41
- after_script:
42
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT