mongoid-eager-loading 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mongoid-eager-loading (0.1.2)
4
+ mongoid-eager-loading (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -10,7 +10,7 @@ module Mongoid
10
10
  # <tt>criteria.includes(:user, :post)</tt>
11
11
  #
12
12
  # Returns: <tt>self</tt>
13
- attr_accessor :eager_loadings, :id_document_map, :id_associations_map
13
+ attr_accessor :eager_loadings, :id_documents_map, :id_associations_map
14
14
 
15
15
  def includes(*options)
16
16
  @eager_loadings = options
@@ -18,12 +18,13 @@ module Mongoid
18
18
  end
19
19
 
20
20
  def preload(documents)
21
+ return if documents.blank?
21
22
  document_class = documents.first.class
22
23
  @eager_loadings.each do |eager_loading|
23
24
  setup_associations(documents, association_reflection(document_class, eager_loading))
24
25
  end
25
26
  end
26
-
27
+
27
28
  private
28
29
  def ignore_includes
29
30
  @eager_loadings = nil
@@ -48,19 +49,21 @@ module Mongoid
48
49
  def setup_associations_with_ids(documents, reflection, one=true)
49
50
  ids = []
50
51
  documents.each do |document|
51
- id_document_map[document.id] = document
52
+ add_id_document(document.id, document)
52
53
  ids << document.id if document.id
53
54
  end
54
55
 
55
56
  association_class = reflection.name.singularize.camelize.constantize
56
57
  ignore_includes
57
- eager_associations = association_class.where(reflection.foreign_key.to_sym.in => ids).to_a
58
+ eager_associations = association_class.where(reflection.foreign_key.to_sym.in => ids.uniq).to_a
58
59
  eager_associations.each do |eager_association|
59
60
  add_id_association(eager_association.send(reflection.foreign_key), eager_association)
60
61
  end
61
62
 
62
- id_document_map.each do |id, document|
63
- document.send("#{reflection.name}=", one ? id_associations_map[id].first : id_associations_map[id])
63
+ id_documents_map.each do |id, documents|
64
+ documents.each do |document|
65
+ document.instance_variable_set("@#{reflection.name}", one ? id_associations_map[id].first : id_associations_map[id])
66
+ end
64
67
  end
65
68
  end
66
69
 
@@ -70,11 +73,11 @@ module Mongoid
70
73
  documents.each do |document|
71
74
  foreign_key_value = document.send(foreign_key_name)
72
75
  if one
73
- id_document_map[foreign_key_value] = document
76
+ add_id_document(foreign_key_value, document)
74
77
  ids << foreign_key_value if foreign_key_value
75
78
  elsif foreign_key_value
76
79
  foreign_key_value.each do |fkv|
77
- id_document_map[fkv] = document
80
+ add_id_document(fkv, document)
78
81
  ids << fkv if fkv
79
82
  end
80
83
  end
@@ -82,31 +85,38 @@ module Mongoid
82
85
 
83
86
  association_class = reflection.name.singularize.camelize.constantize
84
87
  ignore_includes
85
- eager_associations = association_class.find(ids).to_a
88
+ eager_associations = association_class.find(ids.uniq).to_a
86
89
  eager_associations.each do |eager_association|
87
90
  add_id_association(eager_association.id, eager_association)
88
91
  end
89
92
 
90
- id_document_map.each do |id, document|
91
- foreign_key_value = document.send(foreign_key_name)
92
- associations = \
93
- if one
94
- id_associations_map[foreign_key_value].first
95
- else
96
- foreign_key_value.collect { |fkv| id_associations_map[fkv] }.flatten.uniq
97
- end
98
- document.send("#{reflection.name}=", associations)
93
+ id_documents_map.each do |id, documents|
94
+ documents.each do |document|
95
+ foreign_key_value = document.send(foreign_key_name)
96
+ associations = \
97
+ if one
98
+ id_associations_map[foreign_key_value].first
99
+ else
100
+ foreign_key_value.collect { |fkv| id_associations_map[fkv] }.flatten.uniq
101
+ end
102
+ document.instance_variable_set("@#{reflection.name}", associations)
103
+ end
99
104
  end
100
105
  end
101
106
 
102
- def id_document_map
103
- @id_doccument_map ||= {}
107
+ def id_documents_map
108
+ @id_documents_map ||= {}
104
109
  end
105
110
 
106
111
  def id_associations_map
107
112
  @id_associations_map ||= {}
108
113
  end
109
114
 
115
+ def add_id_document(id, document)
116
+ id_documents_map[id] ||= []
117
+ id_documents_map[id] << document
118
+ end
119
+
110
120
  def add_id_association(id, association)
111
121
  id_associations_map[id] ||= []
112
122
  id_associations_map[id] << association
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module EagerLoading
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -23,5 +23,12 @@ describe Mongoid::Criteria do
23
23
  criteria.collect(&:title).should == ["Sir", "Madam"]
24
24
  criteria.collect(&:game).should == [@person1.game, @person2.game]
25
25
  end
26
+
27
+ it "empty parent objects with include" do
28
+ Game.destroy_all
29
+ Person.destroy_all
30
+ criteria = Person.includes(:game)
31
+ criteria.collect(&:game).should == []
32
+ end
26
33
  end
27
34
  end
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe Mongoid::Criterion::EagerLoading do
4
4
 
5
5
  describe "#includes" do
6
-
6
+
7
7
  it "should return self" do
8
8
  criteria = Mongoid::Criteria.new(Person)
9
9
  criteria.includes(:game, :posts).should == criteria
@@ -23,86 +23,130 @@ describe Mongoid::Criterion::EagerLoading do
23
23
  Post.destroy_all
24
24
  Game.destroy_all
25
25
  Person.destroy_all
26
-
27
- person1 = Person.create(:title => "Sir", :age => 100, :aliases => ["D", "Durran"], :ssn => "666666666")
28
- person2 = Person.create(:title => "Madam", :age => 1, :ssn => "098-76-5434")
29
-
30
- person1.create_game(:score => 10)
31
- person2.create_game(:score => 20)
32
-
33
- person1.posts.create(:title => "post1")
34
- person1.posts.create(:title => "post2")
35
- person2.posts.create(:title => "post3")
36
- person2.posts.create(:title => "post4")
37
-
38
- person1.preferences.create(:name => "preference1")
39
- person1.preferences.create(:name => "preference2")
40
- person2.preferences.create(:name => "preference3")
41
- person2.preferences.create(:name => "preference4")
26
+
27
+ @person1 = Person.create(:title => "Sir", :age => 100, :aliases => ["D", "Durran"], :ssn => "666666666")
28
+ @person2 = Person.create(:title => "Madam", :age => 1, :ssn => "098-76-5434")
29
+
30
+ @game1 = @person1.create_game(:score => 10)
31
+ @game2 = @person2.create_game(:score => 20)
32
+
33
+ @post1 = @person1.posts.create(:title => "post1")
34
+ @post2 = @person1.posts.create(:title => "post2")
35
+ @post3 = @person2.posts.create(:title => "post3")
36
+ @post4 = @person2.posts.create(:title => "post4")
37
+
38
+ @preference1 = @person1.preferences.create(:name => "preference1")
39
+ @preference2 = @person1.preferences.create(:name => "preference2")
40
+ @preference3 = @person2.preferences.create(:name => "preference3")
41
+ @preference4 = @person2.preferences.create(:name => "preference4")
42
42
  end
43
43
 
44
44
  it "preload references_one association" do
45
45
  people = Person.all.to_a
46
46
  games = Game.all.to_a
47
47
 
48
- complex = stub(:key => :person_id, :operator => "in")
49
- Mongoid::Criterion::Complex.expects(:new).with(:key => :person_id, :operator => "in").returns(complex)
50
- Game.expects(:where).with(complex => people.collect(&:id)).returns(games)
51
-
52
48
  criteria = Mongoid::Criteria.new(Person)
53
49
  criteria.includes(:game)
54
50
  criteria.preload(people)
55
51
 
56
- people.first.game.should == games.first
57
- people.last.game.should == games.last
52
+ id_documents_map = criteria.send(:id_documents_map)
53
+ id_documents_map[@person1.id].should == [@person1]
54
+ id_documents_map[@person2.id].should == [@person2]
55
+
56
+ id_associations_map = criteria.send(:id_associations_map)
57
+ id_associations_map[@person1.id].should == [@game1]
58
+ id_associations_map[@person2.id].should == [@game2]
59
+
60
+ @person1.game.should == @game1
61
+ @person2.game.should == @game2
58
62
  end
59
63
 
60
64
  it "preload references_many association" do
61
65
  people = Person.all.to_a
62
66
  posts = Post.all.to_a
63
- person1_posts = Post.where(:person_id => people.first.id).to_a
64
- person2_posts = Post.where(:person_id => people.last.id).to_a
65
67
 
66
- complex = stub(:key => :person_id, :operator => "in")
67
- Mongoid::Criterion::Complex.expects(:new).with(:key => :person_id, :operator => "in").returns(complex)
68
- Post.expects(:where).with(complex => people.collect(&:id)).returns(posts)
69
-
70
68
  criteria = Mongoid::Criteria.new(Person)
71
69
  criteria.includes(:posts)
72
70
  criteria.preload(people)
73
71
 
74
- people.first.posts.should == person1_posts
75
- people.last.posts.should == person2_posts
72
+ id_documents_map = criteria.send(:id_documents_map)
73
+ id_documents_map[@person1.id].should == [@person1]
74
+ id_documents_map[@person2.id].should == [@person2]
75
+
76
+ id_associations_map = criteria.send(:id_associations_map)
77
+ id_associations_map[@person1.id].should == [@post1, @post2]
78
+ id_associations_map[@person2.id].should == [@post3, @post4]
79
+
80
+ @person1.posts.should == [@post1, @post2]
81
+ @person2.posts.should == [@post3, @post4]
76
82
  end
77
83
 
78
84
  it "preload references_many_as_array association" do
79
85
  people = Person.all.to_a
80
86
  preferences = Preference.all.to_a
81
- person1_preferences = Preference.find(people.first.preference_ids).to_a
82
- person2_preferences = Preference.find(people.last.preference_ids).to_a
83
-
84
- Preference.expects(:find).with(preferences.collect(&:id)).returns(preferences)
85
87
 
86
88
  criteria = Mongoid::Criteria.new(Person)
87
89
  criteria.includes(:preferences)
88
90
  criteria.preload(people)
89
91
 
90
- people.first.preferences.should == person1_preferences
91
- people.last.preferences.should == person2_preferences
92
+ id_documents_map = criteria.send(:id_documents_map)
93
+ id_documents_map[@preference1.id].should == [@person1]
94
+ id_documents_map[@preference2.id].should == [@person1]
95
+ id_documents_map[@preference3.id].should == [@person2]
96
+ id_documents_map[@preference4.id].should == [@person2]
97
+
98
+ id_associations_map = criteria.send(:id_associations_map)
99
+ id_associations_map[@preference1.id].should == [@preference1]
100
+ id_associations_map[@preference2.id].should == [@preference2]
101
+ id_associations_map[@preference3.id].should == [@preference3]
102
+ id_associations_map[@preference4.id].should == [@preference4]
103
+
104
+ @person1.preferences.should == [@preference1, @preference2]
105
+ @person2.preferences.should == [@preference3, @preference4]
92
106
  end
93
107
 
94
- it "preload referenced_in association" do
95
- people = Person.all.to_a
96
- games = Game.all.to_a
108
+ context "referenced_in" do
109
+ it "preload referenced_in association to references_one" do
110
+ people = Person.all.to_a
111
+ games = Game.all.to_a
112
+
113
+ criteria = Mongoid::Criteria.new(Game)
114
+ criteria.includes(:person)
115
+ criteria.preload(games)
116
+
117
+ id_documents_map = criteria.send(:id_documents_map)
118
+ id_documents_map[@person1.id].should == [@game1]
119
+ id_documents_map[@person2.id].should == [@game2]
120
+
121
+ id_associations_map = criteria.send(:id_associations_map)
122
+ id_associations_map[@person1.id].should == [@person1]
123
+ id_associations_map[@person2.id].should == [@person2]
124
+
125
+ @game1.person.should == @person1
126
+ @game2.person.should == @person2
127
+ end
128
+
129
+ it "preload referenced_in association to references_many" do
130
+ people = Person.all.to_a
131
+ posts = Post.all.to_a
132
+
133
+ criteria = Mongoid::Criteria.new(Game)
134
+ criteria.includes(:person)
135
+ criteria.preload(posts)
136
+
137
+ id_documents_map = criteria.send(:id_documents_map)
138
+ id_documents_map[@person1.id].should == [@post1, @post2]
139
+ id_documents_map[@person2.id].should == [@post3, @post4]
97
140
 
98
- Person.expects(:find).with(people.collect(&:id)).returns(people)
99
-
100
- criteria = Mongoid::Criteria.new(Game)
101
- criteria.includes(:person)
102
- criteria.preload(games)
141
+ id_associations_map = criteria.send(:id_associations_map)
142
+ id_associations_map[@person1.id].should == [@person1]
143
+ id_associations_map[@person2.id].should == [@person2]
103
144
 
104
- people.first.game.should == games.first
105
- people.last.game.should == games.last
145
+ @post1.person.should == @person1
146
+ @post2.person.should == @person1
147
+ @post3.person.should == @person2
148
+ @post4.person.should == @person2
149
+ end
106
150
  end
107
151
  end
108
152
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-eager-loading
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
8
  - 2
10
- version: 0.1.2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Richard Huang
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-19 00:00:00 +08:00
18
+ date: 2011-01-19 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency