goldiloader 3.0.2 → 3.0.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 +4 -4
- data/lib/goldiloader.rb +1 -1
- data/lib/goldiloader/active_record_patches.rb +42 -12
- data/lib/goldiloader/association_options.rb +3 -3
- data/lib/goldiloader/auto_include_context.rb +2 -0
- data/lib/goldiloader/scope_info.rb +39 -0
- data/lib/goldiloader/version.rb +1 -1
- metadata +17 -3
- data/lib/goldiloader/association_info.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f23e35eaad8987983cf1c95ec9c99e281e23715
|
4
|
+
data.tar.gz: 9882b6e39452af1d0a9d55b28b7d1d40e3e3513a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22065fba51aa33fbc113ddc113a84d998de8b5915108c0dd54a878b182684155b957be4aa86bec6971010ff6f930a94116e4ebc4ff3490e6c0257975e0e26272
|
7
|
+
data.tar.gz: 03244b1b7fc590389d9a89a0a5f26376c0198b1e0ce68e5605e5e254ad116e203ae88573da24ca671ed2b5bb44fe0d58cc19f9509a754c462fa9d0e9e2c36129
|
data/lib/goldiloader.rb
CHANGED
@@ -4,7 +4,7 @@ require 'active_support/all'
|
|
4
4
|
require 'active_record'
|
5
5
|
require 'goldiloader/compatibility'
|
6
6
|
require 'goldiloader/auto_include_context'
|
7
|
-
require 'goldiloader/
|
7
|
+
require 'goldiloader/scope_info'
|
8
8
|
require 'goldiloader/association_options'
|
9
9
|
require 'goldiloader/association_loader'
|
10
10
|
require 'goldiloader/active_record_patches'
|
@@ -76,6 +76,35 @@ module Goldiloader
|
|
76
76
|
end
|
77
77
|
ActiveRecord::Relation::Merger.prepend(::Goldiloader::MergerPatch)
|
78
78
|
|
79
|
+
module AssociationReflectionPatch
|
80
|
+
def eager_loadable?
|
81
|
+
return @eager_loadable if instance_variable_defined?(:@eager_loadable)
|
82
|
+
|
83
|
+
@eager_loadable = if scope.nil?
|
84
|
+
# Associations without any scoping options are eager loadable
|
85
|
+
true
|
86
|
+
elsif scope.arity > 0
|
87
|
+
# The scope will be evaluated for every model instance so it can't
|
88
|
+
# be eager loaded
|
89
|
+
false
|
90
|
+
else
|
91
|
+
scope_info = if Goldiloader::Compatibility.rails_4?
|
92
|
+
Goldiloader::ScopeInfo.new(klass.unscoped.instance_exec(&scope) || klass.unscoped)
|
93
|
+
else
|
94
|
+
Goldiloader::ScopeInfo.new(scope_for(klass.unscoped))
|
95
|
+
end
|
96
|
+
scope_info.auto_include? &&
|
97
|
+
!scope_info.limit? &&
|
98
|
+
!scope_info.offset? &&
|
99
|
+
(!has_one? || !scope_info.order?) &&
|
100
|
+
(::Goldiloader::Compatibility.group_eager_loadable? || !scope_info.group?) &&
|
101
|
+
(::Goldiloader::Compatibility.from_eager_loadable? || !scope_info.from?)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
ActiveRecord::Reflection::AssociationReflection.include(::Goldiloader::AssociationReflectionPatch)
|
106
|
+
ActiveRecord::Reflection::ThroughReflection.include(::Goldiloader::AssociationReflectionPatch)
|
107
|
+
|
79
108
|
module AssociationPatch
|
80
109
|
extend ActiveSupport::Concern
|
81
110
|
|
@@ -97,25 +126,26 @@ module Goldiloader
|
|
97
126
|
private
|
98
127
|
|
99
128
|
def eager_loadable?
|
100
|
-
|
101
|
-
|
102
|
-
!association_info.limit? &&
|
103
|
-
!association_info.offset? &&
|
104
|
-
(!association_info.has_one? || !association_info.order?) &&
|
105
|
-
(::Goldiloader::Compatibility.group_eager_loadable? || !association_info.group?) &&
|
106
|
-
(::Goldiloader::Compatibility.from_eager_loadable? || !association_info.from?) &&
|
107
|
-
(::Goldiloader::Compatibility.destroyed_model_associations_eager_loadable? || !owner.destroyed?) &&
|
108
|
-
!association_info.instance_dependent?
|
129
|
+
reflection.eager_loadable? &&
|
130
|
+
(::Goldiloader::Compatibility.destroyed_model_associations_eager_loadable? || !owner.destroyed?)
|
109
131
|
end
|
110
132
|
|
111
133
|
def load_with_auto_include
|
112
134
|
if loaded? && !stale_target?
|
113
135
|
target
|
114
|
-
elsif auto_include?
|
136
|
+
elsif !auto_include?
|
137
|
+
yield
|
138
|
+
elsif owner.auto_include_context.size == 1
|
139
|
+
# Bypassing the preloader for a single model reduces object allocations by ~5% in benchmarks
|
140
|
+
result = yield
|
141
|
+
# As of https://github.com/rails/rails/commit/bd3b28f7f181dce53e872daa23dda101498b8fb4
|
142
|
+
# ActiveRecord does not use ActiveRecord::Relation#exec_queries to resolve association
|
143
|
+
# queries
|
144
|
+
Goldiloader::AutoIncludeContext.register_models(result)
|
145
|
+
result
|
146
|
+
else
|
115
147
|
Goldiloader::AssociationLoader.load(owner, reflection.name)
|
116
148
|
target
|
117
|
-
else
|
118
|
-
yield
|
119
149
|
end
|
120
150
|
end
|
121
151
|
end
|
@@ -18,10 +18,10 @@ module Goldiloader
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def register
|
21
|
-
if ::
|
22
|
-
ActiveRecord::Associations::Builder::Association.extensions << AssociationBuilderExtension
|
23
|
-
else
|
21
|
+
if Goldiloader::Compatibility.rails_4?
|
24
22
|
ActiveRecord::Associations::Builder::Association.valid_options.concat(OPTIONS)
|
23
|
+
else
|
24
|
+
ActiveRecord::Associations::Builder::Association.extensions << AssociationBuilderExtension
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Goldiloader
|
4
|
+
class ScopeInfo
|
5
|
+
attr_reader :scope
|
6
|
+
|
7
|
+
def initialize(scope)
|
8
|
+
@scope = scope
|
9
|
+
end
|
10
|
+
|
11
|
+
def offset?
|
12
|
+
scope.offset_value.present?
|
13
|
+
end
|
14
|
+
|
15
|
+
def limit?
|
16
|
+
scope.limit_value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def auto_include?
|
20
|
+
scope.auto_include_value
|
21
|
+
end
|
22
|
+
|
23
|
+
def from?
|
24
|
+
if Goldiloader::Compatibility.rails_4?
|
25
|
+
scope.from_value.present?
|
26
|
+
else
|
27
|
+
scope.from_clause.present?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def group?
|
32
|
+
scope.group_values.present?
|
33
|
+
end
|
34
|
+
|
35
|
+
def order?
|
36
|
+
scope.order_values.present?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/goldiloader/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goldiloader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Turkel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -64,6 +64,20 @@ dependencies:
|
|
64
64
|
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: '0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: benchmark-ips
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
67
81
|
- !ruby/object:Gem::Dependency
|
68
82
|
name: coveralls
|
69
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,11 +200,11 @@ files:
|
|
186
200
|
- LICENSE.txt
|
187
201
|
- lib/goldiloader.rb
|
188
202
|
- lib/goldiloader/active_record_patches.rb
|
189
|
-
- lib/goldiloader/association_info.rb
|
190
203
|
- lib/goldiloader/association_loader.rb
|
191
204
|
- lib/goldiloader/association_options.rb
|
192
205
|
- lib/goldiloader/auto_include_context.rb
|
193
206
|
- lib/goldiloader/compatibility.rb
|
207
|
+
- lib/goldiloader/scope_info.rb
|
194
208
|
- lib/goldiloader/version.rb
|
195
209
|
homepage: https://github.com/salsify/goldiloader
|
196
210
|
licenses:
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Goldiloader
|
4
|
-
class AssociationInfo
|
5
|
-
|
6
|
-
def initialize(association)
|
7
|
-
@association = association
|
8
|
-
end
|
9
|
-
|
10
|
-
delegate :association_scope, :reflection, to: :@association
|
11
|
-
|
12
|
-
def has_one? # rubocop:disable Naming/PredicateName
|
13
|
-
reflection.has_one?
|
14
|
-
end
|
15
|
-
|
16
|
-
def offset?
|
17
|
-
association_scope && association_scope.offset_value.present?
|
18
|
-
end
|
19
|
-
|
20
|
-
def limit?
|
21
|
-
association_scope && association_scope.limit_value.present?
|
22
|
-
end
|
23
|
-
|
24
|
-
def auto_include?
|
25
|
-
association_scope.nil? || association_scope.auto_include_value
|
26
|
-
end
|
27
|
-
|
28
|
-
def from?
|
29
|
-
if ActiveRecord::VERSION::MAJOR >= 5
|
30
|
-
association_scope && association_scope.from_clause.present?
|
31
|
-
else
|
32
|
-
association_scope && association_scope.from_value.present?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def group?
|
37
|
-
association_scope && association_scope.group_values.present?
|
38
|
-
end
|
39
|
-
|
40
|
-
def order?
|
41
|
-
association_scope && association_scope.order_values.present?
|
42
|
-
end
|
43
|
-
|
44
|
-
def instance_dependent?
|
45
|
-
reflection.scope.present? && reflection.scope.arity > 0
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|