mongoid 0.10.3 → 0.10.4

Sign up to get free protection for your applications and to get access to all the features.
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