mongoload 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 78571a15bc95933c04087943f3b5f13ff672c199
4
- data.tar.gz: acf8006f8200bc0c63bf3b173bee0ec573d9aafa
3
+ metadata.gz: 96fce1e2c2f42caf74c0bfb5674dcf18953aea98
4
+ data.tar.gz: 01454a26063e7ddecbf4cb7c3948bd634d5abf05
5
5
  SHA512:
6
- metadata.gz: 28e7a8b10d772f055fd60c407d5c019b2bd2d2972b4dd824672e14eddd37d86ab59a12478e390b3f5db0a0230125fd864ddcce8db857130a5ff7f1ed6a6504a9
7
- data.tar.gz: 7d0c29e43d846ea5c12e350bb325d2595b4d108314aedad9c7f6340eaaa53fda186ad4b8c04b58df10d008d5433fd2585ca5d4763adc99be40c17362666a73e8
6
+ metadata.gz: b8c5e970c9068f5b18c0bdd0bf6c361b633ca33353b5158961d771e59d9e4e049fa8cd4ab520aa2e21f7cd3d9a85cedf20930ef6de90a7187ca3ce4162d0a142
7
+ data.tar.gz: de7f5785b893aed061a9ed35221b5b624472edd47ed29253207c07fd5e8226bf54f370b3833f304ba000b6e48ba12325a575d6438e0c366f1ffa94751a1f3584
@@ -3,8 +3,8 @@ sudo: false
3
3
  services: mongodb
4
4
  rvm:
5
5
  - "2.1.10"
6
- - "2.2.4"
7
- - "2.3.0"
6
+ - "2.2.5"
7
+ - "2.3.1"
8
8
  gemfile:
9
9
  - gemfiles/mongoid_50.gemfile
10
10
  - gemfiles/mongoid_51.gemfile
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Mongoload
2
-
2
+ [![Gem Version](https://badge.fury.io/rb/mongoload.svg)](https://badge.fury.io/rb/mongoload)
3
3
  [![Build Status](https://travis-ci.org/karloku/mongoload.svg?branch=master)](https://travis-ci.org/karloku/mongoload)
4
4
 
5
5
  Mongoload is a gem to perform eager loading automatically for Mongoid, inspired by [Goldiloader](https://github.com/salsify/goldiloader).
@@ -18,13 +18,53 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install mongoload
20
20
 
21
- ## TODO
21
+ ## Options
22
+
23
+ ### :auto_include
24
+
25
+ Mark if Mongoload should perform eager loading on the relation.
26
+ Pass ```:auto_include``` option to the definition, the value should be ```true```(by default) or ```false```.
27
+
28
+ ```ruby
29
+ class User
30
+ include Mongoid::Document
31
+ has_one :device, auto_include: false # Do not perform automatic eager loading on :device relation
32
+ has_many :posts
33
+
34
+ field :username
35
+ end
36
+
37
+ # Following call will not trigger automatic eager loading on device
38
+ User.all.each(&:device)
39
+ ```
40
+
41
+ ### :fully_load
42
+
43
+ Mark if Mongoload should perform eager loading on the relation, when accessed by following methods:
44
+
45
+ + #first
46
+ + #last
47
+ + #size
48
+ + #empty?
49
+
50
+ Pass ```:fully_load``` option to the definition, the value should be ```true``` or ```false```(by default).
51
+
52
+ ```ruby
53
+ class Tag
54
+ include Mongoid::Document
55
+ has_and_belongs_to_many :posts, fully_load: true
56
+
57
+ field :name
58
+ end
59
+
60
+ # Following calls will trigger automatic eager loading on posts
61
+ Tag.all.each { |tag| tag.posts.first }
62
+ Tag.all.each { |tag| tag.posts.last }
63
+ Tag.all.each { |tag| tag.posts.size }
64
+ Tag.all.each { |tag| tag.posts.empty? }
65
+ ```
22
66
 
23
- * option to perform eager loading when calling following methods on an many/many_to_many relation:
24
- + size
25
- + first
26
- + last
27
- + option to disable eager loading on specific relation
67
+ PS: As for ```#second```, ```#third```, ```#fourth```, ```#fifth``` and ```#forty_two``` calls, mongoid will delegate them to the entries of a relation enumerable set, which makes them just same as a ```#to_a``` call.
28
68
 
29
69
  ## Copyright
30
70
 
@@ -3,7 +3,9 @@ require 'mongoid'
3
3
  require 'mongoload/version'
4
4
  require 'mongoload/auto_include_context'
5
5
  require 'mongoload/relation_loader'
6
- require 'mongoload/patches/mongoid_contextual_mongo_patch'
7
- require 'mongoload/patches/mongoid_document_patch'
8
- require 'mongoload/patches/mongoid_relations_accessors_patch'
9
- require 'mongoload/patches/mongoid_relations_targets_enumerable_patch'
6
+ require 'mongoload/patches/contextual_mongo'
7
+ require 'mongoload/patches/document'
8
+ require 'mongoload/patches/relations_accessors'
9
+ require 'mongoload/patches/relations_targets_enumerable'
10
+ require 'mongoload/patches/relations_options'
11
+ require 'mongoload/patches/relations_metadata'
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Mongoload
3
- module MongoContextWithAutoInclude
3
+ module ContextWithAutoInclude
4
4
  def documents_for_iteration
5
5
  results = super
6
6
  if results.is_a?(Mongo::Collection::View)
@@ -13,4 +13,4 @@ module Mongoload
13
13
  end
14
14
  end
15
15
 
16
- Mongoid::Contextual::Mongo.prepend Mongoload::MongoContextWithAutoInclude
16
+ Mongoid::Contextual::Mongo.prepend Mongoload::ContextWithAutoInclude
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ module Mongoload
3
+ module RelationsAccessorsWithAutoInclude
4
+ private_class_method
5
+
6
+ def self.assign_missing_proxy_method(relation)
7
+ if relation.class == Mongoid::Relations::Targets::Enumerable
8
+ relation.target.define_singleton_method :relation_metadata do
9
+ relation.relation_metadata
10
+ end
11
+
12
+ relation.target.define_singleton_method :base do
13
+ relation.base
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def get_relation(name, metadata, object, reload=false)
21
+ # has_one and belongs_to will return the value immediately
22
+ # while other relation are lazy
23
+ if [Mongoid::Relations::Referenced::In, Mongoid::Relations::Referenced::One].include?(metadata.relation)
24
+ Mongoload::RelationLoader.load(self, metadata) if !object.is_a?(metadata.klass) && ivar(name) == false
25
+ end
26
+
27
+ result = super
28
+ result.tap do |relation|
29
+ Mongoload::RelationsAccessorsWithAutoInclude.assign_missing_proxy_method(relation)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ Mongoid::Document.prepend Mongoload::RelationsAccessorsWithAutoInclude
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module Mongoload
3
+ module RelationsMetadataWithOptions
4
+ def auto_include?
5
+ fetch(:auto_include, true)
6
+ end
7
+
8
+ def fully_load?
9
+ fetch(:fully_load, false)
10
+ end
11
+ end
12
+ end
13
+
14
+ ::Mongoid::Relations::Metadata.include ::Mongoload::RelationsMetadataWithOptions
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ module Mongoload
3
+ module RelationsOptions
4
+ MONGOLOAD_OPTIONS = [
5
+ :auto_include,
6
+ :fully_load
7
+ ].freeze
8
+
9
+ def validate!(options)
10
+ options_clone = options.clone
11
+ MONGOLOAD_OPTIONS.each { |key| options_clone.delete(key) }
12
+ super(options_clone)
13
+ end
14
+ end
15
+ end
16
+
17
+ class << ::Mongoid::Relations::Options
18
+ prepend ::Mongoload::RelationsOptions
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ module Mongoload
3
+ module RelationsEnumerableWithAutoInclude
4
+ # methods which trigger Mongoload only when :fully_load is true
5
+ # other methods delegated to #target will be processed by #unloaded_documents
6
+ %w(first last size empty?).each do |method|
7
+ define_method method do
8
+ if !_loaded? && relation_metadata.fully_load? && Mongoload::RelationLoader.load(base, relation_metadata)
9
+ base.ivar(relation_metadata.name).public_send(method)
10
+ else
11
+ super()
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ # perform eager loading when loading unloaded documents
19
+ def unloaded_documents
20
+ if !_loaded? && Mongoload::RelationLoader.load(base, relation_metadata)
21
+ base.ivar(relation_metadata.name)
22
+ else
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ Mongoid::Relations::Targets::Enumerable.prepend Mongoload::RelationsEnumerableWithAutoInclude
@@ -16,7 +16,7 @@ module Mongoload
16
16
  end
17
17
 
18
18
  def auto_include?(doc, metadata)
19
- relation?(doc, metadata) && !loaded?(doc, metadata)
19
+ metadata.auto_include? && relation?(doc, metadata) && !loaded?(doc, metadata)
20
20
  end
21
21
 
22
22
  def relation?(doc, metadata)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module Mongoload
3
3
  # mongoload version
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
@@ -24,7 +24,7 @@ end
24
24
 
25
25
  class Tag
26
26
  include Mongoid::Document
27
- has_and_belongs_to_many :posts
27
+ has_and_belongs_to_many :posts, fully_load: true
28
28
 
29
29
  field :name
30
30
  end
@@ -11,53 +11,53 @@ describe Mongoload do
11
11
  let(:user3) do
12
12
  User.create!(username: 'Cathy').tap { |u| u.create_device(uuid: '333') }
13
13
  end
14
+ let(:build_users) { [user1, user2, user3] }
15
+ let(:users) { User.all.to_a }
16
+ let(:devices) { Device.all.to_a }
14
17
 
15
18
  let(:tag1) { Tag.create!(name: 'tag1') }
16
19
  let(:tag2) { Tag.create!(name: 'tag2') }
17
20
  let(:tag3) { Tag.create!(name: 'tag3') }
18
21
  let(:tag4) { Tag.create!(name: 'tag4') }
22
+ let(:tags) { Tag.all.to_a }
19
23
 
20
24
  let(:post1) do
21
25
  Post.create!(title: 'post1', user: user1).tap do |p|
22
26
  p.tags << [tag1, tag2]
23
27
  end
24
28
  end
25
-
26
29
  let(:post2) do
27
30
  Post.create!(title: 'post2', user: user1).tap do |p|
28
31
  p.tags << [tag2, tag3]
29
32
  end
30
33
  end
31
-
32
34
  let(:post3) do
33
35
  Post.create!(title: 'post3', user: user2).tap do |p|
34
36
  p.tags << [tag1, tag3]
35
37
  end
36
38
  end
37
-
38
39
  let(:post4) do
39
40
  Post.create!(title: 'post4', user: user2).tap do |p|
40
41
  p.tags << [tag2, tag4]
41
42
  end
42
43
  end
43
-
44
44
  let(:post5) do
45
45
  Post.create!(title: 'post5', user: user3).tap do |p|
46
46
  p.tags << [tag1, tag4]
47
47
  end
48
48
  end
49
-
50
49
  let(:post6) do
51
50
  Post.create!(title: 'post6', user: user3).tap do |p|
52
51
  p.tags << [tag2, tag4]
53
52
  end
54
53
  end
54
+ let(:build_posts) { [post1, post2, post3, post4, post5, post6] }
55
+ let(:posts) { Post.all.to_a }
55
56
 
56
57
  describe 'has_one relation' do
57
- before { user1 && user2 && user3 }
58
+ before { build_users }
58
59
 
59
60
  it 'should eager load' do
60
- users = User.all.to_a
61
61
  users.each do |user|
62
62
  expect(user.ivar(:device)).to be false
63
63
  end
@@ -70,10 +70,9 @@ describe Mongoload do
70
70
  end
71
71
 
72
72
  describe 'has_many relation' do
73
- before { post1 && post2 && post3 && post4 && post5 && post6 }
73
+ before { build_posts }
74
74
 
75
75
  it 'should eager load' do
76
- users = User.all.to_a
77
76
  users.each do |user|
78
77
  expect(user.posts._loaded?).to be false
79
78
  end
@@ -87,10 +86,9 @@ describe Mongoload do
87
86
 
88
87
  describe 'belongs_to' do
89
88
  context 'inverse of has_one' do
90
- before { user1 && user2 && user3 }
89
+ before { build_users }
91
90
 
92
91
  it 'should eager load' do
93
- devices = Device.all.to_a
94
92
  devices.each do |device|
95
93
  expect(device.ivar(:user)).to be false
96
94
  end
@@ -103,10 +101,9 @@ describe Mongoload do
103
101
  end
104
102
 
105
103
  context 'inverse of has_many' do
106
- before { post1 && post2 && post3 && post4 && post5 && post6 }
104
+ before { build_posts }
107
105
 
108
106
  it 'should eager load' do
109
- posts = Post.all.to_a
110
107
  posts.each do |post|
111
108
  expect(post.ivar(:user)).to be false
112
109
  end
@@ -120,10 +117,9 @@ describe Mongoload do
120
117
  end
121
118
 
122
119
  describe 'has_and_belongs_to_many' do
123
- before { post1 && post2 && post3 && post4 && post5 && post6 }
120
+ before { build_posts }
124
121
 
125
122
  it 'should eager load' do
126
- posts = Post.all.to_a
127
123
  posts.each do |post|
128
124
  expect(post.tags._loaded?).to be false
129
125
  end
@@ -134,4 +130,60 @@ describe Mongoload do
134
130
  end
135
131
  end
136
132
  end
133
+
134
+ describe 'auto_include' do
135
+ before { build_users }
136
+ context 'is set to false' do
137
+ before do
138
+ UserWithoutAutoInclude = User.clone
139
+ UserWithoutAutoInclude.has_one :device, auto_include: false
140
+ end
141
+ it 'should not eager load' do
142
+ users = UserWithoutAutoInclude.all.to_a
143
+ users.each do |user|
144
+ expect(user.ivar(:device)).to be false
145
+ end
146
+
147
+ users.first.device
148
+ users[1..-1].each do |user|
149
+ expect(user.ivar(:device)).to be false
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ describe 'fully_load' do
156
+ FULLY_LOAD_METHODS = %w(first last size empty?).freeze
157
+ before { build_posts }
158
+
159
+ context 'is set to true' do
160
+ FULLY_LOAD_METHODS.each do |method|
161
+ it "should eager load with ##{method}" do
162
+ tags.each do |tag|
163
+ expect(tag.posts._loaded?).to be false
164
+ end
165
+
166
+ tags.first.posts.public_send(method)
167
+ tags.each do |tag|
168
+ expect(tag.posts._loaded?).to be true
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ context 'is set to false' do
175
+ FULLY_LOAD_METHODS.each do |method|
176
+ it "should not eager load with ##{method}" do
177
+ posts.each do |post|
178
+ expect(post.tags._loaded?).to be false
179
+ end
180
+
181
+ posts.first.tags.public_send(method)
182
+ posts[1..-1].each do |post|
183
+ expect(post.tags._loaded?).to be false
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
137
189
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoload
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaloku Sang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid
@@ -144,10 +144,12 @@ files:
144
144
  - gemfiles/mongoid_master.gemfile
145
145
  - lib/mongoload.rb
146
146
  - lib/mongoload/auto_include_context.rb
147
- - lib/mongoload/patches/mongoid_contextual_mongo_patch.rb
148
- - lib/mongoload/patches/mongoid_document_patch.rb
149
- - lib/mongoload/patches/mongoid_relations_accessors_patch.rb
150
- - lib/mongoload/patches/mongoid_relations_targets_enumerable_patch.rb
147
+ - lib/mongoload/patches/contextual_mongo.rb
148
+ - lib/mongoload/patches/document.rb
149
+ - lib/mongoload/patches/relations_accessors.rb
150
+ - lib/mongoload/patches/relations_metadata.rb
151
+ - lib/mongoload/patches/relations_options.rb
152
+ - lib/mongoload/patches/relations_targets_enumerable.rb
151
153
  - lib/mongoload/relation_loader.rb
152
154
  - lib/mongoload/version.rb
153
155
  - log/.keep
@@ -177,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
179
  version: '0'
178
180
  requirements: []
179
181
  rubyforge_project:
180
- rubygems_version: 2.6.3
182
+ rubygems_version: 2.6.4
181
183
  signing_key:
182
184
  specification_version: 4
183
185
  summary: Perform eager loading automatically for Mongoid
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
- module Mongoload
3
- module MongoRelationsAccessorsWithAutoInclude
4
- private
5
-
6
- def get_relation(name, metadata, object, reload=false)
7
- # has_one and belongs_to will return the value immediately
8
- # while other relation are lazy
9
- if [Mongoid::Relations::Referenced::In, Mongoid::Relations::Referenced::One].include?(metadata.relation)
10
- Mongoload::RelationLoader.load(self, metadata) if !object.is_a?(metadata.klass) && ivar(name) == false
11
- end
12
-
13
- result = super
14
- result.tap do |relation|
15
- if relation.class == Mongoid::Relations::Targets::Enumerable
16
- relation.target.define_singleton_method :relation_metadata do
17
- relation.relation_metadata
18
- end
19
-
20
- relation.target.define_singleton_method :base do
21
- relation.base
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
28
-
29
- Mongoid::Document.prepend Mongoload::MongoRelationsAccessorsWithAutoInclude
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
- module Mongoload
3
- module MongoRelationsEnumerableWithAutoInclude
4
- private
5
-
6
- def unloaded_documents
7
- if Mongoload::RelationLoader.load(base, relation_metadata)
8
- base.ivar(relation_metadata.name)
9
- else
10
- super
11
- end
12
- rescue NotImplementedError
13
- super
14
- end
15
- end
16
- end
17
-
18
- Mongoid::Relations::Targets::Enumerable.prepend Mongoload::MongoRelationsEnumerableWithAutoInclude