mongoid 0.11.6 → 0.11.7
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/HISTORY +13 -0
- data/VERSION +1 -1
- data/lib/mongoid.rb +2 -0
- data/lib/mongoid/associations.rb +8 -13
- data/lib/mongoid/criteria.rb +31 -8
- data/lib/mongoid/document.rb +1 -1
- data/lib/mongoid/finders.rb +16 -0
- data/lib/mongoid/memoization.rb +27 -0
- data/mongoid.gemspec +5 -2
- data/perf/benchmark.rb +24 -23
- data/spec/integration/mongoid/criteria_spec.rb +23 -5
- data/spec/integration/mongoid/inheritance_spec.rb +18 -0
- data/spec/unit/mongoid/attributes_spec.rb +1 -0
- data/spec/unit/mongoid/criteria_spec.rb +54 -25
- data/spec/unit/mongoid/finders_spec.rb +15 -0
- data/spec/unit/mongoid/memoization_spec.rb +75 -0
- metadata +5 -2
data/HISTORY
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
=== 0.11.7
|
2
|
+
- Added #sum to criteria which takes a single field
|
3
|
+
to aggregate on. Example: Person.sum(:age) would
|
4
|
+
return a float that was the sum of all people's
|
5
|
+
ages in the db.
|
6
|
+
|
7
|
+
- Fixed issue with queries from parent classes always
|
8
|
+
casting the returned documents to the parent.
|
9
|
+
|
10
|
+
- Fixed singleton require issue.
|
11
|
+
|
12
|
+
- Group queries now run as db commands
|
13
|
+
|
1
14
|
=== 0.11.6
|
2
15
|
- Allow namespaced documents to default with:
|
3
16
|
"namespace_modelname"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.11.
|
1
|
+
0.11.7
|
data/lib/mongoid.rb
CHANGED
@@ -28,6 +28,7 @@ gem "leshill-will_paginate", ">= 2.3.11"
|
|
28
28
|
|
29
29
|
require "delegate"
|
30
30
|
require "observer"
|
31
|
+
require "singleton"
|
31
32
|
require "time"
|
32
33
|
require "validatable"
|
33
34
|
require "active_support/callbacks"
|
@@ -48,6 +49,7 @@ require "mongoid/extensions"
|
|
48
49
|
require "mongoid/errors"
|
49
50
|
require "mongoid/field"
|
50
51
|
require "mongoid/finders"
|
52
|
+
require "mongoid/memoization"
|
51
53
|
require "mongoid/timestamps"
|
52
54
|
require "mongoid/versioning"
|
53
55
|
require "mongoid/document"
|
data/lib/mongoid/associations.rb
CHANGED
@@ -11,6 +11,10 @@ module Mongoid # :nodoc:
|
|
11
11
|
module Associations #:nodoc:
|
12
12
|
def self.included(base)
|
13
13
|
base.class_eval do
|
14
|
+
# Associations need to inherit down the chain.
|
15
|
+
class_inheritable_accessor :associations
|
16
|
+
self.associations = {}.with_indifferent_access
|
17
|
+
|
14
18
|
include InstanceMethods
|
15
19
|
extend ClassMethods
|
16
20
|
end
|
@@ -35,9 +39,6 @@ module Mongoid # :nodoc:
|
|
35
39
|
end
|
36
40
|
|
37
41
|
module ClassMethods
|
38
|
-
def associations
|
39
|
-
@associations ||= {}.with_indifferent_access
|
40
|
-
end
|
41
42
|
# Adds the association back to the parent document. This macro is
|
42
43
|
# necessary to set the references from the child back to the parent
|
43
44
|
# document. If a child does not define this association calling
|
@@ -198,22 +199,16 @@ module Mongoid # :nodoc:
|
|
198
199
|
|
199
200
|
protected
|
200
201
|
# Adds the association to the associations hash with the type as the key,
|
201
|
-
# then adds the accessors for the association.
|
202
|
+
# then adds the accessors for the association. The defined setters and
|
203
|
+
# getters for the associations will perform the necessary memoization.
|
202
204
|
def add_association(type, options)
|
203
205
|
name = options.name
|
204
206
|
associations[name] = type
|
205
207
|
define_method(name) do
|
206
|
-
|
207
|
-
proxy = type.instantiate(self, options)
|
208
|
-
instance_variable_set("@#{name}", proxy)
|
208
|
+
memoized(name) { type.instantiate(self, options) }
|
209
209
|
end
|
210
210
|
define_method("#{name}=") do |object|
|
211
|
-
|
212
|
-
if instance_variable_defined?("@#{name}")
|
213
|
-
remove_instance_variable("@#{name}")
|
214
|
-
else
|
215
|
-
instance_variable_set("@#{name}", proxy)
|
216
|
-
end
|
211
|
+
reset(name) { type.update(object, self, options) }
|
217
212
|
end
|
218
213
|
end
|
219
214
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -48,9 +48,8 @@ module Mongoid #:nodoc:
|
|
48
48
|
# Example:
|
49
49
|
#
|
50
50
|
# <tt>criteria.select(:field1).where(:field1 => "Title").aggregate(Person)</tt>
|
51
|
-
def aggregate
|
52
|
-
@klass
|
53
|
-
@klass.collection.group(@options[:fields], @selector, { :count => 0 }, AGGREGATE_REDUCE)
|
51
|
+
def aggregate
|
52
|
+
@klass.collection.group(@options[:fields], @selector, { :count => 0 }, AGGREGATE_REDUCE, true)
|
54
53
|
end
|
55
54
|
|
56
55
|
# Adds a criterion to the +Criteria+ that specifies values that must all
|
@@ -165,9 +164,13 @@ module Mongoid #:nodoc:
|
|
165
164
|
@options[:fields],
|
166
165
|
@selector,
|
167
166
|
{ :group => [] },
|
168
|
-
GROUP_REDUCE
|
167
|
+
GROUP_REDUCE,
|
168
|
+
true
|
169
169
|
).collect do |docs|
|
170
|
-
docs["group"] = docs["group"].collect
|
170
|
+
docs["group"] = docs["group"].collect do |attrs|
|
171
|
+
attrs["_type"].constantize.instantiate(attrs)
|
172
|
+
end
|
173
|
+
docs
|
171
174
|
end
|
172
175
|
end
|
173
176
|
|
@@ -230,7 +233,7 @@ module Mongoid #:nodoc:
|
|
230
233
|
sorting = [[:_id, :asc]] unless sorting
|
231
234
|
opts[:sort] = sorting.collect { |option| [ option[0], option[1].invert ] }
|
232
235
|
attributes = @klass.collection.find_one(@selector, opts)
|
233
|
-
attributes ?
|
236
|
+
attributes ? attributes["_type"].constantize.instantiate(attributes) : nil
|
234
237
|
end
|
235
238
|
|
236
239
|
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
@@ -338,7 +341,7 @@ module Mongoid #:nodoc:
|
|
338
341
|
# <tt>Criteria.select(:name).where(:name = "Chrissy").one</tt>
|
339
342
|
def one
|
340
343
|
attributes = @klass.collection.find_one(@selector, @options.dup)
|
341
|
-
attributes ?
|
344
|
+
attributes ? attributes["_type"].constantize.instantiate(attributes) : nil
|
342
345
|
end
|
343
346
|
|
344
347
|
alias :first :one
|
@@ -418,6 +421,26 @@ module Mongoid #:nodoc:
|
|
418
421
|
@options[:skip] = value; self
|
419
422
|
end
|
420
423
|
|
424
|
+
SUM_REDUCE = "function(obj, prev) { prev.sum += obj.[field]; }"
|
425
|
+
# Sum the criteria. This will take the internally built selector and options
|
426
|
+
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
427
|
+
# collection itself will be retrieved from the class provided, and once the
|
428
|
+
# query has returned it will provided a grouping of keys with sums.
|
429
|
+
#
|
430
|
+
# Example:
|
431
|
+
#
|
432
|
+
# <tt>criteria.select(:field1).where(:field1 => "Title").sum</tt>
|
433
|
+
def sum(field)
|
434
|
+
collection = @klass.collection.group(
|
435
|
+
@options[:fields],
|
436
|
+
@selector,
|
437
|
+
{ :sum => 0 },
|
438
|
+
SUM_REDUCE.gsub("[field]", field.to_s),
|
439
|
+
true
|
440
|
+
)
|
441
|
+
collection.first["sum"]
|
442
|
+
end
|
443
|
+
|
421
444
|
# Translate the supplied arguments into a +Criteria+ object.
|
422
445
|
#
|
423
446
|
# If the passed in args is a single +String+, then it will
|
@@ -490,7 +513,7 @@ module Mongoid #:nodoc:
|
|
490
513
|
attributes = @klass.collection.find(@selector, @options.dup)
|
491
514
|
if attributes
|
492
515
|
@count = attributes.count
|
493
|
-
attributes.collect { |doc|
|
516
|
+
attributes.collect { |doc| doc["_type"].constantize.instantiate(doc) }
|
494
517
|
else
|
495
518
|
[]
|
496
519
|
end
|
data/lib/mongoid/document.rb
CHANGED
@@ -4,7 +4,7 @@ module Mongoid #:nodoc:
|
|
4
4
|
def self.included(base)
|
5
5
|
base.class_eval do
|
6
6
|
include ActiveSupport::Callbacks
|
7
|
-
include Associations, Attributes, Commands, Observable, Validatable
|
7
|
+
include Associations, Attributes, Commands, Memoization, Observable, Validatable
|
8
8
|
include InstanceMethods
|
9
9
|
|
10
10
|
extend ClassMethods
|
data/lib/mongoid/finders.rb
CHANGED
@@ -128,6 +128,22 @@ module Mongoid #:nodoc:
|
|
128
128
|
Criteria.new(self).only(*args)
|
129
129
|
end
|
130
130
|
|
131
|
+
# Convenience method for returning the sum of a specified field for all
|
132
|
+
# documents in the database.
|
133
|
+
#
|
134
|
+
# Options:
|
135
|
+
#
|
136
|
+
# field: The field to use when calculating the sum.
|
137
|
+
#
|
138
|
+
# Example:
|
139
|
+
#
|
140
|
+
# <tt>Person.sum(:age)</tt>
|
141
|
+
#
|
142
|
+
# Returns: <tt>Float</tt> of the sum.
|
143
|
+
def sum(field)
|
144
|
+
Criteria.new(self).sum(field)
|
145
|
+
end
|
146
|
+
|
131
147
|
# Entry point for creating a new criteria from a Document. This will
|
132
148
|
# instantiate a new +Criteria+ object with the supplied select criterion
|
133
149
|
# already added to it.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mongoid #:nodoc
|
2
|
+
module Memoization
|
3
|
+
|
4
|
+
# Handles cases when accessing an association that should be memoized in
|
5
|
+
# the Mongoid specific manner.
|
6
|
+
def memoized(name, &block)
|
7
|
+
var = "@#{name}"
|
8
|
+
if instance_variable_defined?(var)
|
9
|
+
return instance_variable_get(var)
|
10
|
+
end
|
11
|
+
value = yield
|
12
|
+
instance_variable_set(var, value)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Mongoid specific behavior is to remove the memoized object when setting
|
16
|
+
# the association, or if it wasn't previously memoized it will get set.
|
17
|
+
def reset(name, &block)
|
18
|
+
var = "@#{name}"
|
19
|
+
value = yield
|
20
|
+
if instance_variable_defined?(var)
|
21
|
+
remove_instance_variable(var)
|
22
|
+
else
|
23
|
+
instance_variable_set(var, value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/mongoid.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongoid}
|
8
|
-
s.version = "0.11.
|
8
|
+
s.version = "0.11.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Durran Jordan"]
|
12
|
-
s.date = %q{2010-01-
|
12
|
+
s.date = %q{2010-01-06}
|
13
13
|
s.email = %q{durran@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.textile"
|
@@ -68,6 +68,7 @@ Gem::Specification.new do |s|
|
|
68
68
|
"lib/mongoid/extensions/time/conversions.rb",
|
69
69
|
"lib/mongoid/field.rb",
|
70
70
|
"lib/mongoid/finders.rb",
|
71
|
+
"lib/mongoid/memoization.rb",
|
71
72
|
"lib/mongoid/timestamps.rb",
|
72
73
|
"lib/mongoid/versioning.rb",
|
73
74
|
"mongoid.gemspec",
|
@@ -121,6 +122,7 @@ Gem::Specification.new do |s|
|
|
121
122
|
"spec/unit/mongoid/extensions/time/conversions_spec.rb",
|
122
123
|
"spec/unit/mongoid/field_spec.rb",
|
123
124
|
"spec/unit/mongoid/finders_spec.rb",
|
125
|
+
"spec/unit/mongoid/memoization_spec.rb",
|
124
126
|
"spec/unit/mongoid/timestamps_spec.rb",
|
125
127
|
"spec/unit/mongoid/versioning_spec.rb",
|
126
128
|
"spec/unit/mongoid_spec.rb"
|
@@ -179,6 +181,7 @@ Gem::Specification.new do |s|
|
|
179
181
|
"spec/unit/mongoid/extensions/time/conversions_spec.rb",
|
180
182
|
"spec/unit/mongoid/field_spec.rb",
|
181
183
|
"spec/unit/mongoid/finders_spec.rb",
|
184
|
+
"spec/unit/mongoid/memoization_spec.rb",
|
182
185
|
"spec/unit/mongoid/timestamps_spec.rb",
|
183
186
|
"spec/unit/mongoid/versioning_spec.rb",
|
184
187
|
"spec/unit/mongoid_spec.rb"
|
data/perf/benchmark.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "ruby-prof"
|
3
|
+
require "benchmark"
|
3
4
|
require "mongoid"
|
4
5
|
|
5
6
|
connection = Mongo::Connection.new
|
@@ -10,7 +11,6 @@ Mongoid.database.collection("people").drop
|
|
10
11
|
class Person
|
11
12
|
include Mongoid::Document
|
12
13
|
include Mongoid::Timestamps
|
13
|
-
include Mongoid::Versioning
|
14
14
|
field :birth_date, :type => Date
|
15
15
|
has_one :name
|
16
16
|
has_one :address
|
@@ -19,7 +19,6 @@ end
|
|
19
19
|
|
20
20
|
class Name
|
21
21
|
include Mongoid::Document
|
22
|
-
include Mongoid::Timestamps
|
23
22
|
field :given
|
24
23
|
field :family
|
25
24
|
field :middle
|
@@ -28,7 +27,6 @@ end
|
|
28
27
|
|
29
28
|
class Address
|
30
29
|
include Mongoid::Document
|
31
|
-
include Mongoid::Timestamps
|
32
30
|
field :street
|
33
31
|
field :city
|
34
32
|
field :state
|
@@ -39,36 +37,39 @@ end
|
|
39
37
|
|
40
38
|
class Phone
|
41
39
|
include Mongoid::Document
|
42
|
-
include Mongoid::Timestamps
|
43
40
|
field :country_code, :type => Integer
|
44
41
|
field :number
|
45
42
|
field :phone_type
|
46
43
|
belongs_to :person, :inverse_of => :phones
|
47
44
|
end
|
48
45
|
|
49
|
-
RubyProf.start
|
46
|
+
# RubyProf.start
|
50
47
|
|
51
48
|
puts "Starting benchmark..."
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
50
|
+
Benchmark.bm do |bm|
|
51
|
+
bm.report("Mongoid") do
|
52
|
+
10000.times do |n|
|
53
|
+
person = Person.new(:birth_date => Date.new(1970, 1, 1))
|
54
|
+
name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
|
55
|
+
address = Address.new(
|
56
|
+
:street => "1 Starfleet Command Way",
|
57
|
+
:city => "San Francisco",
|
58
|
+
:state => "CA",
|
59
|
+
:post_code => "94133",
|
60
|
+
:type => "Work"
|
61
|
+
)
|
62
|
+
phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
|
63
|
+
person.name = name
|
64
|
+
person.address = address
|
65
|
+
person.phones << phone
|
66
|
+
person.save
|
67
|
+
end
|
68
|
+
end
|
68
69
|
end
|
69
70
|
|
70
|
-
result = RubyProf.stop
|
71
|
-
printer = RubyProf::FlatPrinter.new(result)
|
72
|
-
printer.print(STDOUT, 0)
|
71
|
+
# result = RubyProf.stop
|
72
|
+
# printer = RubyProf::FlatPrinter.new(result)
|
73
|
+
# printer.print(STDOUT, 0)
|
73
74
|
|
74
75
|
# Mongoid.database.collection("people").drop
|
@@ -2,16 +2,34 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Mongoid::Criteria do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
describe "#sum" do
|
6
|
+
|
7
|
+
before do
|
8
|
+
10.times do |n|
|
9
|
+
Person.create(:title => "Sir", :age => 5, :aliases => ["D", "Durran"])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
Person.delete_all
|
15
|
+
end
|
16
|
+
|
17
|
+
it "provides sums for all the fields provided" do
|
18
|
+
Person.where(:age.gt => 3).sum(:age).should == 50.0
|
19
|
+
end
|
8
20
|
|
9
|
-
after do
|
10
|
-
Person.delete_all
|
11
21
|
end
|
12
22
|
|
13
23
|
describe "#where" do
|
14
24
|
|
25
|
+
before do
|
26
|
+
@person = Person.create(:title => "Sir", :age => 33, :aliases => ["D", "Durran"])
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
Person.delete_all
|
31
|
+
end
|
32
|
+
|
15
33
|
context "with complex criterion" do
|
16
34
|
|
17
35
|
context "#all" do
|
@@ -87,6 +87,24 @@ describe Mongoid::Document do
|
|
87
87
|
|
88
88
|
end
|
89
89
|
|
90
|
+
context "when document has subclasses" do
|
91
|
+
|
92
|
+
before do
|
93
|
+
@firefox = Firefox.create(:name => "firefox")
|
94
|
+
end
|
95
|
+
|
96
|
+
after do
|
97
|
+
Firefox.delete_all
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns subclasses for querying parents" do
|
101
|
+
firefox = Canvas.where(:name => "firefox").first
|
102
|
+
firefox.should be_a_kind_of(Firefox)
|
103
|
+
firefox.should == @firefox
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
90
108
|
context "deleting subclasses" do
|
91
109
|
|
92
110
|
before do
|
@@ -4,6 +4,7 @@ describe Mongoid::Criteria do
|
|
4
4
|
|
5
5
|
before do
|
6
6
|
@criteria = Mongoid::Criteria.new(Person)
|
7
|
+
@canvas_criteria = Mongoid::Criteria.new(Canvas)
|
7
8
|
end
|
8
9
|
|
9
10
|
describe "#[]" do
|
@@ -32,22 +33,6 @@ describe Mongoid::Criteria do
|
|
32
33
|
|
33
34
|
describe "#aggregate" do
|
34
35
|
|
35
|
-
context "when klass provided" do
|
36
|
-
|
37
|
-
before do
|
38
|
-
@reduce = "function(obj, prev) { prev.count++; }"
|
39
|
-
@criteria = Mongoid::Criteria.new(Person)
|
40
|
-
@collection = mock
|
41
|
-
Person.expects(:collection).returns(@collection)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "calls group on the collection with the aggregate js" do
|
45
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce)
|
46
|
-
@criteria.only(:field1).aggregate
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
36
|
context "when klass not provided" do
|
52
37
|
|
53
38
|
before do
|
@@ -57,8 +42,8 @@ describe Mongoid::Criteria do
|
|
57
42
|
end
|
58
43
|
|
59
44
|
it "calls group on the collection with the aggregate js" do
|
60
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce)
|
61
|
-
@criteria.only(:field1).aggregate
|
45
|
+
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce, true)
|
46
|
+
@criteria.only(:field1).aggregate
|
62
47
|
end
|
63
48
|
|
64
49
|
end
|
@@ -246,7 +231,9 @@ describe Mongoid::Criteria do
|
|
246
231
|
before do
|
247
232
|
@collection = mock
|
248
233
|
Person.expects(:collection).returns(@collection)
|
249
|
-
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
234
|
+
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
235
|
+
{ "title" => "Sir", "_type" => "Person" }
|
236
|
+
)
|
250
237
|
end
|
251
238
|
|
252
239
|
it "calls find on the collection with the selector and options" do
|
@@ -271,6 +258,23 @@ describe Mongoid::Criteria do
|
|
271
258
|
|
272
259
|
end
|
273
260
|
|
261
|
+
context "when document is a subclass of the class queried from" do
|
262
|
+
|
263
|
+
before do
|
264
|
+
@collection = mock
|
265
|
+
Canvas.expects(:collection).returns(@collection)
|
266
|
+
@collection.expects(:find_one).with(@canvas_criteria.selector, @canvas_criteria.options).returns(
|
267
|
+
{ "name" => "Firefox", "_type" => "Firefox" }
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
it "instantiates the subclass" do
|
272
|
+
criteria = Mongoid::Criteria.new(Canvas)
|
273
|
+
criteria.first.should be_a_kind_of(Firefox)
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
274
278
|
end
|
275
279
|
|
276
280
|
describe "#excludes" do
|
@@ -335,7 +339,7 @@ describe Mongoid::Criteria do
|
|
335
339
|
describe "#group" do
|
336
340
|
|
337
341
|
before do
|
338
|
-
@grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30 }] }]
|
342
|
+
@grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30, "_type" => "Person" }] }]
|
339
343
|
end
|
340
344
|
|
341
345
|
context "when klass provided" do
|
@@ -348,7 +352,7 @@ describe Mongoid::Criteria do
|
|
348
352
|
end
|
349
353
|
|
350
354
|
it "calls group on the collection with the aggregate js" do
|
351
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce).returns(@grouping)
|
355
|
+
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce, true).returns(@grouping)
|
352
356
|
@criteria.only(:field1).group
|
353
357
|
end
|
354
358
|
|
@@ -363,7 +367,7 @@ describe Mongoid::Criteria do
|
|
363
367
|
end
|
364
368
|
|
365
369
|
it "calls group on the collection with the aggregate js" do
|
366
|
-
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce).returns(@grouping)
|
370
|
+
@collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce, true).returns(@grouping)
|
367
371
|
@criteria.only(:field1).group
|
368
372
|
end
|
369
373
|
|
@@ -415,7 +419,9 @@ describe Mongoid::Criteria do
|
|
415
419
|
before do
|
416
420
|
@collection = mock
|
417
421
|
Person.expects(:collection).returns(@collection)
|
418
|
-
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).returns(
|
422
|
+
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).returns(
|
423
|
+
{ "title" => "Sir", "_type" => "Person" }
|
424
|
+
)
|
419
425
|
end
|
420
426
|
|
421
427
|
it "calls find on the collection with the selector and sort options reversed" do
|
@@ -446,7 +452,9 @@ describe Mongoid::Criteria do
|
|
446
452
|
before do
|
447
453
|
@collection = mock
|
448
454
|
Person.expects(:collection).returns(@collection)
|
449
|
-
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(
|
455
|
+
@collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(
|
456
|
+
{ "title" => "Sir", "_type" => "Person" }
|
457
|
+
)
|
450
458
|
end
|
451
459
|
|
452
460
|
it "defaults to sort by id" do
|
@@ -661,7 +669,9 @@ describe Mongoid::Criteria do
|
|
661
669
|
before do
|
662
670
|
@collection = mock
|
663
671
|
Person.expects(:collection).returns(@collection)
|
664
|
-
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
672
|
+
@collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
|
673
|
+
{ "title"=> "Sir", "_type" => "Person" }
|
674
|
+
)
|
665
675
|
end
|
666
676
|
|
667
677
|
it "calls find on the collection with the selector and options" do
|
@@ -830,6 +840,25 @@ describe Mongoid::Criteria do
|
|
830
840
|
|
831
841
|
end
|
832
842
|
|
843
|
+
describe "#sum" do
|
844
|
+
|
845
|
+
context "when klass not provided" do
|
846
|
+
|
847
|
+
before do
|
848
|
+
@reduce = "function(obj, prev) { prev.sum += obj.age; }"
|
849
|
+
@collection = mock
|
850
|
+
Person.expects(:collection).returns(@collection)
|
851
|
+
end
|
852
|
+
|
853
|
+
it "calls group on the collection with the aggregate js" do
|
854
|
+
@collection.expects(:group).with(nil, {:_type => { "$in" => ["Doctor", "Person"] }}, {:sum => 0}, @reduce, true).returns([{"sum" => 50.0}])
|
855
|
+
@criteria.sum(:age)
|
856
|
+
end
|
857
|
+
|
858
|
+
end
|
859
|
+
|
860
|
+
end
|
861
|
+
|
833
862
|
describe ".translate" do
|
834
863
|
|
835
864
|
context "with a single argument" do
|
@@ -295,6 +295,21 @@ describe Mongoid::Finders do
|
|
295
295
|
|
296
296
|
end
|
297
297
|
|
298
|
+
describe ".sum" do
|
299
|
+
|
300
|
+
before do
|
301
|
+
@criteria = mock
|
302
|
+
end
|
303
|
+
|
304
|
+
it "returns the sum of a new criteria" do
|
305
|
+
Mongoid::Criteria.expects(:new).returns(@criteria)
|
306
|
+
@criteria.expects(:sum).with(:age).returns(50.0)
|
307
|
+
sum = Person.sum(:age)
|
308
|
+
sum.should == 50.0
|
309
|
+
end
|
310
|
+
|
311
|
+
end
|
312
|
+
|
298
313
|
describe ".where" do
|
299
314
|
|
300
315
|
it "returns a new criteria with select conditions added" do
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Memoization do
|
4
|
+
|
5
|
+
let(:memo) { "Memo" }
|
6
|
+
|
7
|
+
before do
|
8
|
+
@person = Person.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#memoized" do
|
12
|
+
|
13
|
+
context "when variable has been defined" do
|
14
|
+
|
15
|
+
before do
|
16
|
+
@person.instance_variable_set("@memo", memo)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns the memoized value" do
|
20
|
+
@person.memoized(:memo) { nil }.should == memo
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when variable has not been defined" do
|
26
|
+
|
27
|
+
it "returns the new value" do
|
28
|
+
@person.memoized(:memo) { memo }.should == memo
|
29
|
+
end
|
30
|
+
|
31
|
+
it "memoizes the new value" do
|
32
|
+
@person.memoized(:memo) { memo }
|
33
|
+
@person.instance_variable_get("@memo").should == memo
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#reset" do
|
41
|
+
|
42
|
+
context "when variable has been defined" do
|
43
|
+
|
44
|
+
before do
|
45
|
+
@person.instance_variable_set("@memo", memo)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "removes the memoized value" do
|
49
|
+
@person.reset(:memo) { nil }
|
50
|
+
@person.instance_variable_defined?("@memo").should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns the new value" do
|
54
|
+
@person.reset(:memo) { memo }.should == memo
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when variable has not been defined" do
|
60
|
+
|
61
|
+
it "memoizes the new value" do
|
62
|
+
@person.reset(:memo) { memo }
|
63
|
+
@person.instance_variable_get("@memo").should == memo
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns the value" do
|
67
|
+
@person.reset(:memo) { memo }.should == memo
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Durran Jordan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-06 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- lib/mongoid/extensions/time/conversions.rb
|
135
135
|
- lib/mongoid/field.rb
|
136
136
|
- lib/mongoid/finders.rb
|
137
|
+
- lib/mongoid/memoization.rb
|
137
138
|
- lib/mongoid/timestamps.rb
|
138
139
|
- lib/mongoid/versioning.rb
|
139
140
|
- mongoid.gemspec
|
@@ -187,6 +188,7 @@ files:
|
|
187
188
|
- spec/unit/mongoid/extensions/time/conversions_spec.rb
|
188
189
|
- spec/unit/mongoid/field_spec.rb
|
189
190
|
- spec/unit/mongoid/finders_spec.rb
|
191
|
+
- spec/unit/mongoid/memoization_spec.rb
|
190
192
|
- spec/unit/mongoid/timestamps_spec.rb
|
191
193
|
- spec/unit/mongoid/versioning_spec.rb
|
192
194
|
- spec/unit/mongoid_spec.rb
|
@@ -267,6 +269,7 @@ test_files:
|
|
267
269
|
- spec/unit/mongoid/extensions/time/conversions_spec.rb
|
268
270
|
- spec/unit/mongoid/field_spec.rb
|
269
271
|
- spec/unit/mongoid/finders_spec.rb
|
272
|
+
- spec/unit/mongoid/memoization_spec.rb
|
270
273
|
- spec/unit/mongoid/timestamps_spec.rb
|
271
274
|
- spec/unit/mongoid/versioning_spec.rb
|
272
275
|
- spec/unit/mongoid_spec.rb
|