yodo 0.0.1
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 +15 -0
- data/README.md +66 -0
- data/Rakefile +18 -0
- data/lib/yodo.rb +1 -0
- data/lib/yodo/ams.rb +58 -0
- data/lib/yodo/version.rb +3 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NWIzYjEyNTY5ODI3NWNlMjRiNzE0MTQzZjIzMzA2MDAzYWI5YTc3NA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MTYyM2IxYTliOWZiZTdmYjkxN2UzZWFiZGU4NDE4Yzk5MjczMTFjNA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDU4ZGQzOTQwNzQ4OWY1ODkxNDE2NWJhZjlmY2Q5Y2Y2MjQ5Zjk2YzRjZjZh
|
10
|
+
MmVkMzE1MTk0YTMwMGM0ODUzYWU2NDAxY2Q5NWY2MTMxZWFkNzFhNjFlMjQ0
|
11
|
+
ODFiYmJhMzZjMWI5MGZjYWU3MzAyMWM2ODg5MzlkNDZlZTY1NWY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzgzMDcyMjc5YmJkYjRiMzcyNTAxOTkyYmIzMWZmYWZhOWNkYjY5ZmEzOGE1
|
14
|
+
YWY1M2M5NGNjM2Q2OTA1NjVlODFjY2IxNDZkN2I2ZWJmOTU4NWYzNDQyZTgw
|
15
|
+
MDMzYzczMmFlYmE3OTM0MzQxZjU4MmU5NTNjMGMyZmJjODlhMjE=
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
[](http://travis-ci.org/rubyservices/yodo) [](http://badge.fury.io/rb/yodo)
|
2
|
+
# Yodo
|
3
|
+
|
4
|
+
Determines what includes you need to avoid n+1 queries when using [ActiveModel::Serializers][active_model_serializers].
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
If you already have a Rails project setup with `ActiveModels::Serializers`, add this to your Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'yodo', '~> 0.0.1'
|
12
|
+
```
|
13
|
+
|
14
|
+
Then:
|
15
|
+
|
16
|
+
```
|
17
|
+
bundle install
|
18
|
+
```
|
19
|
+
|
20
|
+
In console:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
rails c
|
24
|
+
```
|
25
|
+
|
26
|
+
Do the following:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'yodo/ams'
|
30
|
+
|
31
|
+
# Get includes required as hash
|
32
|
+
|
33
|
+
Yodo::AMS.analyze_all
|
34
|
+
|
35
|
+
# That might return {AlphaSerializer=>{:suggested_includes=>[:deltas, :gam, :beta, :alpha, {:delts=>[:delts]}]}, GammaSerializer=>{:suggested_includes=>[]}, DeltaSerializer=>{:suggested_includes=>[:delts]}, BetaSerializer=>{:suggested_includes=>[:gammas, :gamma, :deltas, :ds, :beta, :gam, :bet, {:al=>[:deltas, :gam, :beta, :alpha, {:delts=>[:delts]}]}]}}
|
36
|
+
|
37
|
+
# Take the results of Yodo::AMS.analyze_all and sort results in a human readable format
|
38
|
+
|
39
|
+
Yodo::AMS.analyze_all.map {|s,h| h.map {|k,v| "#{s.name} #{k.to_s.gsub('_',' ')} = #{v}" unless v.empty?}.compact}.flatten.sort.each {|a| puts a}; nil
|
40
|
+
|
41
|
+
# That might output:
|
42
|
+
#
|
43
|
+
# AlphaSerializer suggested includes = [:deltas, :gam, :beta, :alpha, {:delts=>[:delts]}]
|
44
|
+
# BetaSerializer suggested includes = [:gammas, :gamma, :deltas, :ds, :beta, :gam, :bet, {:al=>[:deltas, :gam, :beta, :alpha, {:delts=>[:delts]}]}]
|
45
|
+
# DeltaSerializer suggested includes = [:delts]
|
46
|
+
```
|
47
|
+
|
48
|
+
### Release Notes
|
49
|
+
|
50
|
+
See the [Changelog][changelog] for basically what happened when, and git log for everything else.
|
51
|
+
|
52
|
+
### Contributing
|
53
|
+
|
54
|
+
Please fork, make changes in a separate branch, and do a pull request for your branch.
|
55
|
+
|
56
|
+
### Contributors
|
57
|
+
|
58
|
+
* Gary Weaver (https://github.com/garysweaver)
|
59
|
+
|
60
|
+
### License
|
61
|
+
|
62
|
+
Copyright (c) 2013 Gary S. Weaver, released under the [MIT license][lic].
|
63
|
+
|
64
|
+
[active_model_serializers]: https://github.com/rails-api/active_model_serializers
|
65
|
+
[changelog]: https://github.com/garysweaver/yodo/blob/master/CHANGELOG.md
|
66
|
+
[lic]: http://github.com/garysweaver/yodo/blob/master/LICENSE
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'appraisal'
|
4
|
+
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
task :default do |t|
|
9
|
+
if ENV['BUNDLE_GEMFILE'] =~ /gemfiles/
|
10
|
+
exec 'rake spec'
|
11
|
+
else
|
12
|
+
exec 'rake appraise'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
task :appraise => ['appraisal:install'] do |t|
|
17
|
+
exec 'rake appraisal'
|
18
|
+
end
|
data/lib/yodo.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'yodo/version'
|
data/lib/yodo/ams.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Yodo
|
2
|
+
class AMS
|
3
|
+
class << self
|
4
|
+
# Eager loads all Rails' classes to get list of all descendants of ActiveModel::Serializer. Then
|
5
|
+
# returns hash of serializers to results of analysis. Currently the only key in each serializer's
|
6
|
+
# results is :suggested_includes which is a hash representing the includes that should be done for
|
7
|
+
# each ActiveModel::Serializer or an empty array.
|
8
|
+
def analyze_all
|
9
|
+
Rails.application.eager_load!
|
10
|
+
analyze(*ActiveModel::Serializer.descendants)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Takes one or more descendants of ActiveModel::Serializer and returns hash of serializers to
|
14
|
+
# results of analysis. Currently the only key in each serializer's results is
|
15
|
+
# :suggested_includes which is a hash representing the includes that could perhaps be used to avoid
|
16
|
+
# n+1 queries or an empty array.
|
17
|
+
def analyze(*args)
|
18
|
+
args.pop if args.last.is_a?(Hash)
|
19
|
+
serializer_to_results = {}
|
20
|
+
args.each do |serializer|
|
21
|
+
serializer_to_results[serializer] = {:suggested_includes => find_includes(serializer)}
|
22
|
+
end
|
23
|
+
serializer_to_results
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def find_includes(serializer, done = {})
|
28
|
+
# don't follow refs that we've already resolved
|
29
|
+
return [] if done[serializer]
|
30
|
+
results = []
|
31
|
+
serializer._associations.each do |k,v|
|
32
|
+
if v.options[:serializer].respond_to?(:_associations)
|
33
|
+
if results.last.is_a?(Hash)
|
34
|
+
options = results.last
|
35
|
+
else
|
36
|
+
results << (options = {})
|
37
|
+
end
|
38
|
+
# skip self-references or we'll never get done with this serializer
|
39
|
+
associations_with_defined_serializers = v.options[:serializer] == serializer ? [] : find_includes(v.options[:serializer], done)
|
40
|
+
if associations_with_defined_serializers.empty?
|
41
|
+
results.prepend(k)
|
42
|
+
else
|
43
|
+
options[k] = associations_with_defined_serializers
|
44
|
+
end
|
45
|
+
else
|
46
|
+
results.prepend(k)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# inefficient, but works for now...
|
50
|
+
if results.last.is_a?(Hash) && results.last.empty?
|
51
|
+
results.pop
|
52
|
+
end
|
53
|
+
done[serializer] = true
|
54
|
+
results
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/yodo/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yodo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gary S. Weaver
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Determines what includes you need to avoid n+1 queries when using ActiveModel::Serializers.
|
14
|
+
email:
|
15
|
+
- garysweaver@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/yodo/ams.rb
|
21
|
+
- lib/yodo/version.rb
|
22
|
+
- lib/yodo.rb
|
23
|
+
- Rakefile
|
24
|
+
- README.md
|
25
|
+
homepage: https://github.com/garysweaver/yodo
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project:
|
45
|
+
rubygems_version: 2.0.3
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: n+1 query avoidance with AMS.
|
49
|
+
test_files: []
|