occams-record 1.0.0.rc5 → 1.0.0.rc6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/occams-record/eager_loaders/builder.rb +6 -4
- data/lib/occams-record/eager_loaders/context.rb +19 -7
- data/lib/occams-record/results.rb +1 -1
- data/lib/occams-record/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 851fb48e34ce23fa35958cb72bae9ea977f21fa96694bf9ba20a1c98e706a518
|
4
|
+
data.tar.gz: ac548521b2303bce203a0d18ff73a4542ec68ea6cbdd9842a1b9115fd373b1b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6575024104f85f9c3565834e5cf4c012df74aa11dbe9ae9b71b6638035c4d048729cf6e543bce46cd79556ba0dbbb817509a8ffc9fc091c1ce3890ffde8579db
|
7
|
+
data.tar.gz: 8d6100ac2cd92fa4d36fecca233f8684cb96984a56d0322179101130f4cb9c53ba9a2d599bf868f6b69cfb4a2caa108e770d21eba6ec1e2facd3177dab5dc142
|
data/README.md
CHANGED
@@ -230,9 +230,9 @@ The following ActiveRecord features are not supported, and likely never will be.
|
|
230
230
|
|
231
231
|
# Benchmarking
|
232
232
|
|
233
|
-
`bundle exec rake bench` will run a suite of
|
233
|
+
`bundle exec rake bench` will run a suite of speed and memory benchmarks comparing Occams Record to Active Record. [You can find an example of a typical run here.](https://github.com/jhollinger/occams-record/wiki/Measurements). These are primarily used during development to prevent performance regressions. An in-memory Sqlite database is used.
|
234
234
|
|
235
|
-
If you run your own benchmarks, keep in mind exactly what you're measuring. For example if you're benchmarking a report written in AR vs OR, there are many constants in that measurement: the time spent in the database, the time spent
|
235
|
+
If you run your own benchmarks, keep in mind exactly what you're measuring. For example if you're benchmarking a report written in AR vs OR, there are many constants in that measurement: the time spent in the database, the time spent sending the database results over the network, any calculations you're doing in Ruby, and the time spent building your html/json/csv/etc. So if OR is 3x fastr than AR, the total runtime of said report *won't* improve by 3x.
|
236
236
|
|
237
237
|
On the other hand, Active Record makes it *very* easy to forget to eager load associations (the N+1 query problem). Occams Record fixes that. So if your report was missing some associations you could see easily see performance improvements well over 3x.
|
238
238
|
|
@@ -16,12 +16,13 @@ module OccamsRecord
|
|
16
16
|
# @param select [String] a custom SELECT statement, minus the SELECT (optional)
|
17
17
|
# @param use [Array<Module>] optional Module to include in the result class (single or array)
|
18
18
|
# @param as [Symbol] Load the association usign a different attribute name
|
19
|
+
# @param from [Symbol] Opposite of `as`. `assoc` is the custom name and `from` is the name of association on the ActiveRecord model.
|
19
20
|
# @param optimizer [Symbol] Only used for `through` associations. Options are :none (load all intermediate records) | :select (load all intermediate records but only SELECT the necessary columns)
|
20
21
|
# @yield a block where you may perform eager loading on *this* association (optional)
|
21
22
|
# @return [OccamsRecord::Query] returns self
|
22
23
|
#
|
23
|
-
def eager_load(assoc, scope = nil, select: nil, use: nil, as: nil, optimizer: :select, &builder)
|
24
|
-
@eager_loaders.add(assoc, scope, select: select, use: use, as: as, optimizer: optimizer, &builder)
|
24
|
+
def eager_load(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select, &builder)
|
25
|
+
@eager_loaders.add(assoc, scope, select: select, use: use, as: as, from: from, optimizer: optimizer, &builder)
|
25
26
|
self
|
26
27
|
end
|
27
28
|
|
@@ -36,13 +37,14 @@ module OccamsRecord
|
|
36
37
|
# @param select [String] a custom SELECT statement, minus the SELECT (optional)
|
37
38
|
# @param use [Array<Module>] optional Module to include in the result class (single or array)
|
38
39
|
# @param as [Symbol] Load the association usign a different attribute name
|
40
|
+
# @param from [Symbol] Opposite of `as`. `assoc` is the custom name and `from` is the name of association on the ActiveRecord model.
|
39
41
|
# @param optimizer [Symbol] Only used for `through` associations. Options are :none (load all intermediate records) | :select (load all intermediate records but only SELECT the necessary columns)
|
40
42
|
# @return [OccamsRecord::EagerLoaders::Base]
|
41
43
|
#
|
42
44
|
#
|
43
|
-
def nest(assoc, scope = nil, select: nil, use: nil, as: nil, optimizer: :select)
|
45
|
+
def nest(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select)
|
44
46
|
raise ArgumentError, "OccamsRecord::EagerLoaders::Builder#nest does not accept a block!" if block_given?
|
45
|
-
@eager_loaders.add(assoc, scope, select: select, use: use, as: as, optimizer: optimizer) ||
|
47
|
+
@eager_loaders.add(assoc, scope, select: select, use: use, as: as, from: from, optimizer: optimizer) ||
|
46
48
|
raise("OccamsRecord::EagerLoaders::Builder#nest may not be called under a polymorphic association")
|
47
49
|
end
|
48
50
|
|
@@ -71,17 +71,29 @@ module OccamsRecord
|
|
71
71
|
# @param select [String] a custom SELECT statement, minus the SELECT (optional)
|
72
72
|
# @param use [Array<Module>] optional Module to include in the result class (single or array)
|
73
73
|
# @param as [Symbol] Load the association usign a different attribute name
|
74
|
+
# @param from [Symbol] Opposite of `as`. `assoc` is the custom name and `from` is the name of association on the ActiveRecord model.
|
74
75
|
# @param optimizer [Symbol] Only used for `through` associations. Options are :none (load all intermediate records) | :select (load all intermediate records but only SELECT the necessary columns)
|
75
76
|
# @yield a block where you may perform eager loading on *this* association (optional)
|
76
77
|
# @return [OccamsRecord::EagerLoaders::Base] the new loader. if @model is nil, nil will be returned.
|
77
78
|
#
|
78
|
-
def add(assoc, scope = nil, select: nil, use: nil, as: nil, optimizer: :select, &builder)
|
79
|
+
def add(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select, &builder)
|
80
|
+
if from
|
81
|
+
real_assoc = from
|
82
|
+
custom_name = assoc
|
83
|
+
elsif as
|
84
|
+
real_assoc = assoc
|
85
|
+
custom_name = as
|
86
|
+
else
|
87
|
+
real_assoc = assoc
|
88
|
+
custom_name = nil
|
89
|
+
end
|
90
|
+
|
79
91
|
if @model
|
80
|
-
loader = build_loader!(
|
92
|
+
loader = build_loader!(real_assoc, custom_name, scope, select, use, optimizer, builder)
|
81
93
|
@loaders << loader
|
82
94
|
loader
|
83
95
|
else
|
84
|
-
@dynamic_loaders << [
|
96
|
+
@dynamic_loaders << [real_assoc, custom_name, scope, select, use, optimizer, builder]
|
85
97
|
nil
|
86
98
|
end
|
87
99
|
end
|
@@ -102,19 +114,19 @@ module OccamsRecord
|
|
102
114
|
|
103
115
|
private
|
104
116
|
|
105
|
-
def build_loader!(assoc, scope, select, use,
|
106
|
-
build_loader(assoc, scope, select, use,
|
117
|
+
def build_loader!(assoc, custom_name, scope, select, use, optimizer, builder)
|
118
|
+
build_loader(assoc, custom_name, scope, select, use, optimizer, builder) ||
|
107
119
|
raise("OccamsRecord: No assocation `:#{assoc}` on `#{@model.name}` or subclasses")
|
108
120
|
end
|
109
121
|
|
110
|
-
def build_loader(assoc, scope, select, use,
|
122
|
+
def build_loader(assoc, custom_name, scope, select, use, optimizer, builder)
|
111
123
|
ref = @model.reflections[assoc.to_s] ||
|
112
124
|
@model.subclasses.map(&:reflections).detect { |x| x.has_key? assoc.to_s }&.[](assoc.to_s)
|
113
125
|
return nil if ref.nil?
|
114
126
|
|
115
127
|
scope ||= ->(q) { q.select select } if select
|
116
128
|
loader_class = !!ref.through_reflection ? EagerLoaders::Through : EagerLoaders.fetch!(ref)
|
117
|
-
loader_class.new(ref, scope, use: use, as:
|
129
|
+
loader_class.new(ref, scope, use: use, as: custom_name, optimizer: optimizer, &builder)
|
118
130
|
end
|
119
131
|
end
|
120
132
|
end
|
@@ -173,7 +173,7 @@ module OccamsRecord
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def method_missing(name, *args, &block)
|
176
|
-
return super if args.any? or !block.nil?
|
176
|
+
return super if args.any? or !block.nil? or self.class.model_name.nil?
|
177
177
|
model = self.class.model_name.constantize
|
178
178
|
|
179
179
|
if model.reflections.has_key? name.to_s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: occams-record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Hollinger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|