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.
@@ -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=
@@ -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
@@ -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
@@ -0,0 +1 @@
1
+ require 'yodo/version'
@@ -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
@@ -0,0 +1,3 @@
1
+ module Yodo
2
+ VERSION = '0.0.1'
3
+ end
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: []