mongoid 1.2.7 → 1.2.8
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/VERSION +1 -1
- data/lib/mongoid.rb +2 -1
- data/lib/mongoid/associations.rb +18 -14
- data/lib/mongoid/associations/has_many_related.rb +1 -1
- data/lib/mongoid/associations/meta_data.rb +28 -0
- data/lib/mongoid/associations/options.rb +1 -6
- data/lib/mongoid/attributes.rb +1 -1
- data/lib/mongoid/caching.rb +41 -0
- data/lib/mongoid/collection.rb +1 -0
- data/lib/mongoid/components.rb +1 -0
- data/lib/mongoid/config.rb +2 -0
- data/lib/mongoid/contexts/mongo.rb +8 -13
- data/lib/mongoid/criteria.rb +7 -2
- data/lib/mongoid/criterion/inclusion.rb +1 -0
- data/lib/mongoid/criterion/optional.rb +10 -2
- data/lib/mongoid/finders.rb +5 -23
- data/lib/mongoid/identity.rb +1 -1
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/mongoid.gemspec +12 -2
- data/spec/integration/mongoid/attributes_spec.rb +2 -2
- data/spec/integration/mongoid/commands_spec.rb +5 -3
- data/spec/integration/mongoid/criteria_spec.rb +27 -0
- data/spec/models/game.rb +2 -1
- data/spec/models/post.rb +1 -1
- data/spec/unit/mongoid/associations/has_many_related_spec.rb +5 -1
- data/spec/unit/mongoid/associations/meta_data_spec.rb +88 -0
- data/spec/unit/mongoid/associations/options_spec.rb +20 -19
- data/spec/unit/mongoid/associations_spec.rb +41 -7
- data/spec/unit/mongoid/caching_spec.rb +63 -0
- data/spec/unit/mongoid/collection_spec.rb +20 -4
- data/spec/unit/mongoid/config_spec.rb +7 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +51 -12
- data/spec/unit/mongoid/criteria_spec.rb +23 -1
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +8 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +0 -10
- data/spec/unit/mongoid/identity_spec.rb +24 -3
- data/spec/unit/mongoid/javascript_spec.rb +48 -0
- metadata +12 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.8
|
data/lib/mongoid.rb
CHANGED
@@ -38,8 +38,8 @@ require "active_support/time_with_zone"
|
|
38
38
|
require "will_paginate/collection"
|
39
39
|
require "mongo"
|
40
40
|
require "mongoid/associations"
|
41
|
-
require "mongoid/associations/options"
|
42
41
|
require "mongoid/attributes"
|
42
|
+
require "mongoid/caching"
|
43
43
|
require "mongoid/callbacks"
|
44
44
|
require "mongoid/collection"
|
45
45
|
require "mongoid/commands"
|
@@ -56,6 +56,7 @@ require "mongoid/fields"
|
|
56
56
|
require "mongoid/finders"
|
57
57
|
require "mongoid/identity"
|
58
58
|
require "mongoid/indexes"
|
59
|
+
require "mongoid/javascript"
|
59
60
|
require "mongoid/matchers"
|
60
61
|
require "mongoid/memoization"
|
61
62
|
require "mongoid/named_scope"
|
data/lib/mongoid/associations.rb
CHANGED
@@ -6,6 +6,8 @@ require "mongoid/associations/has_many"
|
|
6
6
|
require "mongoid/associations/has_many_related"
|
7
7
|
require "mongoid/associations/has_one"
|
8
8
|
require "mongoid/associations/has_one_related"
|
9
|
+
require "mongoid/associations/options"
|
10
|
+
require "mongoid/associations/meta_data"
|
9
11
|
|
10
12
|
module Mongoid # :nodoc:
|
11
13
|
module Associations #:nodoc:
|
@@ -28,13 +30,13 @@ module Mongoid # :nodoc:
|
|
28
30
|
|
29
31
|
# Updates all the one-to-many relational associations for the name.
|
30
32
|
def update_associations(name)
|
31
|
-
send(name).each { |doc| doc.save }
|
33
|
+
send(name).each { |doc| doc.save } if new_record?
|
32
34
|
end
|
33
35
|
|
34
36
|
# Update the one-to-one relational association for the name.
|
35
37
|
def update_association(name)
|
36
38
|
association = send(name)
|
37
|
-
association.save
|
39
|
+
association.save if new_record? && !association.nil?
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
@@ -87,14 +89,12 @@ module Mongoid # :nodoc:
|
|
87
89
|
# end
|
88
90
|
#
|
89
91
|
def belongs_to_related(name, options = {}, &block)
|
90
|
-
|
91
|
-
|
92
|
-
add_association(
|
93
|
-
Associations::BelongsToRelated,
|
94
|
-
Associations::Options.new(
|
95
|
-
options.merge(:name => name, :extend => block)
|
92
|
+
opts = Associations::Options.new(
|
93
|
+
options.merge(:name => name, :extend => block, :foreign_key => foreign_key(name, options))
|
96
94
|
)
|
97
|
-
)
|
95
|
+
add_association(Associations::BelongsToRelated, opts)
|
96
|
+
field opts.foreign_key
|
97
|
+
index opts.foreign_key unless self.embedded
|
98
98
|
end
|
99
99
|
|
100
100
|
# Adds the association from a parent document to its children. The name
|
@@ -140,10 +140,9 @@ module Mongoid # :nodoc:
|
|
140
140
|
# end
|
141
141
|
#
|
142
142
|
def has_many_related(name, options = {}, &block)
|
143
|
-
add_association(
|
144
|
-
Associations::HasManyRelated,
|
143
|
+
add_association(Associations::HasManyRelated,
|
145
144
|
Associations::Options.new(
|
146
|
-
options.merge(:name => name, :
|
145
|
+
options.merge(:name => name, :foreign_key => foreign_key(self.name, options), :extend => block)
|
147
146
|
)
|
148
147
|
)
|
149
148
|
before_save do |document|
|
@@ -197,7 +196,7 @@ module Mongoid # :nodoc:
|
|
197
196
|
add_association(
|
198
197
|
Associations::HasOneRelated,
|
199
198
|
Associations::Options.new(
|
200
|
-
options.merge(:name => name, :
|
199
|
+
options.merge(:name => name, :foreign_key => foreign_key(name, options), :extend => block)
|
201
200
|
)
|
202
201
|
)
|
203
202
|
before_save do |document|
|
@@ -226,7 +225,7 @@ module Mongoid # :nodoc:
|
|
226
225
|
# getters for the associations will perform the necessary memoization.
|
227
226
|
def add_association(type, options)
|
228
227
|
name = options.name.to_s
|
229
|
-
associations[name] = type
|
228
|
+
associations[name] = MetaData.new(type, options)
|
230
229
|
define_method(name) do
|
231
230
|
memoized(name) { type.instantiate(self, options) }
|
232
231
|
end
|
@@ -253,6 +252,11 @@ module Mongoid # :nodoc:
|
|
253
252
|
document.save; document
|
254
253
|
end
|
255
254
|
end
|
255
|
+
|
256
|
+
# Find the foreign key.
|
257
|
+
def foreign_key(name, options)
|
258
|
+
options[:foreign_key] || name.to_s.foreign_key
|
259
|
+
end
|
256
260
|
end
|
257
261
|
end
|
258
262
|
end
|
@@ -59,7 +59,7 @@ module Mongoid #:nodoc:
|
|
59
59
|
# options: The association +Options+.
|
60
60
|
def initialize(document, options, target = nil)
|
61
61
|
@parent, @klass = document, options.klass
|
62
|
-
@foreign_key =
|
62
|
+
@foreign_key = options.foreign_key
|
63
63
|
@target = target || @klass.all(:conditions => { @foreign_key => document.id })
|
64
64
|
extends(options)
|
65
65
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Associations #:nodoc:
|
4
|
+
class MetaData #:nodoc:
|
5
|
+
|
6
|
+
attr_reader :association, :options
|
7
|
+
|
8
|
+
delegate :macro, :to => :association
|
9
|
+
|
10
|
+
# Delegate all methods on +Options+ to the options instance.
|
11
|
+
Associations::Options.public_instance_methods(false).each do |name|
|
12
|
+
define_method(name) { |*args| @options.send(name) }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create the new associations MetaData object, which holds the type of
|
16
|
+
# the association and its options, with convenience methods for getting
|
17
|
+
# that information.
|
18
|
+
#
|
19
|
+
# Options:
|
20
|
+
#
|
21
|
+
# association: The association type as a class instance.
|
22
|
+
# options: The association options
|
23
|
+
def initialize(association, options)
|
24
|
+
@association, @options = association, options
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -21,7 +21,7 @@ module Mongoid #:nodoc:
|
|
21
21
|
|
22
22
|
# Return the foreign key based off the association name.
|
23
23
|
def foreign_key
|
24
|
-
name.to_s.foreign_key
|
24
|
+
@attributes[:foreign_key] || klass.name.to_s.foreign_key
|
25
25
|
end
|
26
26
|
|
27
27
|
# Returns the name of the inverse_of association
|
@@ -42,11 +42,6 @@ module Mongoid #:nodoc:
|
|
42
42
|
@attributes[:name].to_s
|
43
43
|
end
|
44
44
|
|
45
|
-
# Returns the parent foreign key association name.
|
46
|
-
def parent_key
|
47
|
-
@attributes[:parent_key]
|
48
|
-
end
|
49
|
-
|
50
45
|
# Returns whether or not this association is polymorphic.
|
51
46
|
def polymorphic
|
52
47
|
@attributes[:polymorphic] == true
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Caching #:nodoc:
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
extend ClassMethods
|
7
|
+
class_inheritable_accessor :cached
|
8
|
+
self.cached = false
|
9
|
+
|
10
|
+
delegate :cached?, :to => "self.class"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods #:nodoc
|
15
|
+
# Sets caching on for this class. This class level configuration will
|
16
|
+
# default all queries to cache the results of the first iteration over
|
17
|
+
# the cursor into an internal array. This should only be used for queries
|
18
|
+
# that return a small number of results or have small documents, as after
|
19
|
+
# the first iteration the entire results will be stored in memory.
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
#
|
23
|
+
# class Person
|
24
|
+
# include Mongoid::Document
|
25
|
+
# cache
|
26
|
+
# end
|
27
|
+
def cache
|
28
|
+
self.cached = true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Determines if the class is cached or not.
|
32
|
+
#
|
33
|
+
# Returns:
|
34
|
+
#
|
35
|
+
# True if cached, false if not.
|
36
|
+
def cached?
|
37
|
+
self.cached == true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/mongoid/collection.rb
CHANGED
data/lib/mongoid/components.rb
CHANGED
data/lib/mongoid/config.rb
CHANGED
@@ -8,6 +8,7 @@ module Mongoid #:nodoc
|
|
8
8
|
:reconnect_time,
|
9
9
|
:parameterize_keys,
|
10
10
|
:persist_in_safe_mode,
|
11
|
+
:persist_types,
|
11
12
|
:raise_not_found_error,
|
12
13
|
:use_object_ids
|
13
14
|
|
@@ -16,6 +17,7 @@ module Mongoid #:nodoc
|
|
16
17
|
@allow_dynamic_fields = true
|
17
18
|
@parameterize_keys = true
|
18
19
|
@persist_in_safe_mode = true
|
20
|
+
@persist_types = true
|
19
21
|
@raise_not_found_error = true
|
20
22
|
@reconnect_time = 3
|
21
23
|
@use_object_ids = false
|
@@ -7,7 +7,6 @@ module Mongoid #:nodoc:
|
|
7
7
|
|
8
8
|
delegate :klass, :options, :selector, :to => :criteria
|
9
9
|
|
10
|
-
AGGREGATE_REDUCE = "function(obj, prev) { prev.count++; }"
|
11
10
|
# Aggregate the context. This will take the internally built selector and options
|
12
11
|
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
13
12
|
# collection itself will be retrieved from the class provided, and once the
|
@@ -21,7 +20,7 @@ module Mongoid #:nodoc:
|
|
21
20
|
#
|
22
21
|
# A +Hash+ with field values as keys, counts as values
|
23
22
|
def aggregate
|
24
|
-
klass.collection.group(options[:fields], selector, { :count => 0 },
|
23
|
+
klass.collection.group(options[:fields], selector, { :count => 0 }, Javascript.aggregate, true)
|
25
24
|
end
|
26
25
|
|
27
26
|
# Get the count of matching documents in the database for the context.
|
@@ -59,7 +58,6 @@ module Mongoid #:nodoc:
|
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
62
|
-
GROUP_REDUCE = "function(obj, prev) { prev.group.push(obj); }"
|
63
61
|
# Groups the context. This will take the internally built selector and options
|
64
62
|
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
65
63
|
# collection itself will be retrieved from the class provided, and once the
|
@@ -77,7 +75,7 @@ module Mongoid #:nodoc:
|
|
77
75
|
options[:fields],
|
78
76
|
selector,
|
79
77
|
{ :group => [] },
|
80
|
-
|
78
|
+
Javascript.group,
|
81
79
|
true
|
82
80
|
).collect do |docs|
|
83
81
|
docs["group"] = docs["group"].collect do |attrs|
|
@@ -95,9 +93,11 @@ module Mongoid #:nodoc:
|
|
95
93
|
# <tt>Mongoid::Contexts::Mongo.new(criteria)</tt>
|
96
94
|
def initialize(criteria)
|
97
95
|
@criteria = criteria
|
98
|
-
if
|
96
|
+
if klass.hereditary && Mongoid.persist_types
|
99
97
|
criteria.in(:_type => criteria.klass._types)
|
100
98
|
end
|
99
|
+
criteria.enslave if klass.enslaved?
|
100
|
+
criteria.cache if klass.cached?
|
101
101
|
end
|
102
102
|
|
103
103
|
# Return the last result for the +Context+. Essentially does a find_one on
|
@@ -120,8 +120,6 @@ module Mongoid #:nodoc:
|
|
120
120
|
attributes ? Mongoid::Factory.build(klass, attributes) : nil
|
121
121
|
end
|
122
122
|
|
123
|
-
MAX_REDUCE = "function(obj, prev) { if (prev.max == 'start') { prev.max = obj.[field]; } " +
|
124
|
-
"if (prev.max < obj.[field]) { prev.max = obj.[field]; } }"
|
125
123
|
# Return the max value for a field.
|
126
124
|
#
|
127
125
|
# This will take the internally built selector and options
|
@@ -137,11 +135,9 @@ module Mongoid #:nodoc:
|
|
137
135
|
#
|
138
136
|
# A numeric max value.
|
139
137
|
def max(field)
|
140
|
-
grouped(:max, field.to_s,
|
138
|
+
grouped(:max, field.to_s, Javascript.max)
|
141
139
|
end
|
142
140
|
|
143
|
-
MIN_REDUCE = "function(obj, prev) { if (prev.min == 'start') { prev.min = obj.[field]; } " +
|
144
|
-
"if (prev.min > obj.[field]) { prev.min = obj.[field]; } }"
|
145
141
|
# Return the min value for a field.
|
146
142
|
#
|
147
143
|
# This will take the internally built selector and options
|
@@ -157,7 +153,7 @@ module Mongoid #:nodoc:
|
|
157
153
|
#
|
158
154
|
# A numeric minimum value.
|
159
155
|
def min(field)
|
160
|
-
grouped(:min, field.to_s,
|
156
|
+
grouped(:min, field.to_s, Javascript.min)
|
161
157
|
end
|
162
158
|
|
163
159
|
# Return the first result for the +Context+.
|
@@ -176,7 +172,6 @@ module Mongoid #:nodoc:
|
|
176
172
|
|
177
173
|
alias :first :one
|
178
174
|
|
179
|
-
SUM_REDUCE = "function(obj, prev) { if (prev.sum == 'start') { prev.sum = 0; } prev.sum += obj.[field]; }"
|
180
175
|
# Sum the context.
|
181
176
|
#
|
182
177
|
# This will take the internally built selector and options
|
@@ -192,7 +187,7 @@ module Mongoid #:nodoc:
|
|
192
187
|
#
|
193
188
|
# A numeric value that is the sum.
|
194
189
|
def sum(field)
|
195
|
-
grouped(:sum, field.to_s,
|
190
|
+
grouped(:sum, field.to_s, Javascript.sum)
|
196
191
|
end
|
197
192
|
|
198
193
|
# Common functionality for grouping operations. Currently used by min, max
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -165,7 +165,7 @@ module Mongoid #:nodoc:
|
|
165
165
|
# Returns: <tt>Criteria</tt>
|
166
166
|
def method_missing(name, *args)
|
167
167
|
if @klass.respond_to?(name)
|
168
|
-
new_scope = @klass.send(name)
|
168
|
+
new_scope = @klass.send(name, *args)
|
169
169
|
new_scope.merge(self)
|
170
170
|
return new_scope
|
171
171
|
else
|
@@ -203,7 +203,12 @@ module Mongoid #:nodoc:
|
|
203
203
|
unless params.is_a?(Hash)
|
204
204
|
return new(klass).id_criteria(params)
|
205
205
|
end
|
206
|
-
|
206
|
+
conditions = params.delete(:conditions) || {}
|
207
|
+
if conditions.include?(:id)
|
208
|
+
conditions[:_id] = conditions[:id]
|
209
|
+
conditions.delete(:id)
|
210
|
+
end
|
211
|
+
return new(klass).where(conditions).extras(params)
|
207
212
|
end
|
208
213
|
|
209
214
|
protected
|
@@ -61,6 +61,7 @@ module Mongoid #:nodoc:
|
|
61
61
|
def in(attributes = {})
|
62
62
|
update_selector(attributes, "$in")
|
63
63
|
end
|
64
|
+
alias any_in in
|
64
65
|
|
65
66
|
# Adds a criterion to the +Criteria+ that specifies values that must
|
66
67
|
# be matched in order to return results. This is similar to a SQL "WHERE"
|
@@ -20,8 +20,7 @@ module Mongoid #:nodoc:
|
|
20
20
|
#
|
21
21
|
# <tt>criteria.cached?</tt>
|
22
22
|
def cached?
|
23
|
-
@
|
24
|
-
@cached == true
|
23
|
+
@options[:cache] == true
|
25
24
|
end
|
26
25
|
|
27
26
|
# Flags the criteria to execute against a read-only slave in the pool
|
@@ -34,6 +33,15 @@ module Mongoid #:nodoc:
|
|
34
33
|
@options.merge!(:enslave => true); self
|
35
34
|
end
|
36
35
|
|
36
|
+
# Will return true if the criteria is enslaved.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# <tt>criteria.enslaved?</tt>
|
41
|
+
def enslaved?
|
42
|
+
@options[:enslave] == true
|
43
|
+
end
|
44
|
+
|
37
45
|
# Adds a criterion to the +Criteria+ that specifies additional options
|
38
46
|
# to be passed to the Ruby driver, in the exact format for the driver.
|
39
47
|
#
|
data/lib/mongoid/finders.rb
CHANGED
@@ -112,27 +112,9 @@ module Mongoid #:nodoc:
|
|
112
112
|
#
|
113
113
|
# Returns: <tt>Float</tt> max value.
|
114
114
|
def max(field)
|
115
|
-
|
115
|
+
criteria.max(field)
|
116
116
|
end
|
117
117
|
|
118
|
-
# Will execute a +Criteria+ based on the +DynamicFinder+ that gets
|
119
|
-
# generated.
|
120
|
-
#
|
121
|
-
# Options:
|
122
|
-
#
|
123
|
-
# name: The finder method name
|
124
|
-
# args: The arguments to pass to the method.
|
125
|
-
#
|
126
|
-
# Example:
|
127
|
-
#
|
128
|
-
# <tt>Person.find_all_by_title_and_age("Sir", 30)</tt>
|
129
|
-
# def method_missing(name, *args)
|
130
|
-
# dyna = DynamicFinder.new(name, *args)
|
131
|
-
# finder, conditions = dyna.finder, dyna.conditions
|
132
|
-
# results = find(finder, :conditions => conditions)
|
133
|
-
# results ? results : dyna.create(self)
|
134
|
-
# end
|
135
|
-
|
136
118
|
# Convenience method for returning the min value of a field.
|
137
119
|
#
|
138
120
|
# Options:
|
@@ -145,7 +127,7 @@ module Mongoid #:nodoc:
|
|
145
127
|
#
|
146
128
|
# Returns: <tt>Float</tt> min value.
|
147
129
|
def min(field)
|
148
|
-
|
130
|
+
criteria.min(field)
|
149
131
|
end
|
150
132
|
|
151
133
|
# Find all documents in paginated fashion given the supplied arguments.
|
@@ -179,7 +161,7 @@ module Mongoid #:nodoc:
|
|
179
161
|
#
|
180
162
|
# Returns: <tt>Criteria</tt>
|
181
163
|
def only(*args)
|
182
|
-
|
164
|
+
criteria.only(*args)
|
183
165
|
end
|
184
166
|
|
185
167
|
# Convenience method for returning the sum of a specified field for all
|
@@ -195,7 +177,7 @@ module Mongoid #:nodoc:
|
|
195
177
|
#
|
196
178
|
# Returns: <tt>Float</tt> of the sum.
|
197
179
|
def sum(field)
|
198
|
-
|
180
|
+
criteria.sum(field)
|
199
181
|
end
|
200
182
|
|
201
183
|
# Entry point for creating a new criteria from a Document. This will
|
@@ -212,7 +194,7 @@ module Mongoid #:nodoc:
|
|
212
194
|
#
|
213
195
|
# Returns: <tt>Criteria</tt>
|
214
196
|
def where(selector = nil)
|
215
|
-
|
197
|
+
criteria.where(selector)
|
216
198
|
end
|
217
199
|
|
218
200
|
protected
|