mongoid 2.0.0.beta.10 → 2.0.0.beta.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # Copyright (c) 2009 Durran Jordan
2
+ # Copyright (c) 2009, 2010 Durran Jordan
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -63,12 +63,14 @@ require "mongoid/hierarchy"
63
63
  require "mongoid/identity"
64
64
  require "mongoid/indexes"
65
65
  require "mongoid/javascript"
66
+ require "mongoid/keys"
66
67
  require "mongoid/logger"
67
68
  require "mongoid/matchers"
68
69
  require "mongoid/memoization"
69
70
  require "mongoid/named_scope"
70
71
  require "mongoid/paths"
71
72
  require "mongoid/persistence"
73
+ require "mongoid/safety"
72
74
  require "mongoid/scope"
73
75
  require "mongoid/state"
74
76
  require "mongoid/timestamps"
@@ -99,7 +99,9 @@ module Mongoid # :nodoc:
99
99
  # end
100
100
  def embedded_in(name, options = {}, &block)
101
101
  unless options.has_key?(:inverse_of)
102
- raise Errors::InvalidOptions.new("Options for embedded_in association must include :inverse_of")
102
+ raise Errors::InvalidOptions.new(
103
+ "Options for embedded_in association must include :inverse_of"
104
+ )
103
105
  end
104
106
  self.embedded = true
105
107
  associate(Associations::EmbeddedIn, optionize(name, options, nil, &block))
@@ -176,8 +178,8 @@ module Mongoid # :nodoc:
176
178
  def referenced_in(name, options = {}, &block)
177
179
  opts = optionize(name, options, constraint(name, options, :in), &block)
178
180
  associate(Associations::ReferencedIn, opts)
179
- field(opts.foreign_key, :type => Mongoid.use_object_ids ? BSON::ObjectID : String)
180
- index(opts.foreign_key) unless embedded?
181
+ field(opts.foreign_key, :type => using_object_ids? ? BSON::ObjectID : String)
182
+ index(opts.foreign_key, :background => true) if !embedded? && opts.index
181
183
  set_callback(:save, :before) { |document| document.update_foreign_keys }
182
184
  end
183
185
 
@@ -268,7 +270,11 @@ module Mongoid # :nodoc:
268
270
  define_method("build_#{name}") do |*params|
269
271
  attrs = params[0]
270
272
  attr_options = params[1] || {}
271
- reset(name) { type.new(self, (attrs || {}).stringify_keys, options) } unless type == Associations::EmbedsOne && attr_options[:update_only]
273
+ reset(name) do
274
+ unless type == Associations::EmbedsOne && attr_options[:update_only]
275
+ type.new(self, (attrs || {}).stringify_keys, options)
276
+ end
277
+ end
272
278
  end
273
279
  end
274
280
 
@@ -279,7 +285,9 @@ module Mongoid # :nodoc:
279
285
  define_method("create_#{name}") do |*params|
280
286
  attrs = params[0]
281
287
  attr_options = params[1] || {}
282
- send("build_#{name}", attrs, attr_options).tap(&:save) unless type == Associations::EmbedsOne && attr_options[:update_only]
288
+ unless type == Associations::EmbedsOne && attr_options[:update_only]
289
+ send("build_#{name}", attrs, attr_options).tap(&:save)
290
+ end
283
291
  end
284
292
  end
285
293
 
@@ -292,8 +300,10 @@ module Mongoid # :nodoc:
292
300
 
293
301
  def reference_many(name, options, &block)
294
302
  if (options[:stored_as] == :array)
303
+ foreign_key = "#{name.to_s.singularize}_ids"
295
304
  opts = optionize(name, options, constraint(name, options, :many_as_array), &block)
296
- field "#{name.to_s.singularize}_ids", :type => Array, :default => []
305
+ field(foreign_key, :type => Array, :default => [])
306
+ index(foreign_key, :background => true) if opts.index
297
307
  associate(Associations::ReferencesManyAsArray, opts)
298
308
  else
299
309
  opts = optionize(name, options, constraint(name, options, :many), &block)
@@ -26,6 +26,11 @@ module Mongoid #:nodoc:
26
26
  key.to_s
27
27
  end
28
28
 
29
+ # Returns whether the foreign key column is indexed.
30
+ def index
31
+ self[:index] || false
32
+ end
33
+
29
34
  # Returns the name of the inverse_of association
30
35
  def inverse_of
31
36
  self[:inverse_of]
@@ -19,10 +19,12 @@ module Mongoid #:nodoc
19
19
  include Mongoid::Fields
20
20
  include Mongoid::Hierarchy
21
21
  include Mongoid::Indexes
22
+ include Mongoid::Keys
22
23
  include Mongoid::Matchers
23
24
  include Mongoid::Memoization
24
25
  include Mongoid::Paths
25
26
  include Mongoid::Persistence
27
+ include Mongoid::Safety
26
28
  include Mongoid::State
27
29
  include Mongoid::Validations
28
30
  include Mongoid::Callbacks
@@ -12,7 +12,6 @@ module Mongoid #:nodoc
12
12
  :persist_in_safe_mode,
13
13
  :raise_not_found_error,
14
14
  :autocreate_indexes,
15
- :use_object_ids,
16
15
  :skip_version_check
17
16
 
18
17
  # Initializes the configuration with default settings.
@@ -195,51 +194,14 @@ module Mongoid #:nodoc
195
194
  def reset
196
195
  @allow_dynamic_fields = true
197
196
  @parameterize_keys = true
198
- @persist_in_safe_mode = true
197
+ @persist_in_safe_mode = false
199
198
  @raise_not_found_error = true
200
199
  @reconnect_time = 3
201
200
  @autocreate_indexes = false
202
- @use_object_ids = false
203
201
  @skip_version_check = false
204
202
  @time_zone = nil
205
203
  end
206
204
 
207
- ##
208
- # If Mongoid.use_object_ids = true
209
- # Convert args to BSON::ObjectID
210
- # If this args is an array, convert all args inside
211
- # Else
212
- # return args
213
- #
214
- # Options:
215
- #
216
- # args : A +String+ or an +Array+ convert to +BSON::ObjectID+
217
- # cast : A +Boolean+ define if we can or not cast to BSON::ObjectID. If false, we use the default type of args
218
- #
219
- # Example:
220
- #
221
- # <tt>Mongoid.convert_to_object_id("4ab2bc4b8ad548971900005c", true)</tt>
222
- # <tt>Mongoid.convert_to_object_id(["4ab2bc4b8ad548971900005c", "4ab2bc4b8ad548971900005d"])</tt>
223
- #
224
- # Returns:
225
- #
226
- # If Mongoid.use_object_ids = true
227
- # An +Array+ of +BSON::ObjectID+ of each element if params is an +Array+
228
- # A +BSON::ObjectID+ from params if params is +String+
229
- # Else
230
- # <tt>args</tt>
231
- #
232
- def convert_to_object_id(args, cast=true)
233
- return args if !use_object_ids || args.is_a?(BSON::ObjectID) || !cast
234
- if args.is_a?(String)
235
- BSON::ObjectID(args)
236
- else
237
- args.map{ |a|
238
- a.is_a?(BSON::ObjectID) ? a : BSON::ObjectID(a)
239
- }
240
- end
241
- end
242
-
243
205
  protected
244
206
 
245
207
  # Check if the database is valid and the correct version.
@@ -38,6 +38,38 @@ module Mongoid #:nodoc:
38
38
  @options[:cache] == true
39
39
  end
40
40
 
41
+ # If the document is using BSON::ObjectIDs the convert the argument to
42
+ # either an object id or an array of them if the supplied argument is an
43
+ # Array. Otherwise just return.
44
+ #
45
+ # Options:
46
+ # args: A +String+ or an +Array+ convert to +BSON::ObjectID+
47
+ # cast: A +Boolean+ define if we can or not cast to BSON::ObjectID.
48
+ # If false, we use the default type of args
49
+ #
50
+ # Example:
51
+ #
52
+ # <tt>Mongoid.cast_ids!("4ab2bc4b8ad548971900005c", true)</tt>
53
+ # <tt>Mongoid.cast_ids!(["4ab2bc4b8ad548971900005c"])</tt>
54
+ #
55
+ # Returns:
56
+ #
57
+ # If using object ids:
58
+ # An +Array+ of +BSON::ObjectID+ of each element if params is an +Array+
59
+ # A +BSON::ObjectID+ from params if params is +String+
60
+ # Otherwise:
61
+ # <tt>args</tt>
62
+ def cast_ids!(args, cast = true)
63
+ return args if !using_object_ids? || args.is_a?(BSON::ObjectID) || !cast
64
+ if args.is_a?(String)
65
+ BSON::ObjectID(args)
66
+ else
67
+ args.map{ |a|
68
+ a.is_a?(BSON::ObjectID) ? a : BSON::ObjectID(a)
69
+ }
70
+ end
71
+ end
72
+
41
73
  # Adds fields to be sorted in descending order. Will add them in the order
42
74
  # they were passed into the method.
43
75
  #
@@ -102,9 +134,9 @@ module Mongoid #:nodoc:
102
134
  def id(*ids)
103
135
  ids.flatten!
104
136
  if ids.size > 1
105
- self.in(:_id => Mongoid.convert_to_object_id(ids, self.klass.primary_key.nil?))
137
+ self.in(:_id => cast_ids!(ids, self.klass.primary_key.nil?))
106
138
  else
107
- @selector[:_id] = Mongoid.convert_to_object_id(ids.first, self.klass.primary_key.nil?)
139
+ @selector[:_id] = cast_ids!(ids.first, self.klass.primary_key.nil?)
108
140
  end
109
141
  self
110
142
  end
@@ -174,7 +206,8 @@ module Mongoid #:nodoc:
174
206
  @options[:skip] = value; self
175
207
  end
176
208
 
177
- # Adds a criterion to the +Criteria+ that specifies a type or an Array of type that must be matched.
209
+ # Adds a criterion to the +Criteria+ that specifies a type or an Array of
210
+ # type that must be matched.
178
211
  #
179
212
  # Options:
180
213
  #
@@ -5,13 +5,9 @@ module Mongoid #:nodoc:
5
5
  included do
6
6
  include Mongoid::Components
7
7
 
8
- cattr_accessor :primary_key
9
-
10
8
  attr_accessor :association_name
11
9
  attr_reader :new_record
12
10
 
13
- delegate :primary_key, :to => "self.class"
14
-
15
11
  unless self.instance_of?(Class) and self.name == ""
16
12
  (@@descendants ||= {})[self] = :seen
17
13
  end
@@ -46,22 +42,6 @@ module Mongoid #:nodoc:
46
42
  end
47
43
  end
48
44
 
49
- # Defines the field that will be used for the id of this +Document+. This
50
- # set the id of this +Document+ before save to a parameterized version of
51
- # the field that was supplied. This is good for use for readable URLS in
52
- # web applications.
53
- #
54
- # Example:
55
- #
56
- # class Person
57
- # include Mongoid::Document
58
- # key :first_name, :last_name
59
- # end
60
- def key(*fields)
61
- self.primary_key = fields
62
- set_callback :save, :before, :identify
63
- end
64
-
65
45
  # Returns the classes that have included Mongoid::Document
66
46
  def self.descendents
67
47
  (@@descendants ||= {}).keys
@@ -88,8 +68,13 @@ module Mongoid #:nodoc:
88
68
  self == (comparison_object)
89
69
  end
90
70
 
91
- # Delegates to id in order to allow two records of the same type and id to work with something like:
92
- # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
71
+ # Delegates to id in order to allow two records of the same type and id to
72
+ # work with something like:
73
+ # [ Person.find(1),
74
+ # Person.find(2),
75
+ # Person.find(3) ] &
76
+ # [ Person.find(1),
77
+ # Person.find(4) ] # => [ Person.find(1) ]
93
78
  def hash
94
79
  id.hash
95
80
  end
@@ -25,7 +25,7 @@ module Mongoid #:nodoc:
25
25
  # Return the proper id for the document.
26
26
  def generate_id
27
27
  id = BSON::ObjectID.new
28
- Mongoid.use_object_ids ? id : id.to_s
28
+ @document.using_object_ids? ? id : id.to_s
29
29
  end
30
30
 
31
31
  # Set the id for the document.
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Keys
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ cattr_accessor :primary_key, :_identity
7
+ self._identity = { :type => BSON::ObjectID }
8
+
9
+ delegate \
10
+ :_id_type,
11
+ :primary_key,
12
+ :using_object_ids?, :to => "self.class"
13
+ end
14
+
15
+ module ClassMethods #:nodoc:
16
+
17
+ # Convenience method for returning the type of the id for this class.
18
+ #
19
+ # Example:
20
+ #
21
+ # <tt>Person._id_type</tt>
22
+ #
23
+ # Returns:
24
+ #
25
+ # The type of the id.
26
+ def _id_type
27
+ _identity[:type]
28
+ end
29
+
30
+ # Used for telling Mongoid on a per model basis whether to override the
31
+ # default +BSON::ObjectID+ and use a different type. This will be
32
+ # expanded in the future for requiring a PkFactory if the type is not a
33
+ # +BSON::ObjectID+ or +String+.
34
+ #
35
+ # Example:
36
+ #
37
+ # class Person
38
+ # include Mongoid::Document
39
+ # identity :type => String
40
+ # end
41
+ def identity(options = {})
42
+ self._identity = options
43
+ end
44
+
45
+ # Defines the field that will be used for the id of this +Document+. This
46
+ # set the id of this +Document+ before save to a parameterized version of
47
+ # the field that was supplied. This is good for use for readable URLS in
48
+ # web applications.
49
+ #
50
+ # Example:
51
+ #
52
+ # class Person
53
+ # include Mongoid::Document
54
+ # key :first_name, :last_name
55
+ # end
56
+ def key(*fields)
57
+ self.primary_key = fields
58
+ identity(:type => String)
59
+ set_callback :save, :before, :identify
60
+ end
61
+
62
+ # Convenience method for determining if we are using +BSON::ObjectIDs+ as
63
+ # our id.
64
+ #
65
+ # Example:
66
+ #
67
+ # <tt>person.using_object_ids?</tt>
68
+ #
69
+ # Returns:
70
+ #
71
+ # true if we are using BSON::ObjectIDs
72
+ def using_object_ids?
73
+ _id_type == BSON::ObjectID
74
+ end
75
+ end
76
+ end
77
+ end
@@ -19,15 +19,14 @@ module Mongoid #:nodoc:
19
19
  # <tt>document.upsert</tt>
20
20
  module Persistence
21
21
  extend ActiveSupport::Concern
22
+
22
23
  # Remove the +Document+ from the datbase with callbacks.
23
24
  #
24
25
  # Example:
25
26
  #
26
27
  # <tt>document.destroy</tt>
27
- #
28
- # TODO: Will get rid of other #destroy once new persistence complete.
29
- def destroy
30
- run_callbacks(:destroy) { self.destroyed = true if _remove }
28
+ def destroy(options = {})
29
+ run_callbacks(:destroy) { self.destroyed = true if _remove(options) }
31
30
  end
32
31
 
33
32
  # Insert a new +Document+ into the database. Will return the document
@@ -36,8 +35,8 @@ module Mongoid #:nodoc:
36
35
  # Example:
37
36
  #
38
37
  # <tt>document.insert</tt>
39
- def insert(validate = true)
40
- Insert.new(self, validate).persist
38
+ def insert(options = {})
39
+ Insert.new(self, options).persist
41
40
  end
42
41
 
43
42
  # Remove the +Document+ from the datbase.
@@ -47,8 +46,8 @@ module Mongoid #:nodoc:
47
46
  # <tt>document._remove</tt>
48
47
  #
49
48
  # TODO: Will get rid of other #remove once observable pattern killed.
50
- def _remove
51
- Remove.new(self).persist
49
+ def _remove(options = {})
50
+ Remove.new(self, options).persist
52
51
  end
53
52
 
54
53
  alias :delete :_remove
@@ -64,7 +63,7 @@ module Mongoid #:nodoc:
64
63
  # Returns:
65
64
  #
66
65
  # +true+ if validation passed, will raise error otherwise.
67
- def save!
66
+ def save!(options = {})
68
67
  self.class.fail_validate!(self) unless upsert; true
69
68
  end
70
69
 
@@ -73,8 +72,8 @@ module Mongoid #:nodoc:
73
72
  # Example:
74
73
  #
75
74
  # <tt>document.update</tt>
76
- def update(validate = true)
77
- Update.new(self, validate).persist
75
+ def update(options = {})
76
+ Update.new(self, options).persist
78
77
  end
79
78
 
80
79
  # Update the +Document+ attributes in the datbase.
@@ -116,12 +115,11 @@ module Mongoid #:nodoc:
116
115
  # Returns:
117
116
  #
118
117
  # A +Boolean+ for updates.
119
- def upsert(validate = true)
120
- validate = parse_validate(validate)
118
+ def upsert(options = {})
121
119
  if new_record?
122
- insert(validate).persisted?
120
+ insert(options).persisted?
123
121
  else
124
- update(validate)
122
+ update(options)
125
123
  end
126
124
  end
127
125
 
@@ -133,15 +131,6 @@ module Mongoid #:nodoc:
133
131
  # <tt>document.save</tt>
134
132
  alias :save :upsert
135
133
 
136
- protected
137
- # Alternative validation params.
138
- def parse_validate(validate)
139
- if validate.is_a?(Hash) && validate.has_key?(:validate)
140
- validate = validate[:validate]
141
- end
142
- validate
143
- end
144
-
145
134
  module ClassMethods #:nodoc:
146
135
 
147
136
  # Create a new +Document+. This will instantiate a new document and
@@ -186,7 +175,7 @@ module Mongoid #:nodoc:
186
175
  def delete_all(conditions = {})
187
176
  RemoveAll.new(
188
177
  self,
189
- false,
178
+ { :validate => false },
190
179
  conditions[:conditions] || {}
191
180
  ).persist
192
181
  end
@@ -17,13 +17,13 @@ module Mongoid #:nodoc:
17
17
  # Options:
18
18
  #
19
19
  # document_or_class: The +Document+ or +Class+ to get the collection.
20
- # validate: Is the document to be validated.
20
+ # options: Options like validation or safe mode.
21
21
  # selector: Optional selector to use in query.
22
22
  #
23
23
  # Example:
24
24
  #
25
- # <tt>DeleteAll.new(Person, false, {})</tt>
26
- def initialize(document_or_class, validate = true, selector = {})
25
+ # <tt>DeleteAll.new(Person, { :validate => true }, {})</tt>
26
+ def initialize(document_or_class, options = {}, selector = {})
27
27
  if document_or_class.is_a?(Mongoid::Document)
28
28
  @document = document_or_class
29
29
  @collection = @document.embedded? ? @document._root.collection : @document.collection
@@ -31,8 +31,20 @@ module Mongoid #:nodoc:
31
31
  @klass = document_or_class
32
32
  @collection = @klass.collection
33
33
  end
34
- @selector, @validate = selector, validate
35
- @options = { :safe => Mongoid.persist_in_safe_mode }
34
+ validate = options[:validate]
35
+ @selector = selector
36
+ @validate = (validate.nil? ? true : validate)
37
+ @options = { :safe => safe_mode?(options) }
38
+ end
39
+
40
+ protected
41
+ # Determine based on configuration if we are persisting in safe mode or
42
+ # not.
43
+ #
44
+ # The query option will always override the global configuration.
45
+ def safe_mode?(options)
46
+ safe = options[:safe]
47
+ safe.nil? ? Mongoid.persist_in_safe_mode : safe
36
48
  end
37
49
  end
38
50
  end
@@ -38,7 +38,10 @@ module Mongoid #:nodoc:
38
38
  # Insert the document into the database.
39
39
  def insert
40
40
  if @document.embedded?
41
- Persistence::InsertEmbedded.new(@document, @validate).persist
41
+ Persistence::InsertEmbedded.new(
42
+ @document,
43
+ @options.merge(:validate => @validate)
44
+ ).persist
42
45
  else
43
46
  @collection.insert(@document.raw_attributes, @options)
44
47
  end
@@ -29,7 +29,10 @@ module Mongoid #:nodoc:
29
29
  # Remove the document from the database.
30
30
  def remove
31
31
  if @document.embedded?
32
- Persistence::RemoveEmbedded.new(@document, @validate).persist
32
+ Persistence::RemoveEmbedded.new(
33
+ @document,
34
+ @options.merge(:validate => @validate)
35
+ ).persist
33
36
  else
34
37
  @collection.remove({ :_id => @document.id }, @options)
35
38
  end
@@ -61,9 +61,12 @@ module Mongoid #:nodoc:
61
61
  updates = @document._updates
62
62
  unless updates.empty?
63
63
  other_pushes = updates.delete(:other)
64
-
65
64
  @collection.update(@document._selector, updates, @options.merge(:multi => false))
66
- @collection.update(@document._selector, { "$pushAll" => other_pushes }, @options.merge(:multi => false)) if other_pushes
65
+ @collection.update(
66
+ @document._selector,
67
+ { "$pushAll" => other_pushes },
68
+ @options.merge(:multi => false)
69
+ ) if other_pushes
67
70
  end; true
68
71
  end
69
72
  end
@@ -0,0 +1,168 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # The +Safety+ module is used to provide a DSL to execute database operations
5
+ # in safe mode on a per query basis, either from the +Document+ class level
6
+ # or instance level.
7
+ module Safety
8
+ extend ActiveSupport::Concern
9
+
10
+ # Execute the following class-level persistence operation in safe mode.
11
+ #
12
+ # Example:
13
+ #
14
+ # <tt>person.safely.upsert</tt>
15
+ # <tt>person.safely.destroy</tt>
16
+ #
17
+ # Returns:
18
+ #
19
+ # A +Proxy+ to the +Document+.
20
+ def safely
21
+ Proxy.new(self)
22
+ end
23
+
24
+ module ClassMethods #:nodoc:
25
+
26
+ # Execute the following class-level persistence operation in safe mode.
27
+ #
28
+ # Example:
29
+ #
30
+ # <tt>Person.safely.create(:name => "John")</tt>
31
+ # <tt>Person.safely.delete_all</tt>
32
+ #
33
+ # Returns:
34
+ #
35
+ # A +Proxy+ to the +Document+ class.
36
+ def safely
37
+ Proxy.new(self)
38
+ end
39
+ end
40
+
41
+ # When this class proxies a document or class, the next persistence
42
+ # operation executed on it will query in safe mode.
43
+ #
44
+ # Operations that took a hash of attributes had to be somewhat duplicated
45
+ # here since we do not want to allow a :safe attribute to be included in
46
+ # the args. This is because safe could be a common attribute name and we
47
+ # don't want the collision between the attribute and determining whether or
48
+ # not safe mode is allowed.
49
+ class Proxy
50
+
51
+ attr_reader :target
52
+
53
+ # Create the new +Proxy+.
54
+ #
55
+ # Options:
56
+ #
57
+ # target: Either the class or the instance.
58
+ def initialize(target)
59
+ @target = target
60
+ end
61
+
62
+ # We will use method missing to proxy calls to the target.
63
+ #
64
+ # Example:
65
+ #
66
+ # <tt>person.safely.save</tt>
67
+ def method_missing(*args)
68
+ name = args[0]
69
+ attributes = args[1] || {}
70
+ @target.send(name, attributes.merge(:safe => true))
71
+ end
72
+
73
+ # Update the +Document+ attributes in the datbase.
74
+ #
75
+ # Example:
76
+ #
77
+ # <tt>document.update_attributes(:title => "Sir")</tt>
78
+ #
79
+ # Returns:
80
+ #
81
+ # +true+ if validation passed, +false+ if not.
82
+ def update_attributes(attributes = {})
83
+ @target.write_attributes(attributes)
84
+ @target.update(:safe => true)
85
+ end
86
+
87
+ # Update the +Document+ attributes in the datbase.
88
+ #
89
+ # Example:
90
+ #
91
+ # <tt>document.update_attributes(:title => "Sir")</tt>
92
+ #
93
+ # Returns:
94
+ #
95
+ # +true+ if validation passed, raises an error if not
96
+ def update_attributes!(attributes = {})
97
+ @target.write_attributes(attributes)
98
+ result = update(:safe => true)
99
+ @target.class.fail_validate!(self) unless result
100
+ result
101
+ end
102
+
103
+ # Create a new +Document+. This will instantiate a new document and
104
+ # insert it in a single call. Will always return the document
105
+ # whether save passed or not.
106
+ #
107
+ # Example:
108
+ #
109
+ # <tt>Person.create(:title => "Mr")</tt>
110
+ #
111
+ # Returns: the +Document+.
112
+ def create(attributes = {})
113
+ @target.new(attributes).tap { |doc| doc.insert(:safe => true) }
114
+ end
115
+
116
+ # Create a new +Document+. This will instantiate a new document and
117
+ # insert it in a single call. Will always return the document
118
+ # whether save passed or not, and if validation fails an error will be
119
+ # raise.
120
+ #
121
+ # Example:
122
+ #
123
+ # <tt>Person.create!(:title => "Mr")</tt>
124
+ #
125
+ # Returns: the +Document+.
126
+ def create!(attributes = {})
127
+ document = @target.new(attributes)
128
+ fail_validate!(document) if document.insert(:safe => true).errors.any?
129
+ document
130
+ end
131
+
132
+ # Delete all documents given the supplied conditions. If no conditions
133
+ # are passed, the entire collection will be dropped for performance
134
+ # benefits. Does not fire any callbacks.
135
+ #
136
+ # Example:
137
+ #
138
+ # <tt>Person.delete_all(:conditions => { :title => "Sir" })</tt>
139
+ # <tt>Person.delete_all</tt>
140
+ #
141
+ # Returns: true or raises an error.
142
+ def delete_all(conditions = {})
143
+ Mongoid::Persistence::RemoveAll.new(
144
+ @target,
145
+ { :validate => false, :safe => true },
146
+ conditions[:conditions] || {}
147
+ ).persist
148
+ end
149
+
150
+ # Delete all documents given the supplied conditions. If no conditions
151
+ # are passed, the entire collection will be dropped for performance
152
+ # benefits. Fires the destroy callbacks if conditions were passed.
153
+ #
154
+ # Example:
155
+ #
156
+ # <tt>Person.destroy_all(:conditions => { :title => "Sir" })</tt>
157
+ # <tt>Person.destroy_all</tt>
158
+ #
159
+ # Returns: true or raises an error.
160
+ def destroy_all(conditions = {})
161
+ documents = @target.all(conditions)
162
+ count = documents.count
163
+ documents.each { |doc| doc.destroy(:safe => true) }
164
+ count
165
+ end
166
+ end
167
+ end
168
+ end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc
3
- VERSION = "2.0.0.beta.10"
3
+ VERSION = "2.0.0.beta.11"
4
4
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196471
4
+ hash: 62196469
5
5
  prerelease: true
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
9
  - 0
10
10
  - beta
11
- - 10
12
- version: 2.0.0.beta.10
11
+ - 11
12
+ version: 2.0.0.beta.11
13
13
  platform: ruby
14
14
  authors:
15
15
  - Durran Jordan
@@ -253,6 +253,7 @@ files:
253
253
  - lib/mongoid/indexes.rb
254
254
  - lib/mongoid/javascript/functions.yml
255
255
  - lib/mongoid/javascript.rb
256
+ - lib/mongoid/keys.rb
256
257
  - lib/mongoid/logger.rb
257
258
  - lib/mongoid/matchers/all.rb
258
259
  - lib/mongoid/matchers/default.rb
@@ -280,6 +281,7 @@ files:
280
281
  - lib/mongoid/persistence.rb
281
282
  - lib/mongoid/railtie.rb
282
283
  - lib/mongoid/railties/database.rake
284
+ - lib/mongoid/safety.rb
283
285
  - lib/mongoid/scope.rb
284
286
  - lib/mongoid/state.rb
285
287
  - lib/mongoid/timestamps.rb
@@ -301,7 +303,7 @@ has_rdoc: true
301
303
  homepage: http://mongoid.org
302
304
  licenses: []
303
305
 
304
- post_install_message:
306
+ post_install_message: " _________________________________\n |:::::::::::::::::::::::::::::::::| \"I find your lack of faith disturbing.\"\n |:::::::::::::;;::::::::::::::::::|\n |:::::::::::'~||~~~``:::::::::::::| Mongoid 2 introduces\n |::::::::' .': o`:::::::::::| a different way of defining how\n |:::::::' oo | |o o ::::::::::| ids are stored on documents, as\n |::::::: 8 .'.' 8 o :::::::::| well as how foreign key fields\n |::::::: 8 | | 8 :::::::::| and indexes are stored.\n |::::::: _._| |_,...8 :::::::::|\n |::::::'~--. .--. `. `::::::::| If you were using String\n |:::::' =8 ~ \\ o ::::::::| representations of BSON::ObjectIDs\n |::::' 8._ 88. \\ o::::::::| as your document ids, all of your\n |:::' __. ,.ooo~~. \\ o`::::::| documents will now need to tell\n |::: . -. 88`78o/: \\ `:::::| Mongoid to use Strings like so:\n |::' /. o o \\ :: \\88`::::|\n |:; o|| 8 8 |d. `8 `:::| class User\n |:. - ^ ^ -' `-`::| include Mongoid::Document\n |::. .:::| identity :type => String\n |:::::..... ::' ``::| end\n |::::::::-'`- 88 `|\n |:::::-'. - :: | All ids will default to\n |:-~. . . : | BSON:ObjectIDs from now on, and\n | .. . ..: o:8 88o | Config#use_object_ids has been\n |. . ::: 8:P d888. . . | removed.\n |. . :88 88 888' . . |\n | o8 d88P . 88 ' d88P .. | Foreign key fields for relational\n | 88P 888 d8P ' 888 | associations no longer index by\n | 8 d88P.'d:8 .- dP~ o8 | default - you will need to pass\n | 888 888 d~ o888 LS | :index => true to the association\n |_________________________________| definition to have the field indexed\n\n or create the index manually, which is the preferred method. Note that\n if you were using String ids and now want to use object ids instead you\n will have to migrate your database manually - Mongoid cannot perform\n this for you automatically. If you were using custom composite keys,\n these will need to be defined as Strings since they cannot be converted.\n\n Please see the following gist for assistance in migrating the database\n via the Ruby driver (thanks to Kyle Banker):\n\n http://gist.github.com/489098\n\n"
305
307
  rdoc_options: []
306
308
 
307
309
  require_paths: