mongoid 0.10.3 → 0.10.4

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 ADDED
@@ -0,0 +1,18 @@
1
+ === 0.10.4
2
+
3
+ - Documents no longer inherit from Mongoid::Document.
4
+ Please include Mongoid::Document in all your models now.
5
+
6
+ - Config module added, you can now set one option:
7
+ Mongoid.raise_not_found_error = (true|false)
8
+
9
+ - When set to false, a Mongoid::Errors::DocumentNotFound
10
+ will NOT get thrown when performing a Document.find(id)
11
+ that does not return a document from the database.
12
+ This defaults to true.
13
+
14
+ - Mongoid::Document.collection_name macro added. You can
15
+ now set the name of the database collection to persist to.
16
+
17
+ - Mongoid::Criteria#select becomes Mongoid::Criteria#only
18
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.3
1
+ 0.10.4
@@ -41,6 +41,7 @@ require "mongoid/associations"
41
41
  require "mongoid/associations/options"
42
42
  require "mongoid/attributes"
43
43
  require "mongoid/commands"
44
+ require "mongoid/config"
44
45
  require "mongoid/complex_criterion"
45
46
  require "mongoid/criteria"
46
47
  require "mongoid/dynamic_finder"
@@ -52,17 +53,13 @@ require "mongoid/timestamps"
52
53
  require "mongoid/versioning"
53
54
  require "mongoid/document"
54
55
 
55
- module Mongoid
56
+ module Mongoid #:nodoc
56
57
 
57
- # Sets the Mongo::DB to be used.
58
- def self.database=(db)
59
- raise Errors::InvalidDatabase.new("Database should be a Mongo::DB, not #{db.class.name}") unless db.kind_of?(Mongo::DB)
60
- @database = db
61
- end
62
-
63
- # Returns the Mongo::DB to use or raise an error if none was set.
64
- def self.database
65
- @database || (raise Errors::InvalidDatabase.new("No database has been set, please use Mongoid.database="))
58
+ class << self
59
+ #direct all calls to the configuration
60
+ def method_missing(name, *args)
61
+ Config.instance.send(name, *args)
62
+ end
66
63
  end
67
64
 
68
65
  end
@@ -18,10 +18,12 @@ module Mongoid #:nodoc:
18
18
 
19
19
  # Clears the association, and notifies the parents of the removal.
20
20
  def clear
21
- object = @documents.first
22
- object.changed(true)
23
- object.notify_observers(object, true)
24
- @documents.clear
21
+ unless @documents.empty?
22
+ object = @documents.first
23
+ object.changed(true)
24
+ object.notify_observers(object, true)
25
+ @documents.clear
26
+ end
25
27
  end
26
28
 
27
29
  # Appends the object to the +Array+, setting its parent in
@@ -0,0 +1,25 @@
1
+ module Mongoid #:nodoc
2
+ class Config #:nodoc
3
+ include Singleton
4
+
5
+ attr_accessor :raise_not_found_error
6
+
7
+ def initialize
8
+ @raise_not_found_error = true
9
+ end
10
+
11
+ # Sets the Mongo::DB to be used.
12
+ def database=(db)
13
+ raise Errors::InvalidDatabase.new(
14
+ "Database should be a Mongo::DB, not #{db.class.name}"
15
+ ) unless db.kind_of?(Mongo::DB)
16
+ @database = db
17
+ end
18
+
19
+ # Returns the Mongo::DB to use or raise an error if none was set.
20
+ def database
21
+ @database || (raise Errors::InvalidDatabase.new("No database has been set, please use Mongoid.database="))
22
+ end
23
+
24
+ end
25
+ end
@@ -11,7 +11,7 @@ module Mongoid #:nodoc:
11
11
  #
12
12
  # <tt>criteria = Criteria.new</tt>
13
13
  #
14
- # <tt>criteria.select(:field => "value").only(:field).skip(20).limit(20)</tt>
14
+ # <tt>criteria.only(:field).where(:field => "value").skip(20).limit(20)</tt>
15
15
  #
16
16
  # <tt>criteria.execute</tt>
17
17
  class Criteria
@@ -341,6 +341,25 @@ module Mongoid #:nodoc:
341
341
  attributes ? @klass.instantiate(attributes) : nil
342
342
  end
343
343
 
344
+ alias :first :one
345
+
346
+ # Adds a criterion to the +Criteria+ that specifies the fields that will
347
+ # get returned from the Document. Used mainly for list views that do not
348
+ # require all fields to be present. This is similar to SQL "SELECT" values.
349
+ #
350
+ # Options:
351
+ #
352
+ # args: A list of field names to retrict the returned fields to.
353
+ #
354
+ # Example:
355
+ #
356
+ # <tt>criteria.only(:field1, :field2, :field3)</tt>
357
+ #
358
+ # Returns: <tt>self</tt>
359
+ def only(*args)
360
+ @options[:fields] = args.flatten if args.any?; self
361
+ end
362
+
344
363
  # Adds a criterion to the +Criteria+ that specifies the sort order of
345
364
  # the returned documents in the database. Similar to a SQL "ORDER BY".
346
365
  #
@@ -381,23 +400,6 @@ module Mongoid #:nodoc:
381
400
  (@options[:limit] || 20).to_i
382
401
  end
383
402
 
384
- # Adds a criterion to the +Criteria+ that specifies the fields that will
385
- # get returned from the Document. Used mainly for list views that do not
386
- # require all fields to be present. This is similar to SQL "SELECT" values.
387
- #
388
- # Options:
389
- #
390
- # args: A list of field names to retrict the returned fields to.
391
- #
392
- # Example:
393
- #
394
- # <tt>criteria.select(:field1, :field2, :field3)</tt>
395
- #
396
- # Returns: <tt>self</tt>
397
- def select(*args)
398
- @options[:fields] = args.flatten if args.any?; self
399
- end
400
-
401
403
  # Adds a criterion to the +Criteria+ that specifies how many results to skip
402
404
  # when returning Documents. This is mostly used in conjunction with
403
405
  # <tt>limit()</tt> to handle paginated results, and is similar to the
@@ -440,7 +442,10 @@ module Mongoid #:nodoc:
440
442
  params = args[1] || {}
441
443
  if params.is_a?(String)
442
444
  document = new(klass).id(params).one
443
- return document ? document : (raise Errors::DocumentNotFound.new(klass, params))
445
+ if Mongoid.raise_not_found_error
446
+ raise Errors::DocumentNotFound.new(klass, params) unless document
447
+ end
448
+ return document
444
449
  end
445
450
  return new(klass).where(params.delete(:conditions) || {}).extras(params)
446
451
  end
@@ -1,20 +1,26 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc:
3
- class Document
4
- include ActiveSupport::Callbacks
5
- include Associations, Attributes, Commands, Observable, Validatable
6
- extend Finders
3
+ module Document
4
+ def self.included(base)
5
+ base.class_eval do
6
+ include ActiveSupport::Callbacks
7
+ include Associations, Attributes, Commands, Observable, Validatable
8
+ include InstanceMethods
7
9
 
8
- attr_accessor :association_name, :parent
9
- attr_reader :attributes, :new_record
10
+ extend ClassMethods
11
+ extend Finders
10
12
 
11
- delegate :collection, :defaults, :embedded?, :fields, :primary_key, :to => :klass
13
+ attr_accessor :association_name, :parent
14
+ attr_reader :attributes, :new_record
12
15
 
13
- define_callbacks :before_create, :before_destroy, :before_save, :before_update, :before_validation
14
- define_callbacks :after_create, :after_destroy, :after_save, :after_update, :after_validation
16
+ delegate :collection, :defaults, :embedded?, :fields, :primary_key, :to => :klass
15
17
 
16
- class << self
18
+ define_callbacks :before_create, :before_destroy, :before_save, :before_update, :before_validation
19
+ define_callbacks :after_create, :after_destroy, :after_save, :after_update, :after_validation
20
+ end
21
+ end
17
22
 
23
+ module ClassMethods
18
24
  # Returns the collection associated with this +Document+. If the
19
25
  # document is embedded, there will be no collection associated
20
26
  # with it.
@@ -26,6 +32,11 @@ module Mongoid #:nodoc:
26
32
  @collection ||= Mongoid.database.collection(@collection_name)
27
33
  end
28
34
 
35
+ # Set the collection name for the +Document+.
36
+ def collection_name(name)
37
+ @collection_name = name
38
+ end
39
+
29
40
  # Returns a hash of all the default values
30
41
  def defaults
31
42
  @defaults
@@ -122,186 +133,191 @@ module Mongoid #:nodoc:
122
133
 
123
134
  end
124
135
 
125
- # Performs equality checking on the attributes. For now we chack against
126
- # all attributes excluding timestamps on the object.
127
- def ==(other)
128
- return false unless other.is_a?(Document)
129
- @attributes.except(:modified_at).except(:created_at) ==
130
- other.attributes.except(:modified_at).except(:created_at)
131
- end
136
+ module InstanceMethods
137
+ # Performs equality checking on the attributes. For now we chack against
138
+ # all attributes excluding timestamps on the object.
139
+ def ==(other)
140
+ return false unless other.is_a?(Document)
141
+ @attributes.except(:modified_at).except(:created_at) ==
142
+ other.attributes.except(:modified_at).except(:created_at)
143
+ end
132
144
 
133
- # Introduces a child object into the +Document+ object graph. This will
134
- # set up the relationships between the parent and child and update the
135
- # attributes of the parent +Document+.
136
- #
137
- # Options:
138
- #
139
- # parent: The +Document+ to assimilate with.
140
- # options: The association +Options+ for the child.
141
- #
142
- # Example:
143
- #
144
- # <tt>name.assimilate(person, options)</tt>
145
- #
146
- # Returns: The child +Document+.
147
- def assimilate(parent, options)
148
- parentize(parent, options.name); notify; self
149
- end
145
+ # Introduces a child object into the +Document+ object graph. This will
146
+ # set up the relationships between the parent and child and update the
147
+ # attributes of the parent +Document+.
148
+ #
149
+ # Options:
150
+ #
151
+ # parent: The +Document+ to assimilate with.
152
+ # options: The association +Options+ for the child.
153
+ #
154
+ # Example:
155
+ #
156
+ # <tt>name.assimilate(person, options)</tt>
157
+ #
158
+ # Returns: The child +Document+.
159
+ def assimilate(parent, options)
160
+ parentize(parent, options.name); notify; self
161
+ end
150
162
 
151
- # Clone the current +Document+. This will return all attributes with the
152
- # exception of the document's id and versions.
153
- def clone
154
- self.class.instantiate(@attributes.except(:_id).except(:versions).dup, true)
155
- end
163
+ # Clone the current +Document+. This will return all attributes with the
164
+ # exception of the document's id and versions.
165
+ def clone
166
+ self.class.instantiate(@attributes.except(:_id).except(:versions).dup, true)
167
+ end
156
168
 
157
- # Get the id associated with this object. This will pull the _id value out
158
- # of the attributes +Hash+.
159
- def id
160
- @attributes[:_id]
161
- end
169
+ # Get the id associated with this object. This will pull the _id value out
170
+ # of the attributes +Hash+.
171
+ def id
172
+ @attributes[:_id]
173
+ end
162
174
 
163
- # Set the id
164
- def id=(new_id)
165
- @attributes[:_id] = new_id
166
- end
175
+ # Set the id
176
+ def id=(new_id)
177
+ @attributes[:_id] = new_id
178
+ end
167
179
 
168
- alias :_id :id
169
- alias :_id= :id=
170
-
171
- # Instantiate a new +Document+, setting the Document's attributes if
172
- # given. If no attributes are provided, they will be initialized with
173
- # an empty +Hash+.
174
- #
175
- # If a primary key is defined, the document's id will be set to that key,
176
- # otherwise it will be set to a fresh +Mongo::ObjectID+ string.
177
- #
178
- # Options:
179
- #
180
- # attrs: The attributes +Hash+ to set up the document with.
181
- #
182
- # Example:
183
- #
184
- # <tt>Person.new(:title => "Mr", :age => 30)</tt>
185
- def initialize(attrs = {})
186
- @attributes = {}.with_indifferent_access
187
- process(defaults.merge(attrs))
188
- @new_record = true if id.nil?
189
- document = yield self if block_given?
190
- generate_key; document
191
- end
180
+ alias :_id :id
181
+ alias :_id= :id=
192
182
 
193
- # Returns the class name plus its attributes.
194
- def inspect
195
- attrs = fields.map { |name, field| "#{name}: #{@attributes[name] || 'nil'}" } * ", "
196
- "#<#{self.class.name} _id: #{id}, #{attrs}>"
197
- end
183
+ # Instantiate a new +Document+, setting the Document's attributes if
184
+ # given. If no attributes are provided, they will be initialized with
185
+ # an empty +Hash+.
186
+ #
187
+ # If a primary key is defined, the document's id will be set to that key,
188
+ # otherwise it will be set to a fresh +Mongo::ObjectID+ string.
189
+ #
190
+ # Options:
191
+ #
192
+ # attrs: The attributes +Hash+ to set up the document with.
193
+ #
194
+ # Example:
195
+ #
196
+ # <tt>Person.new(:title => "Mr", :age => 30)</tt>
197
+ def initialize(attrs = {})
198
+ @attributes = {}.with_indifferent_access
199
+ process(defaults.merge(attrs))
200
+ @new_record = true if id.nil?
201
+ document = yield self if block_given?
202
+ generate_key; document
203
+ end
198
204
 
199
- # Returns true is the +Document+ has not been persisted to the database,
200
- # false if it has. This is determined by the instance variable @new_record
201
- # and NOT if the object has an id.
202
- def new_record?
203
- @new_record == true
204
- end
205
+ # Returns the class name plus its attributes.
206
+ def inspect
207
+ attrs = fields.map { |name, field| "#{name}: #{@attributes[name] || 'nil'}" } * ", "
208
+ "#<#{self.class.name} _id: #{id}, #{attrs}>"
209
+ end
205
210
 
206
- # Sets the new_record boolean - used after document is saved.
207
- def new_record=(saved)
208
- @new_record = saved
209
- end
211
+ # Returns true is the +Document+ has not been persisted to the database,
212
+ # false if it has. This is determined by the instance variable @new_record
213
+ # and NOT if the object has an id.
214
+ def new_record?
215
+ @new_record == true
216
+ end
210
217
 
211
- # Set the changed state of the +Document+ then notify observers that it has changed.
212
- #
213
- # Example:
214
- #
215
- # <tt>person.notify</tt>
216
- def notify
217
- changed(true)
218
- notify_observers(self)
219
- end
218
+ # Sets the new_record boolean - used after document is saved.
219
+ def new_record=(saved)
220
+ @new_record = saved
221
+ end
220
222
 
221
- # Sets up a child/parent association. This is used for newly created
222
- # objects so they can be properly added to the graph and have the parent
223
- # observers set up properly.
224
- #
225
- # Options:
226
- #
227
- # abject: The parent object that needs to be set for the child.
228
- # association_name: The name of the association for the child.
229
- #
230
- # Example:
231
- #
232
- # <tt>address.parentize(person, :addresses)</tt>
233
- def parentize(object, association_name)
234
- self.parent = object
235
- self.association_name = association_name
236
- add_observer(object)
237
- end
223
+ # Set the changed state of the +Document+ then notify observers that it has changed.
224
+ #
225
+ # Example:
226
+ #
227
+ # <tt>person.notify</tt>
228
+ def notify
229
+ changed(true)
230
+ notify_observers(self)
231
+ end
238
232
 
239
- # Reloads the +Document+ attributes from the database.
240
- def reload
241
- @attributes = collection.find_one(:_id => id).with_indifferent_access
242
- end
233
+ # Sets up a child/parent association. This is used for newly created
234
+ # objects so they can be properly added to the graph and have the parent
235
+ # observers set up properly.
236
+ #
237
+ # Options:
238
+ #
239
+ # abject: The parent object that needs to be set for the child.
240
+ # association_name: The name of the association for the child.
241
+ #
242
+ # Example:
243
+ #
244
+ # <tt>address.parentize(person, :addresses)</tt>
245
+ def parentize(object, association_name)
246
+ self.parent = object
247
+ self.association_name = association_name
248
+ add_observer(object)
249
+ end
243
250
 
244
- # Return the root +Document+ in the object graph. If the current +Document+
245
- # is the root object in the graph it will return self.
246
- def root
247
- object = self
248
- while (object.parent) do object = object.parent; end
249
- object || self
250
- end
251
+ # Reloads the +Document+ attributes from the database.
252
+ def reload
253
+ @attributes = collection.find_one(:_id => id).with_indifferent_access
254
+ end
251
255
 
252
- # Return an array with this +Document+ only in it.
253
- def to_a
254
- [ self ]
255
- end
256
+ # Return the root +Document+ in the object graph. If the current +Document+
257
+ # is the root object in the graph it will return self.
258
+ def root
259
+ object = self
260
+ while (object.parent) do object = object.parent; end
261
+ object || self
262
+ end
256
263
 
257
- # Returns the id of the Document, used in Rails compatibility.
258
- def to_param
259
- id
260
- end
264
+ # Return an array with this +Document+ only in it.
265
+ def to_a
266
+ [ self ]
267
+ end
261
268
 
262
- # Observe a notify call from a child +Document+. This will either update
263
- # existing attributes on the +Document+ or clear them out for the child if
264
- # the clear boolean is provided.
265
- #
266
- # Options:
267
- #
268
- # child: The child +Document+ that sent the notification.
269
- # clear: Will clear out the child's attributes if set to true.
270
- #
271
- # Example:
272
- #
273
- # <tt>person.notify_observers(self)</tt> will cause this method to execute.
274
- #
275
- # This will also cause the observing +Document+ to notify it's parent if
276
- # there is any.
277
- def update(child, clear = false)
278
- name = child.association_name
279
- clear ? @attributes.delete(name) : @attributes.insert(name, child.attributes)
280
- notify
281
- end
269
+ # Returns the id of the Document, used in Rails compatibility.
270
+ def to_param
271
+ id
272
+ end
282
273
 
283
- # Needs to run the appropriate callbacks the delegate up to the validatable
284
- # gem.
285
- def valid?
286
- run_callbacks(:before_validation)
287
- result = super
288
- run_callbacks(:after_validation)
289
- result
290
- end
274
+ # Observe a notify call from a child +Document+. This will either update
275
+ # existing attributes on the +Document+ or clear them out for the child if
276
+ # the clear boolean is provided.
277
+ #
278
+ # Options:
279
+ #
280
+ # child: The child +Document+ that sent the notification.
281
+ # clear: Will clear out the child's attributes if set to true.
282
+ #
283
+ # Example:
284
+ #
285
+ # <tt>person.notify_observers(self)</tt> will cause this method to execute.
286
+ #
287
+ # This will also cause the observing +Document+ to notify it's parent if
288
+ # there is any.
289
+ def update(child, clear = false)
290
+ name = child.association_name
291
+ clear ? @attributes.delete(name) : @attributes.insert(name, child.attributes)
292
+ notify
293
+ end
291
294
 
292
- protected
293
- def generate_key
294
- if primary_key
295
- values = primary_key.collect { |key| @attributes[key] }
296
- @attributes[:_id] = values.join(" ").parameterize.to_s
297
- else
298
- @attributes[:_id] = Mongo::ObjectID.new.to_s unless id
295
+ # Needs to run the appropriate callbacks the delegate up to the validatable
296
+ # gem.
297
+ def valid?
298
+ run_callbacks(:before_validation)
299
+ result = super
300
+ run_callbacks(:after_validation)
301
+ result
302
+ end
303
+
304
+ protected
305
+ def generate_key
306
+ if primary_key
307
+ values = primary_key.collect { |key| @attributes[key] }
308
+ @attributes[:_id] = values.join(" ").parameterize.to_s
309
+ else
310
+ @attributes[:_id] = Mongo::ObjectID.new.to_s unless id
311
+ end
312
+ end
313
+
314
+ # Convenience method to get the document's class
315
+ def klass
316
+ self.class
299
317
  end
300
- end
301
318
 
302
- # Convenience method to get the document's class
303
- def klass
304
- self.class
305
319
  end
320
+
306
321
  end
322
+
307
323
  end
@@ -120,11 +120,28 @@ module Mongoid #:nodoc:
120
120
  #
121
121
  # Example:
122
122
  #
123
- # <tt>Person.select(:field1, :field2, :field3)</tt>
123
+ # <tt>Person.only(:field1, :field2, :field3)</tt>
124
124
  #
125
125
  # Returns: <tt>Criteria</tt>
126
- def select(*args)
127
- Criteria.new(self).select(*args)
126
+ def only(*args)
127
+ Criteria.new(self).only(*args)
128
+ end
129
+
130
+ # Entry point for creating a new criteria from a Document. This will
131
+ # instantiate a new +Criteria+ object with the supplied select criterion
132
+ # already added to it.
133
+ #
134
+ # Options:
135
+ #
136
+ # selector: A where criteria to initialize.
137
+ #
138
+ # Example:
139
+ #
140
+ # <tt>Person.where(:field1 => "Value")</tt>
141
+ #
142
+ # Returns: <tt>Criteria</tt>
143
+ def where(selector = nil)
144
+ Criteria.new(self).where(selector)
128
145
  end
129
146
 
130
147
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoid}
8
- s.version = "0.10.3"
8
+ s.version = "0.10.4"
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{2009-12-26}
12
+ s.date = %q{2009-12-28}
13
13
  s.email = %q{durran@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.textile"
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.files = [
18
18
  ".gitignore",
19
19
  ".watchr",
20
+ "HISTORY",
20
21
  "MIT_LICENSE",
21
22
  "README.textile",
22
23
  "Rakefile",
@@ -40,6 +41,7 @@ Gem::Specification.new do |s|
40
41
  "lib/mongoid/commands/destroy_all.rb",
41
42
  "lib/mongoid/commands/save.rb",
42
43
  "lib/mongoid/complex_criterion.rb",
44
+ "lib/mongoid/config.rb",
43
45
  "lib/mongoid/criteria.rb",
44
46
  "lib/mongoid/document.rb",
45
47
  "lib/mongoid/dynamic_finder.rb",
@@ -92,6 +94,7 @@ Gem::Specification.new do |s|
92
94
  "spec/unit/mongoid/commands/destroy_spec.rb",
93
95
  "spec/unit/mongoid/commands/save_spec.rb",
94
96
  "spec/unit/mongoid/commands_spec.rb",
97
+ "spec/unit/mongoid/config_spec.rb",
95
98
  "spec/unit/mongoid/criteria_spec.rb",
96
99
  "spec/unit/mongoid/document_spec.rb",
97
100
  "spec/unit/mongoid/dynamic_finder_spec.rb",
@@ -147,6 +150,7 @@ Gem::Specification.new do |s|
147
150
  "spec/unit/mongoid/commands/destroy_spec.rb",
148
151
  "spec/unit/mongoid/commands/save_spec.rb",
149
152
  "spec/unit/mongoid/commands_spec.rb",
153
+ "spec/unit/mongoid/config_spec.rb",
150
154
  "spec/unit/mongoid/criteria_spec.rb",
151
155
  "spec/unit/mongoid/document_spec.rb",
152
156
  "spec/unit/mongoid/dynamic_finder_spec.rb",
@@ -70,14 +70,6 @@ describe Mongoid::Criteria do
70
70
 
71
71
  end
72
72
 
73
- context "#mod" do
74
-
75
- it "returns those matching a mod clause" do
76
- Person.criteria.where(:age.lte => 33).should == [@person]
77
- end
78
-
79
- end
80
-
81
73
  context "#ne" do
82
74
 
83
75
  it "returns those matching a ne clause" do
@@ -159,13 +159,13 @@ describe Mongoid::Document do
159
159
  describe "#group" do
160
160
 
161
161
  before do
162
- 30.times do |num|
162
+ 5.times do |num|
163
163
  Person.create(:title => "Sir", :age => num)
164
164
  end
165
165
  end
166
166
 
167
167
  it "returns grouped documents" do
168
- grouped = Person.select(:title).group
168
+ grouped = Person.only(:title).group
169
169
  people = grouped.first["group"]
170
170
  person = people.first
171
171
  person.should be_a_kind_of(Person)
@@ -13,14 +13,15 @@ Mongoid.database = connection.db("mongoid_test")
13
13
 
14
14
  Spec::Runner.configure do |config|
15
15
  config.mock_with :mocha
16
- Mocha::Configuration.prevent(:stubbing_non_existent_method)
17
16
  end
18
17
 
19
- class MixedDrink < Mongoid::Document
18
+ class MixedDrink
19
+ include Mongoid::Document
20
20
  field :name
21
21
  end
22
22
 
23
- class Person < Mongoid::Document
23
+ class Person
24
+ include Mongoid::Document
24
25
  include Mongoid::Timestamps
25
26
 
26
27
  field :title
@@ -73,50 +74,61 @@ class Person < Mongoid::Document
73
74
 
74
75
  end
75
76
 
77
+ class Admin < Person
78
+ field :code
79
+ end
80
+
76
81
  class Employer
77
82
  def id
78
83
  "1"
79
84
  end
80
85
  end
81
86
 
82
- class CountryCode < Mongoid::Document
87
+ class CountryCode
88
+ include Mongoid::Document
83
89
  field :code, :type => Integer
84
90
  key :code
85
91
  belongs_to :phone_number, :inverse_of => :country_codes
86
92
  end
87
93
 
88
- class Phone < Mongoid::Document
94
+ class Phone
95
+ include Mongoid::Document
89
96
  field :number
90
97
  key :number
91
98
  belongs_to :person, :inverse_of => :phone_numbers
92
99
  has_one :country_code
93
100
  end
94
101
 
95
- class Animal < Mongoid::Document
102
+ class Animal
103
+ include Mongoid::Document
96
104
  field :name
97
105
  key :name
98
106
  belongs_to :person, :inverse_of => :pet
99
107
  end
100
108
 
101
- class PetOwner < Mongoid::Document
109
+ class PetOwner
110
+ include Mongoid::Document
102
111
  field :title
103
112
  has_one :pet
104
113
  has_one :address
105
114
  end
106
115
 
107
- class Pet < Mongoid::Document
116
+ class Pet
117
+ include Mongoid::Document
108
118
  field :name
109
119
  field :weight, :type => Float, :default => 0.0
110
120
  has_many :vet_visits
111
121
  belongs_to :pet_owner, :inverse_of => :pet
112
122
  end
113
123
 
114
- class VetVisit < Mongoid::Document
124
+ class VetVisit
125
+ include Mongoid::Document
115
126
  field :date, :type => Date
116
127
  belongs_to :pet, :inverse_of => :vet_visits
117
128
  end
118
129
 
119
- class Address < Mongoid::Document
130
+ class Address
131
+ include Mongoid::Document
120
132
  field :street
121
133
  field :city
122
134
  field :state
@@ -125,14 +137,16 @@ class Address < Mongoid::Document
125
137
  belongs_to :addressable, :inverse_of => :addresses
126
138
  end
127
139
 
128
- class Name < Mongoid::Document
140
+ class Name
141
+ include Mongoid::Document
129
142
  field :first_name
130
143
  field :last_name
131
144
  key :first_name, :last_name
132
145
  belongs_to :person, :inverse_of => :name
133
146
  end
134
147
 
135
- class Comment < Mongoid::Document
148
+ class Comment
149
+ include Mongoid::Document
136
150
  include Mongoid::Versioning
137
151
  include Mongoid::Timestamps
138
152
  field :text
@@ -140,19 +154,26 @@ class Comment < Mongoid::Document
140
154
  validates_presence_of :text
141
155
  end
142
156
 
143
- class Post < Mongoid::Document
157
+ class Post
158
+ include Mongoid::Document
144
159
  include Mongoid::Versioning
145
160
  include Mongoid::Timestamps
146
161
  field :title
147
162
  belongs_to_related :person
148
163
  end
149
164
 
150
- class Game < Mongoid::Document
165
+ class Game
166
+ include Mongoid::Document
151
167
  field :high_score, :default => 500
152
168
  field :score, :type => Integer, :default => 0
153
169
  belongs_to_related :person
154
170
  end
155
171
 
172
+ class Patient
173
+ include Mongoid::Document
174
+ collection_name "population"
175
+ end
176
+
156
177
  if RUBY_VERSION == '1.8.6'
157
178
  class Array
158
179
  alias :count :size
@@ -104,7 +104,10 @@ describe Mongoid::Associations::HasMany do
104
104
  describe "#concat" do
105
105
 
106
106
  before do
107
- @association = Mongoid::Associations::HasMany.new(@document, Mongoid::Associations::Options.new(:name => :addresses))
107
+ @association = Mongoid::Associations::HasMany.new(
108
+ @document,
109
+ Mongoid::Associations::Options.new(:name => :addresses)
110
+ )
108
111
  @address = Address.new
109
112
  end
110
113
 
@@ -116,6 +119,24 @@ describe Mongoid::Associations::HasMany do
116
119
 
117
120
  end
118
121
 
122
+ describe "#clear" do
123
+
124
+ before do
125
+ @association = Mongoid::Associations::HasMany.new(
126
+ @document,
127
+ Mongoid::Associations::Options.new(:name => :addresses)
128
+ )
129
+ @address = Address.new
130
+ @association << @address
131
+ end
132
+
133
+ it "clears out the association" do
134
+ @association.clear
135
+ @association.size.should == 0
136
+ end
137
+
138
+ end
139
+
119
140
  describe "#find" do
120
141
 
121
142
  before do
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Config do
4
+
5
+ after :all do
6
+ config.raise_not_found_error = true
7
+ end
8
+
9
+ let(:config) { Mongoid::Config.instance }
10
+
11
+ describe ".database=" do
12
+
13
+ context "when object provided is not a Mongo::DB" do
14
+
15
+ it "raises an error" do
16
+ lambda { config.database = "Test" }.should raise_error
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ describe ".raise_not_found_error=" do
24
+
25
+ context "when setting to true" do
26
+
27
+ before do
28
+ config.raise_not_found_error = true
29
+ end
30
+
31
+ it "sets the value" do
32
+ config.raise_not_found_error.should == true
33
+ end
34
+
35
+ end
36
+
37
+ context "when setting to false" do
38
+
39
+ before do
40
+ config.raise_not_found_error = false
41
+ end
42
+
43
+ it "sets the value" do
44
+ config.raise_not_found_error.should == false
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -43,7 +43,7 @@ describe Mongoid::Criteria do
43
43
 
44
44
  it "calls group on the collection with the aggregate js" do
45
45
  @collection.expects(:group).with([:field1], {}, {:count => 0}, @reduce)
46
- @criteria.select(:field1).aggregate
46
+ @criteria.only(:field1).aggregate
47
47
  end
48
48
 
49
49
  end
@@ -58,7 +58,7 @@ describe Mongoid::Criteria do
58
58
 
59
59
  it "calls group on the collection with the aggregate js" do
60
60
  @collection.expects(:group).with([:field1], {}, {:count => 0}, @reduce)
61
- @criteria.select(:field1).aggregate(Person)
61
+ @criteria.only(:field1).aggregate(Person)
62
62
  end
63
63
 
64
64
  end
@@ -239,7 +239,37 @@ describe Mongoid::Criteria do
239
239
 
240
240
  end
241
241
 
242
- describe "#each_index" do
242
+ describe "#first" do
243
+
244
+ context "when documents exist" do
245
+
246
+ before do
247
+ @collection = mock
248
+ Person.expects(:collection).returns(@collection)
249
+ @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns({ :title => "Sir" })
250
+ end
251
+
252
+ it "calls find on the collection with the selector and options" do
253
+ criteria = Mongoid::Criteria.new(Person)
254
+ criteria.first.should be_a_kind_of(Person)
255
+ end
256
+
257
+ end
258
+
259
+ context "when no documents exist" do
260
+
261
+ before do
262
+ @collection = mock
263
+ Person.expects(:collection).returns(@collection)
264
+ @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(nil)
265
+ end
266
+
267
+ it "returns nil" do
268
+ criteria = Mongoid::Criteria.new(Person)
269
+ criteria.first.should be_nil
270
+ end
271
+
272
+ end
243
273
 
244
274
  end
245
275
 
@@ -319,7 +349,7 @@ describe Mongoid::Criteria do
319
349
 
320
350
  it "calls group on the collection with the aggregate js" do
321
351
  @collection.expects(:group).with([:field1], {}, {:group => []}, @reduce).returns(@grouping)
322
- @criteria.select(:field1).group
352
+ @criteria.only(:field1).group
323
353
  end
324
354
 
325
355
  end
@@ -334,7 +364,7 @@ describe Mongoid::Criteria do
334
364
 
335
365
  it "calls group on the collection with the aggregate js" do
336
366
  @collection.expects(:group).with([:field1], {}, {:group => []}, @reduce).returns(@grouping)
337
- @criteria.select(:field1).group
367
+ @criteria.only(:field1).group
338
368
  end
339
369
 
340
370
  end
@@ -699,7 +729,7 @@ describe Mongoid::Criteria do
699
729
  before do
700
730
  @collection = mock
701
731
  Person.expects(:collection).returns(@collection)
702
- @criteria = Person.select.where(:_id => "1").skip(60).limit(20)
732
+ @criteria = Person.where(:_id => "1").skip(60).limit(20)
703
733
  @collection.expects(:find).with({:_id => "1"}, :skip => 60, :limit => 20).returns([])
704
734
  @results = @criteria.paginate
705
735
  end
@@ -739,17 +769,17 @@ describe Mongoid::Criteria do
739
769
 
740
770
  end
741
771
 
742
- describe "#select" do
772
+ describe "#only" do
743
773
 
744
774
  context "when args are provided" do
745
775
 
746
776
  it "adds the options for limiting by fields" do
747
- @criteria.select(:title, :text)
777
+ @criteria.only(:title, :text)
748
778
  @criteria.options.should == { :fields => [ :title, :text ] }
749
779
  end
750
780
 
751
781
  it "returns self" do
752
- @criteria.select.should == @criteria
782
+ @criteria.only.should == @criteria
753
783
  end
754
784
 
755
785
  end
@@ -757,7 +787,7 @@ describe Mongoid::Criteria do
757
787
  context "when no args provided" do
758
788
 
759
789
  it "does not add the field option" do
760
- @criteria.select
790
+ @criteria.only
761
791
  @criteria.options[:fields].should be_nil
762
792
  end
763
793
 
@@ -898,12 +928,96 @@ describe Mongoid::Criteria do
898
928
 
899
929
  end
900
930
 
901
- context "with complex hash keys" do
931
+ context "with complex criterion" do
932
+
933
+ context "#all" do
934
+
935
+ it "returns those matching an all clause" do
936
+ @criteria.where(:title.all => ["Sir"])
937
+ @criteria.selector.should == { :title => { "$all" => ["Sir"] } }
938
+ end
939
+
940
+ end
941
+
942
+ context "#exists" do
943
+
944
+ it "returns those matching an exists clause" do
945
+ @criteria.where(:title.exists => true)
946
+ @criteria.selector.should == { :title => { "$exists" => true } }
947
+ end
948
+
949
+ end
950
+
951
+ context "#gt" do
952
+
953
+ it "returns those matching a gt clause" do
954
+ @criteria.where(:age.gt => 30)
955
+ @criteria.selector.should == { :age => { "$gt" => 30 } }
956
+ end
957
+
958
+ end
959
+
960
+ context "#gte" do
961
+
962
+ it "returns those matching a gte clause" do
963
+ @criteria.where(:age.gte => 33)
964
+ @criteria.selector.should == { :age => { "$gte" => 33 } }
965
+ end
966
+
967
+ end
968
+
969
+ context "#in" do
970
+
971
+ it "returns those matching an in clause" do
972
+ @criteria.where(:title.in => ["Sir", "Madam"])
973
+ @criteria.selector.should == { :title => { "$in" => ["Sir", "Madam"] } }
974
+ end
975
+
976
+ end
977
+
978
+ context "#lt" do
979
+
980
+ it "returns those matching a lt clause" do
981
+ @criteria.where(:age.lt => 34)
982
+ @criteria.selector.should == { :age => { "$lt" => 34 } }
983
+ end
984
+
985
+ end
986
+
987
+ context "#lte" do
988
+
989
+ it "returns those matching a lte clause" do
990
+ @criteria.where(:age.lte => 33)
991
+ @criteria.selector.should == { :age => { "$lte" => 33 } }
992
+ end
993
+
994
+ end
995
+
996
+ context "#ne" do
997
+
998
+ it "returns those matching a ne clause" do
999
+ @criteria.where(:age.ne => 50)
1000
+ @criteria.selector.should == { :age => { "$ne" => 50 } }
1001
+ end
1002
+
1003
+ end
1004
+
1005
+ context "#nin" do
1006
+
1007
+ it "returns those matching a nin clause" do
1008
+ @criteria.where(:title.nin => ["Esquire", "Congressman"])
1009
+ @criteria.selector.should == { :title => { "$nin" => ["Esquire", "Congressman"] } }
1010
+ end
1011
+
1012
+ end
1013
+
1014
+ context "#size" do
1015
+
1016
+ it "returns those matching a size clause" do
1017
+ @criteria.where(:aliases.size => 2)
1018
+ @criteria.selector.should == { :aliases => { "$size" => 2 } }
1019
+ end
902
1020
 
903
- it "adds the correct clause to the selector" do
904
- dob = 40.years.ago
905
- @criteria.where(:age.gt => 40, :title => "Title", :dob.lt => dob)
906
- @criteria.selector.should == {:age => {"$gt" => 40}, :title => "Title", :dob => {"$lt" => dob}}
907
1021
  end
908
1022
 
909
1023
  end
@@ -109,6 +109,19 @@ describe Mongoid::Document do
109
109
 
110
110
  end
111
111
 
112
+ describe ".collection_name" do
113
+
114
+ before do
115
+ @coll = stub(:name => "population")
116
+ end
117
+
118
+ it "sets the collection name on the document class" do
119
+ Mongoid.database.expects(:collection).with("population").returns(@coll)
120
+ Patient.collection.should == @coll
121
+ end
122
+
123
+ end
124
+
112
125
  describe ".defaults" do
113
126
 
114
127
  it "returns a hash of all the default values" do
@@ -278,13 +278,22 @@ describe Mongoid::Finders do
278
278
 
279
279
  end
280
280
 
281
- describe ".select" do
281
+ describe ".only" do
282
282
 
283
283
  it "returns a new criteria with select conditions added" do
284
- criteria = Person.select(:title, :age)
284
+ criteria = Person.only(:title, :age)
285
285
  criteria.options.should == { :fields => [ :title, :age ] }
286
286
  end
287
287
 
288
288
  end
289
289
 
290
+ describe ".where" do
291
+
292
+ it "returns a new criteria with select conditions added" do
293
+ criteria = Person.where(:title => "Sir")
294
+ criteria.selector.should == { :title => "Sir" }
295
+ end
296
+
297
+ end
298
+
290
299
  end
@@ -2,14 +2,16 @@ require "spec_helper"
2
2
 
3
3
  describe Mongoid do
4
4
 
5
- describe ".database=" do
5
+ describe ".method_missing" do
6
6
 
7
- context "when object provided is not a Mongo::DB" do
8
-
9
- it "raises an error" do
10
- lambda { Mongoid.database = "Test" }.should raise_error
11
- end
7
+ before do
8
+ @config = mock
9
+ Mongoid::Config.expects(:instance).returns(@config)
10
+ end
12
11
 
12
+ it "delegates all calls to the config singleton" do
13
+ @config.expects(:raise_not_found_error=).with(false)
14
+ Mongoid.raise_not_found_error = false
13
15
  end
14
16
 
15
17
  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.10.3
4
+ version: 0.10.4
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: 2009-12-26 00:00:00 -05:00
12
+ date: 2009-12-28 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -93,6 +93,7 @@ extra_rdoc_files:
93
93
  files:
94
94
  - .gitignore
95
95
  - .watchr
96
+ - HISTORY
96
97
  - MIT_LICENSE
97
98
  - README.textile
98
99
  - Rakefile
@@ -116,6 +117,7 @@ files:
116
117
  - lib/mongoid/commands/destroy_all.rb
117
118
  - lib/mongoid/commands/save.rb
118
119
  - lib/mongoid/complex_criterion.rb
120
+ - lib/mongoid/config.rb
119
121
  - lib/mongoid/criteria.rb
120
122
  - lib/mongoid/document.rb
121
123
  - lib/mongoid/dynamic_finder.rb
@@ -168,6 +170,7 @@ files:
168
170
  - spec/unit/mongoid/commands/destroy_spec.rb
169
171
  - spec/unit/mongoid/commands/save_spec.rb
170
172
  - spec/unit/mongoid/commands_spec.rb
173
+ - spec/unit/mongoid/config_spec.rb
171
174
  - spec/unit/mongoid/criteria_spec.rb
172
175
  - spec/unit/mongoid/document_spec.rb
173
176
  - spec/unit/mongoid/dynamic_finder_spec.rb
@@ -245,6 +248,7 @@ test_files:
245
248
  - spec/unit/mongoid/commands/destroy_spec.rb
246
249
  - spec/unit/mongoid/commands/save_spec.rb
247
250
  - spec/unit/mongoid/commands_spec.rb
251
+ - spec/unit/mongoid/config_spec.rb
248
252
  - spec/unit/mongoid/criteria_spec.rb
249
253
  - spec/unit/mongoid/document_spec.rb
250
254
  - spec/unit/mongoid/dynamic_finder_spec.rb