mongoload 0.0.2 → 0.0.3

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.
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