deep_pluck 1.1.2 → 1.1.3
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 +5 -5
- data/.gitignore +9 -9
- data/.rubocop.yml +1228 -1228
- data/.travis.yml +34 -34
- data/CHANGELOG.md +54 -47
- data/CODE_OF_CONDUCT.md +48 -48
- data/LICENSE.txt +21 -21
- data/README.md +171 -171
- data/bin/console +0 -0
- data/bin/setup +8 -8
- data/deep_pluck.gemspec +45 -44
- data/gemfiles/3.2.gemfile +11 -11
- data/gemfiles/4.2.gemfile +11 -11
- data/gemfiles/5.0.gemfile +11 -11
- data/gemfiles/5.1.gemfile +11 -11
- data/gemfiles/5.2.gemfile +11 -11
- data/gemfiles/6.0.gemfile +11 -11
- data/lib/deep_pluck.rb +23 -23
- data/lib/deep_pluck/model.rb +209 -196
- data/lib/deep_pluck/version.rb +3 -3
- metadata +17 -4
data/bin/console
CHANGED
File without changes
|
data/bin/setup
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -euo pipefail
|
3
|
-
IFS=$'\n\t'
|
4
|
-
set -vx
|
5
|
-
|
6
|
-
bundle install --gemfile=gemfiles/4.2.gemfile
|
7
|
-
|
8
|
-
# Do any other automated setup that you need to do here
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
set -vx
|
5
|
+
|
6
|
+
bundle install --gemfile=gemfiles/4.2.gemfile
|
7
|
+
|
8
|
+
# Do any other automated setup that you need to do here
|
data/deep_pluck.gemspec
CHANGED
@@ -1,44 +1,45 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'deep_pluck/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'deep_pluck'
|
8
|
-
spec.version = DeepPluck::VERSION
|
9
|
-
spec.authors = ['khiav reoy']
|
10
|
-
spec.email = ['mrtmrt15xn@yahoo.com.tw']
|
11
|
-
|
12
|
-
spec.summary = 'Use deep_pluck as a shortcut to select one or more attributes and include associated models without loading a bunch of records.'
|
13
|
-
spec.description = 'Use deep_pluck as a shortcut to select one or more attributes and include associated models without loading a bunch of records. And DRY up your code when using #as_json.'
|
14
|
-
spec.homepage = 'https://github.com/khiav223577/deep_pluck'
|
15
|
-
spec.license = 'MIT'
|
16
|
-
|
17
|
-
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
-
# delete this section to allow pushing this gem to any host.
|
19
|
-
# if spec.respond_to?(:metadata)
|
20
|
-
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
-
# else
|
22
|
-
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
-
# end
|
24
|
-
|
25
|
-
spec.files = `git ls-files -z`.split("\x0").reject{|f| f.match(%r{^(test|spec|features)/}) }
|
26
|
-
spec.bindir = 'exe'
|
27
|
-
spec.executables = spec.files.grep(%r{^exe/}){|f| File.basename(f) }
|
28
|
-
spec.require_paths = ['lib']
|
29
|
-
spec.metadata = {
|
30
|
-
'homepage_uri' => 'https://github.com/khiav223577/deep_pluck',
|
31
|
-
'changelog_uri' => 'https://github.com/khiav223577/deep_pluck/blob/master/CHANGELOG.md',
|
32
|
-
'source_code_uri' => 'https://github.com/khiav223577/deep_pluck',
|
33
|
-
'documentation_uri' => 'https://www.rubydoc.info/gems/deep_pluck',
|
34
|
-
'bug_tracker_uri' => 'https://github.com/khiav223577/deep_pluck/issues',
|
35
|
-
}
|
36
|
-
|
37
|
-
spec.add_development_dependency 'bundler', '>= 1.17', '< 3.x'
|
38
|
-
spec.add_development_dependency 'rake', '~> 12.0'
|
39
|
-
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
40
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
41
|
-
|
42
|
-
spec.add_dependency 'activerecord', '>= 3'
|
43
|
-
spec.add_dependency 'pluck_all', '>= 1.2.3'
|
44
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'deep_pluck/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'deep_pluck'
|
8
|
+
spec.version = DeepPluck::VERSION
|
9
|
+
spec.authors = ['khiav reoy']
|
10
|
+
spec.email = ['mrtmrt15xn@yahoo.com.tw']
|
11
|
+
|
12
|
+
spec.summary = 'Use deep_pluck as a shortcut to select one or more attributes and include associated models without loading a bunch of records.'
|
13
|
+
spec.description = 'Use deep_pluck as a shortcut to select one or more attributes and include associated models without loading a bunch of records. And DRY up your code when using #as_json.'
|
14
|
+
spec.homepage = 'https://github.com/khiav223577/deep_pluck'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
# else
|
22
|
+
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
# end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject{|f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = 'exe'
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}){|f| File.basename(f) }
|
28
|
+
spec.require_paths = ['lib']
|
29
|
+
spec.metadata = {
|
30
|
+
'homepage_uri' => 'https://github.com/khiav223577/deep_pluck',
|
31
|
+
'changelog_uri' => 'https://github.com/khiav223577/deep_pluck/blob/master/CHANGELOG.md',
|
32
|
+
'source_code_uri' => 'https://github.com/khiav223577/deep_pluck',
|
33
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/deep_pluck',
|
34
|
+
'bug_tracker_uri' => 'https://github.com/khiav223577/deep_pluck/issues',
|
35
|
+
}
|
36
|
+
|
37
|
+
spec.add_development_dependency 'bundler', '>= 1.17', '< 3.x'
|
38
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
39
|
+
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
40
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
41
|
+
|
42
|
+
spec.add_dependency 'activerecord', '>= 3'
|
43
|
+
spec.add_dependency 'pluck_all', '>= 1.2.3'
|
44
|
+
spec.add_dependency 'rails_compatibility', '>= 0.0.1'
|
45
|
+
end
|
data/gemfiles/3.2.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activerecord', '~> 3.2.0'
|
4
|
-
gem 'pluck_all', '~> 1.2.2'
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'sqlite3', '~> 1.3.6'
|
9
|
-
end
|
10
|
-
|
11
|
-
gemspec path: '../'
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 3.2.0'
|
4
|
+
gem 'pluck_all', '~> 1.2.2'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/4.2.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activerecord', '~> 4.2.0'
|
4
|
-
gem 'pluck_all', '~> 1.2.2'
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'sqlite3', '~> 1.3.6'
|
9
|
-
end
|
10
|
-
|
11
|
-
gemspec path: '../'
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 4.2.0'
|
4
|
+
gem 'pluck_all', '~> 1.2.2'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/5.0.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activerecord', '~> 5.0.0'
|
4
|
-
gem 'pluck_all', '~> 1.2.2'
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'sqlite3', '~> 1.3.6'
|
9
|
-
end
|
10
|
-
|
11
|
-
gemspec path: '../'
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 5.0.0'
|
4
|
+
gem 'pluck_all', '~> 1.2.2'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/5.1.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activerecord', '~> 5.1.0'
|
4
|
-
gem 'pluck_all', '~> 1.2.2'
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'sqlite3', '~> 1.3.6'
|
9
|
-
end
|
10
|
-
|
11
|
-
gemspec path: '../'
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 5.1.0'
|
4
|
+
gem 'pluck_all', '~> 1.2.2'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/5.2.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activerecord', '~> 5.2.0'
|
4
|
-
gem 'pluck_all', '~> 1.2.2'
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'sqlite3', '~> 1.3.6'
|
9
|
-
end
|
10
|
-
|
11
|
-
gemspec path: '../'
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 5.2.0'
|
4
|
+
gem 'pluck_all', '~> 1.2.2'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov'
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/gemfiles/6.0.gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activerecord', '~> 6.0.0'
|
4
|
-
gem 'pluck_all', '~> 2.0.4'
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'sqlite3', '~> 1.4.1'
|
9
|
-
end
|
10
|
-
|
11
|
-
gemspec path: '../'
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activerecord', '~> 6.0.0'
|
4
|
+
gem 'pluck_all', '~> 2.0.4'
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'simplecov'
|
8
|
+
gem 'sqlite3', '~> 1.4.1'
|
9
|
+
end
|
10
|
+
|
11
|
+
gemspec path: '../'
|
data/lib/deep_pluck.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
require 'deep_pluck/version'
|
2
|
-
require 'deep_pluck/model'
|
3
|
-
require 'active_record'
|
4
|
-
require 'pluck_all'
|
5
|
-
|
6
|
-
class ActiveRecord::Relation
|
7
|
-
def deep_pluck(*args)
|
8
|
-
DeepPluck::Model.new(self).add(args).load_all
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class ActiveRecord::Base
|
13
|
-
def self.deep_pluck(*args)
|
14
|
-
where('').deep_pluck(*args)
|
15
|
-
end
|
16
|
-
|
17
|
-
def deep_pluck(*args)
|
18
|
-
hash_args, other_args = args.partition{|s| s.is_a?(Hash) }
|
19
|
-
model = DeepPluck::Model.new(self, need_columns: other_args)
|
20
|
-
model.add(*hash_args) if hash_args.any?
|
21
|
-
return model.load_all.first
|
22
|
-
end
|
23
|
-
end
|
1
|
+
require 'deep_pluck/version'
|
2
|
+
require 'deep_pluck/model'
|
3
|
+
require 'active_record'
|
4
|
+
require 'pluck_all'
|
5
|
+
|
6
|
+
class ActiveRecord::Relation
|
7
|
+
def deep_pluck(*args)
|
8
|
+
DeepPluck::Model.new(self).add(args).load_all
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ActiveRecord::Base
|
13
|
+
def self.deep_pluck(*args)
|
14
|
+
where('').deep_pluck(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def deep_pluck(*args)
|
18
|
+
hash_args, other_args = args.partition{|s| s.is_a?(Hash) }
|
19
|
+
model = DeepPluck::Model.new(self, need_columns: other_args)
|
20
|
+
model.add(*hash_args) if hash_args.any?
|
21
|
+
return model.load_all.first
|
22
|
+
end
|
23
|
+
end
|
data/lib/deep_pluck/model.rb
CHANGED
@@ -1,196 +1,209 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# ----------------------------------------------------------------
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@
|
13
|
-
|
14
|
-
@
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@
|
22
|
-
@
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# ----------------------------------------------------------------
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
return
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
+
return relation.joins(get_join_table(reflect)).where(query)
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_includes_data(parent, column_name, model)
|
126
|
+
reflect = get_reflect(column_name)
|
127
|
+
reverse = !reflect.belongs_to?
|
128
|
+
foreign_key = get_foreign_key(reflect, reverse: reverse)
|
129
|
+
primary_key = get_foreign_key(reflect, reverse: !reverse)
|
130
|
+
children = model.load_data{|relation| do_query(parent, reflect, relation) }
|
131
|
+
# reverse = false: Child.where(:id => parent.pluck(:child_id))
|
132
|
+
# reverse = true : Child.where(:parent_id => parent.pluck(:id))
|
133
|
+
return DataCombiner.combine_data(
|
134
|
+
parent,
|
135
|
+
children,
|
136
|
+
primary_key,
|
137
|
+
column_name,
|
138
|
+
foreign_key,
|
139
|
+
reverse,
|
140
|
+
reflect.collection?,
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_query_columns
|
145
|
+
if @parent_model
|
146
|
+
parent_reflect = @parent_model.get_reflect(@parent_association_key)
|
147
|
+
prev_need_columns = @parent_model.get_foreign_key(parent_reflect, reverse: true, with_table_name: true)
|
148
|
+
end
|
149
|
+
next_need_columns = @associations.map{|key, _| get_foreign_key(get_reflect(key), with_table_name: true) }.uniq
|
150
|
+
return [*prev_need_columns, *next_need_columns, *@need_columns].uniq(&Helper::TO_KEY_PROC)
|
151
|
+
end
|
152
|
+
|
153
|
+
def pluck_values(columns)
|
154
|
+
includes_values = @relation.includes_values
|
155
|
+
@relation.includes_values = []
|
156
|
+
|
157
|
+
result = @relation.pluck_all(*columns)
|
158
|
+
|
159
|
+
@relation.includes_values = includes_values
|
160
|
+
return result
|
161
|
+
end
|
162
|
+
|
163
|
+
def loaded_models
|
164
|
+
return [@model] if @model
|
165
|
+
return @relation if @relation.loaded
|
166
|
+
end
|
167
|
+
|
168
|
+
public
|
169
|
+
|
170
|
+
def load_data
|
171
|
+
columns = get_query_columns
|
172
|
+
key_columns = columns.map(&Helper::TO_KEY_PROC)
|
173
|
+
@relation = yield(@relation) if block_given?
|
174
|
+
@data = loaded_models ? loaded_models.as_json(root: false, only: key_columns) : pluck_values(columns)
|
175
|
+
if @data.size != 0
|
176
|
+
# for delete_extra_column_data!
|
177
|
+
@extra_columns = key_columns - @need_columns.map(&Helper::TO_KEY_PROC)
|
178
|
+
@associations.each do |key, model|
|
179
|
+
set_includes_data(@data, key, model)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
return @data
|
183
|
+
end
|
184
|
+
|
185
|
+
def load_all
|
186
|
+
load_data
|
187
|
+
delete_extra_column_data!
|
188
|
+
return @data
|
189
|
+
end
|
190
|
+
|
191
|
+
def delete_extra_column_data!
|
192
|
+
return if @data.blank?
|
193
|
+
@data.each{|s| s.except!(*@extra_columns) }
|
194
|
+
@associations.each{|_, model| model.delete_extra_column_data! }
|
195
|
+
end
|
196
|
+
|
197
|
+
# ----------------------------------------------------------------
|
198
|
+
# ● Helper methods
|
199
|
+
# ----------------------------------------------------------------
|
200
|
+
module Helper
|
201
|
+
TO_KEY_PROC = proc{|s| Helper.column_to_key(s) }
|
202
|
+
def self.column_to_key(key) # user_achievements.user_id => user_id
|
203
|
+
key = key[/(\w+)[^\w]*\z/]
|
204
|
+
key.gsub!(/[^\w]+/, '')
|
205
|
+
return key
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|