yodo 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/rubyservices/yodo.png?branch=master)](http://travis-ci.org/rubyservices/yodo) [![Gem Version](https://badge.fury.io/rb/yodo.png)](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: []
|