mongoid-eager-loading 0.2.0 → 0.3.0
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.
- data/Gemfile.lock +13 -12
- data/README.md +12 -10
- data/benchmark/benchmark.rb +11 -4
- data/lib/mongoid-eager-loading.rb +1 -6
- data/lib/mongoid-eager-loading/mongoid/criterion/eager_loading.rb +36 -36
- data/lib/mongoid-eager-loading/version.rb +1 -1
- data/mongoid-eager-loading.gemspec +4 -3
- data/spec/models/account.rb +11 -5
- data/spec/models/address.rb +8 -1
- data/spec/models/address_component.rb +5 -0
- data/spec/models/agent.rb +2 -3
- data/spec/models/animal.rb +8 -5
- data/spec/models/answer.rb +1 -1
- data/spec/models/bar.rb +5 -0
- data/spec/models/book.rb +5 -0
- data/spec/models/business.rb +7 -0
- data/spec/models/callbacks.rb +2 -2
- data/spec/models/category.rb +3 -3
- data/spec/models/country_code.rb +1 -1
- data/spec/models/description.rb +3 -0
- data/spec/models/drug.rb +5 -0
- data/spec/models/favorite.rb +1 -3
- data/spec/models/fruits.rb +11 -0
- data/spec/models/game.rb +2 -1
- data/spec/models/house.rb +4 -0
- data/spec/models/inheritance.rb +19 -4
- data/spec/models/location.rb +1 -1
- data/spec/models/membership.rb +4 -0
- data/spec/models/movie.rb +5 -0
- data/spec/models/name.rb +1 -1
- data/spec/models/page.rb +5 -0
- data/spec/models/page_question.rb +4 -0
- data/spec/models/paranoid_post.rb +1 -1
- data/spec/models/parents.rb +1 -1
- data/spec/models/patient.rb +2 -2
- data/spec/models/person.rb +27 -12
- data/spec/models/pet.rb +1 -1
- data/spec/models/pet_owner.rb +1 -1
- data/spec/models/phone.rb +1 -1
- data/spec/models/post.rb +6 -4
- data/spec/models/preference.rb +2 -1
- data/spec/models/question.rb +3 -3
- data/spec/models/quiz.rb +4 -0
- data/spec/models/rating.rb +6 -0
- data/spec/models/role.rb +5 -0
- data/spec/models/shelf.rb +5 -0
- data/spec/models/slave_address_numbers.rb +14 -0
- data/spec/models/survey.rb +1 -2
- data/spec/models/tracking_id_validation_history.rb +25 -0
- data/spec/models/translation.rb +1 -1
- data/spec/models/user.rb +3 -2
- data/spec/models/user_account.rb +3 -2
- data/spec/models/vet_visit.rb +1 -1
- data/spec/models/video.rb +1 -1
- data/spec/models/wiki_page.rb +6 -0
- data/spec/mongoid-eager-loading/mongoid/criterion/eager_loading_spec.rb +19 -0
- data/spec/spec_helper.rb +1 -1
- metadata +93 -59
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mongoid-eager-loading (0.
|
4
|
+
mongoid-eager-loading (0.3.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -11,18 +11,18 @@ GEM
|
|
11
11
|
builder (~> 2.1.2)
|
12
12
|
i18n (~> 0.4)
|
13
13
|
activesupport (3.0.3)
|
14
|
-
bson (1.
|
15
|
-
bson_ext (1.
|
14
|
+
bson (1.2.0)
|
15
|
+
bson_ext (1.2.0)
|
16
16
|
builder (2.1.2)
|
17
17
|
diff-lcs (1.1.2)
|
18
|
-
i18n (0.
|
18
|
+
i18n (0.5.0)
|
19
19
|
mocha (0.9.9)
|
20
20
|
rake
|
21
|
-
mongo (1.
|
22
|
-
bson (>= 1.
|
23
|
-
mongoid (2.0.0.
|
21
|
+
mongo (1.2.0)
|
22
|
+
bson (>= 1.2.0)
|
23
|
+
mongoid (2.0.0.rc.6)
|
24
24
|
activemodel (~> 3.0)
|
25
|
-
mongo (~> 1.
|
25
|
+
mongo (~> 1.2)
|
26
26
|
tzinfo (~> 0.3.22)
|
27
27
|
will_paginate (~> 3.0.pre)
|
28
28
|
rake (0.8.7)
|
@@ -36,7 +36,7 @@ GEM
|
|
36
36
|
rspec-mocks (2.0.1)
|
37
37
|
rspec-core (~> 2.0.1)
|
38
38
|
rspec-expectations (~> 2.0.1)
|
39
|
-
tzinfo (0.3.
|
39
|
+
tzinfo (0.3.24)
|
40
40
|
watchr (0.7)
|
41
41
|
will_paginate (3.0.pre2)
|
42
42
|
|
@@ -44,11 +44,12 @@ PLATFORMS
|
|
44
44
|
ruby
|
45
45
|
|
46
46
|
DEPENDENCIES
|
47
|
-
|
47
|
+
bson (= 1.2.0)
|
48
|
+
bson_ext (= 1.2.0)
|
48
49
|
bundler (>= 1.0.0)
|
49
50
|
mocha
|
50
|
-
mongo (
|
51
|
-
mongoid (= 2.0.0.
|
51
|
+
mongo (= 1.2.0)
|
52
|
+
mongoid (= 2.0.0.rc.6)
|
52
53
|
mongoid-eager-loading!
|
53
54
|
rspec (~> 2.0.0)
|
54
55
|
watchr
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ mongoid-eager-loading adds the eager loading feature for mongoid.
|
|
5
5
|
|
6
6
|
Originally it is my [pull request][0] for mongoid, but it is not accepted yet, so I created this gem to get the eager loading benefits easily for my projects.
|
7
7
|
|
8
|
-
I only test it in mongoid
|
8
|
+
I only test it in mongoid 2.0.0.beta.19 and 2.0.0.beta.20, maybe you can try it on other mongoid version, and let me know if it works fine.
|
9
9
|
|
10
10
|
Usage
|
11
11
|
-----
|
@@ -18,7 +18,7 @@ suppose you have a mongoid model Post
|
|
18
18
|
|
19
19
|
class Post
|
20
20
|
include Mongoid::Document
|
21
|
-
|
21
|
+
|
22
22
|
referenced_in :user
|
23
23
|
references_many :comments
|
24
24
|
end
|
@@ -27,9 +27,9 @@ then you can use the eager loading like
|
|
27
27
|
|
28
28
|
Post.includes(:user)
|
29
29
|
Post.includes(:user, :comments)
|
30
|
-
|
30
|
+
|
31
31
|
eager loading can be only used on referenced_in, references_one and references_many associations.
|
32
|
-
|
32
|
+
|
33
33
|
Benchmark
|
34
34
|
---------
|
35
35
|
|
@@ -37,12 +37,14 @@ I also run a [benchmark][1] on my local computer, the result is as follows
|
|
37
37
|
|
38
38
|
Starting benchmark...
|
39
39
|
user system total real
|
40
|
-
Finding 10 posts with person, without eager loading 0.
|
41
|
-
Finding 10 posts with person, with eager loading 0.
|
42
|
-
Finding 50 posts with person, without eager loading 0.
|
43
|
-
Finding 50 posts with person, with eager loading 0.
|
44
|
-
Finding 100 posts with person, without eager loading 0.040000 0.000000 0.040000 ( 0.
|
45
|
-
Finding 100 posts with person, with eager loading 0.
|
40
|
+
Finding 10 posts with person, without eager loading 0.000000 0.000000 0.000000 ( 0.005373)
|
41
|
+
Finding 10 posts with person, with eager loading 0.010000 0.000000 0.010000 ( 0.002984)
|
42
|
+
Finding 50 posts with person, without eager loading 0.010000 0.000000 0.010000 ( 0.022207)
|
43
|
+
Finding 50 posts with person, with eager loading 0.010000 0.000000 0.010000 ( 0.006831)
|
44
|
+
Finding 100 posts with person, without eager loading 0.040000 0.000000 0.040000 ( 0.050991)
|
45
|
+
Finding 100 posts with person, with eager loading 0.010000 0.000000 0.010000 ( 0.012867)
|
46
|
+
Finding 1000 posts with person, without eager loading 0.390000 0.050000 0.440000 ( 0.477983)
|
47
|
+
Finding 1000 posts with person, with eager loading 0.120000 0.010000 0.130000 ( 0.128879)
|
46
48
|
|
47
49
|
Author
|
48
50
|
------
|
data/benchmark/benchmark.rb
CHANGED
@@ -5,7 +5,8 @@ require "mongoid"
|
|
5
5
|
require "mongoid-eager-loading"
|
6
6
|
|
7
7
|
Mongoid.configure do |config|
|
8
|
-
config.master = Mongo::Connection.new
|
8
|
+
#config.master = Mongo::Connection.new('localhost', 27018, :logger => Logger.new($stdout)).db("mongoid_perf_test")
|
9
|
+
config.master = Mongo::Connection.new.db("mongoid_perf_test")
|
9
10
|
end
|
10
11
|
|
11
12
|
Mongoid.master.collection("people").drop
|
@@ -36,22 +37,28 @@ Benchmark.bm(60) do |bm|
|
|
36
37
|
bm.report("Finding 10 posts with person, without eager loading") do
|
37
38
|
Post.limit(10).each { |p| p.person.name }
|
38
39
|
end
|
39
|
-
|
40
40
|
bm.report("Finding 10 posts with person, with eager loading") do
|
41
41
|
Post.limit(10).includes(:person).each { |p| p.person.name }
|
42
42
|
end
|
43
|
+
|
43
44
|
bm.report("Finding 50 posts with person, without eager loading") do
|
44
45
|
Post.limit(50).each { |p| p.person.name }
|
45
46
|
end
|
46
|
-
|
47
47
|
bm.report("Finding 50 posts with person, with eager loading") do
|
48
48
|
Post.limit(50).includes(:person).each { |p| p.person.name }
|
49
49
|
end
|
50
|
+
|
50
51
|
bm.report("Finding 100 posts with person, without eager loading") do
|
51
52
|
Post.limit(100).each { |p| p.person.name }
|
52
53
|
end
|
53
|
-
|
54
54
|
bm.report("Finding 100 posts with person, with eager loading") do
|
55
55
|
Post.limit(100).includes(:person).each { |p| p.person.name }
|
56
56
|
end
|
57
|
+
|
58
|
+
bm.report("Finding 1000 posts with person, without eager loading") do
|
59
|
+
Post.limit(1000).each { |p| p.person.name }
|
60
|
+
end
|
61
|
+
bm.report("Finding 1000 posts with person, with eager loading") do
|
62
|
+
Post.limit(1000).includes(:person).each { |p| p.person.name }
|
63
|
+
end
|
57
64
|
end
|
@@ -1,8 +1,3 @@
|
|
1
1
|
require 'mongoid-eager-loading/mongoid/criterion/eager_loading'
|
2
2
|
require 'mongoid-eager-loading/mongoid/criteria'
|
3
|
-
require 'mongoid-eager-loading/mongoid/finders'
|
4
|
-
|
5
|
-
module Mongoid
|
6
|
-
module EagerLoading
|
7
|
-
end
|
8
|
-
end
|
3
|
+
require 'mongoid-eager-loading/mongoid/finders'
|
@@ -35,75 +35,75 @@ module Mongoid
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def setup_associations(documents, reflection)
|
38
|
-
|
38
|
+
case reflection.macro
|
39
|
+
when :references_one
|
39
40
|
setup_associations_with_ids(documents, reflection, true)
|
40
|
-
|
41
|
+
when :references_many
|
41
42
|
setup_associations_with_ids(documents, reflection, false)
|
42
|
-
|
43
|
+
when :references_and_referenced_in_many
|
43
44
|
setup_associations_with_foreign_keys(documents, reflection, false)
|
44
|
-
|
45
|
+
when :referenced_in
|
45
46
|
setup_associations_with_foreign_keys(documents, reflection, true)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
50
|
def setup_associations_with_ids(documents, reflection, one=true)
|
50
|
-
ids =
|
51
|
-
documents.each do |document|
|
52
|
-
add_id_document(document.id, document)
|
53
|
-
ids << document.id if document.id
|
54
|
-
end
|
51
|
+
ids = association_ids(documents, reflection)
|
55
52
|
|
56
|
-
association_class = reflection.name.singularize.camelize.constantize
|
57
53
|
ignore_includes
|
58
|
-
eager_associations =
|
54
|
+
eager_associations = reflection.klass.where(reflection.foreign_key.to_sym.in => ids.uniq).to_a
|
59
55
|
eager_associations.each do |eager_association|
|
60
56
|
add_id_association(eager_association.send(reflection.foreign_key), eager_association)
|
61
57
|
end
|
62
58
|
|
63
|
-
|
64
|
-
documents.each do |document|
|
65
|
-
document.instance_variable_set("@#{reflection.name}", one ? id_associations_map[id].first : id_associations_map[id])
|
66
|
-
end
|
67
|
-
end
|
59
|
+
assign_associations(documents, reflection)
|
68
60
|
end
|
69
61
|
|
70
62
|
def setup_associations_with_foreign_keys(documents, reflection, one)
|
71
|
-
ids =
|
72
|
-
foreign_key_name = reflection.foreign_key
|
73
|
-
documents.each do |document|
|
74
|
-
foreign_key_value = document.send(foreign_key_name)
|
75
|
-
if one
|
76
|
-
add_id_document(foreign_key_value, document)
|
77
|
-
ids << foreign_key_value if foreign_key_value
|
78
|
-
elsif foreign_key_value
|
79
|
-
foreign_key_value.each do |fkv|
|
80
|
-
add_id_document(fkv, document)
|
81
|
-
ids << fkv if fkv
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
63
|
+
ids = association_ids(documents, reflection)
|
85
64
|
|
86
|
-
association_class = reflection.name.singularize.camelize.constantize
|
87
65
|
ignore_includes
|
88
|
-
eager_associations =
|
66
|
+
eager_associations = reflection.klass.find(ids.uniq).to_a
|
89
67
|
eager_associations.each do |eager_association|
|
90
68
|
add_id_association(eager_association.id, eager_association)
|
91
69
|
end
|
92
70
|
|
71
|
+
assign_associations(documents, reflection)
|
72
|
+
end
|
73
|
+
|
74
|
+
def association_ids(documents, reflection)
|
75
|
+
ids = []
|
76
|
+
key_name = reflection.key
|
77
|
+
documents.each do |document|
|
78
|
+
key_value = document.send(key_name)
|
79
|
+
to_array(key_value).each do |v|
|
80
|
+
add_id_document(v, document)
|
81
|
+
ids << v
|
82
|
+
end
|
83
|
+
end
|
84
|
+
ids
|
85
|
+
end
|
86
|
+
|
87
|
+
def assign_associations(documents, reflection)
|
93
88
|
id_documents_map.each do |id, documents|
|
94
89
|
documents.each do |document|
|
95
|
-
|
90
|
+
key_value = document.send(reflection.key)
|
96
91
|
associations = \
|
97
|
-
if
|
98
|
-
id_associations_map[
|
92
|
+
if key_value.is_a?(Array)
|
93
|
+
key_value.collect { |v| id_associations_map[v] }
|
99
94
|
else
|
100
|
-
|
95
|
+
id_associations_map[key_value] ? id_associations_map[key_value].first : nil
|
101
96
|
end
|
102
97
|
document.instance_variable_set("@#{reflection.name}", associations)
|
103
98
|
end
|
104
99
|
end
|
105
100
|
end
|
106
101
|
|
102
|
+
def to_array(value)
|
103
|
+
array = value.is_a?(Array) ? value : [value]
|
104
|
+
array.compact
|
105
|
+
end
|
106
|
+
|
107
107
|
def id_documents_map
|
108
108
|
@id_documents_map ||= {}
|
109
109
|
end
|
@@ -15,12 +15,13 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "mongoid-eager-loading"
|
16
16
|
|
17
17
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
18
|
-
s.add_development_dependency "
|
18
|
+
s.add_development_dependency "mongo", "1.2.0"
|
19
|
+
s.add_development_dependency "bson", "1.2.0"
|
20
|
+
s.add_development_dependency "bson_ext", "1.2.0"
|
21
|
+
s.add_development_dependency "mongoid", "2.0.0.rc.6"
|
19
22
|
s.add_development_dependency "rspec", "~> 2.0.0"
|
20
23
|
s.add_development_dependency "mocha"
|
21
24
|
s.add_development_dependency "watchr"
|
22
|
-
s.add_development_dependency "bson_ext", "~> 1.1.1"
|
23
|
-
s.add_development_dependency "mongo", "~> 1.1.1"
|
24
25
|
|
25
26
|
s.files = `git ls-files`.split("\n")
|
26
27
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
data/spec/models/account.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
class Account
|
2
2
|
include Mongoid::Document
|
3
|
+
field :number, :type => String
|
4
|
+
field :balance, :type => String
|
5
|
+
field :nickname, :type => String
|
6
|
+
field :name, :type => String
|
7
|
+
|
8
|
+
embeds_many :memberships
|
3
9
|
referenced_in :creator, :class_name => "User", :foreign_key => :creator_id
|
4
10
|
referenced_in :person
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
11
|
+
|
12
|
+
attr_accessible :nickname, :name
|
13
|
+
|
14
|
+
validates_presence_of :name
|
15
|
+
validates_length_of :name, :maximum => 10, :on => :create
|
10
16
|
end
|
data/spec/models/address.rb
CHANGED
@@ -15,7 +15,7 @@ class Address
|
|
15
15
|
key :street
|
16
16
|
embeds_many :locations
|
17
17
|
|
18
|
-
embedded_in :addressable, :
|
18
|
+
embedded_in :addressable, :polymorphic => true do
|
19
19
|
def extension
|
20
20
|
"Testing"
|
21
21
|
end
|
@@ -24,6 +24,8 @@ class Address
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
referenced_in :account
|
28
|
+
|
27
29
|
named_scope :rodeo, where(:street => "Rodeo Dr") do
|
28
30
|
def mansion?
|
29
31
|
all? { |address| address.street == "Rodeo Dr" }
|
@@ -31,11 +33,16 @@ class Address
|
|
31
33
|
end
|
32
34
|
|
33
35
|
validates_presence_of :street, :on => :update
|
36
|
+
validates_format_of :street, :with => /\D/, :allow_nil => true
|
34
37
|
|
35
38
|
def set_parent=(set = false)
|
36
39
|
self.parent_title = addressable.title if set
|
37
40
|
end
|
38
41
|
|
42
|
+
def <=>(other)
|
43
|
+
street <=> other.street
|
44
|
+
end
|
45
|
+
|
39
46
|
class << self
|
40
47
|
def california
|
41
48
|
where(:state => "CA")
|
data/spec/models/agent.rb
CHANGED
@@ -2,7 +2,6 @@ class Agent
|
|
2
2
|
include Mongoid::Document
|
3
3
|
field :title
|
4
4
|
field :number
|
5
|
-
embeds_many :names
|
6
|
-
|
7
|
-
accepts_nested_attributes_for :posts, :allow_destroy => true
|
5
|
+
embeds_many :names, :as => :namable
|
6
|
+
referenced_in :game
|
8
7
|
end
|
data/spec/models/animal.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
class Animal
|
2
2
|
include Mongoid::Document
|
3
3
|
field :name
|
4
|
-
field :tags, :type => Array
|
4
|
+
field :tags, :type => Array
|
5
5
|
key :name
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
embedded_in :person
|
8
|
+
|
9
|
+
accepts_nested_attributes_for :person
|
10
|
+
|
8
11
|
def tag_list
|
9
12
|
tags.join(", ")
|
10
13
|
end
|
11
|
-
|
14
|
+
|
12
15
|
def tag_list=(_tag_list)
|
13
16
|
self.tags = _tag_list.split(",").map(&:strip)
|
14
|
-
end
|
17
|
+
end
|
15
18
|
end
|
data/spec/models/answer.rb
CHANGED
data/spec/models/bar.rb
ADDED
data/spec/models/book.rb
ADDED
data/spec/models/callbacks.rb
CHANGED
@@ -20,13 +20,13 @@ end
|
|
20
20
|
class Song
|
21
21
|
include Mongoid::Document
|
22
22
|
field :title
|
23
|
-
embedded_in :artist
|
23
|
+
embedded_in :artist
|
24
24
|
end
|
25
25
|
|
26
26
|
class Label
|
27
27
|
include Mongoid::Document
|
28
28
|
field :name
|
29
|
-
embedded_in :artist
|
29
|
+
embedded_in :artist
|
30
30
|
before_validation :cleanup
|
31
31
|
|
32
32
|
private
|
data/spec/models/category.rb
CHANGED
@@ -5,9 +5,9 @@ end
|
|
5
5
|
|
6
6
|
class Category
|
7
7
|
include Mongoid::Document
|
8
|
-
embedded_in :root_category
|
9
|
-
embedded_in :category
|
8
|
+
embedded_in :root_category
|
9
|
+
embedded_in :category
|
10
10
|
embeds_many :categories
|
11
11
|
|
12
12
|
field :name
|
13
|
-
end
|
13
|
+
end
|