mongoid-eager-loading 0.1.2 → 0.2.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.
@@ -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