mongoid 2.0.0.beta.20 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/README.rdoc +8 -0
  2. data/Rakefile +51 -0
  3. data/lib/config/locales/nl.yml +39 -0
  4. data/lib/config/locales/ro.yml +1 -1
  5. data/lib/mongoid.rb +17 -17
  6. data/lib/mongoid/atomicity.rb +54 -22
  7. data/lib/mongoid/attributes.rb +145 -125
  8. data/lib/mongoid/callbacks.rb +7 -2
  9. data/lib/mongoid/collection.rb +49 -32
  10. data/lib/mongoid/collections.rb +0 -1
  11. data/lib/mongoid/components.rb +34 -29
  12. data/lib/mongoid/config.rb +207 -193
  13. data/lib/mongoid/config/database.rb +167 -0
  14. data/lib/mongoid/contexts.rb +2 -5
  15. data/lib/mongoid/contexts/enumerable.rb +30 -4
  16. data/lib/mongoid/contexts/ids.rb +2 -2
  17. data/lib/mongoid/contexts/mongo.rb +30 -5
  18. data/lib/mongoid/copyable.rb +44 -0
  19. data/lib/mongoid/criteria.rb +110 -56
  20. data/lib/mongoid/criterion/creational.rb +34 -0
  21. data/lib/mongoid/criterion/destructive.rb +37 -0
  22. data/lib/mongoid/criterion/exclusion.rb +3 -1
  23. data/lib/mongoid/criterion/inclusion.rb +59 -64
  24. data/lib/mongoid/criterion/inspection.rb +22 -0
  25. data/lib/mongoid/criterion/optional.rb +42 -54
  26. data/lib/mongoid/criterion/selector.rb +9 -0
  27. data/lib/mongoid/default_scope.rb +28 -0
  28. data/lib/mongoid/deprecation.rb +5 -5
  29. data/lib/mongoid/dirty.rb +4 -5
  30. data/lib/mongoid/document.rb +161 -114
  31. data/lib/mongoid/extensions.rb +7 -11
  32. data/lib/mongoid/extensions/array/parentization.rb +2 -2
  33. data/lib/mongoid/extensions/date/conversions.rb +1 -1
  34. data/lib/mongoid/extensions/hash/conversions.rb +0 -23
  35. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  36. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  37. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  38. data/lib/mongoid/extensions/string/conversions.rb +23 -4
  39. data/lib/mongoid/extensions/time_conversions.rb +4 -4
  40. data/lib/mongoid/field.rb +30 -19
  41. data/lib/mongoid/fields.rb +15 -5
  42. data/lib/mongoid/finders.rb +19 -11
  43. data/lib/mongoid/hierarchy.rb +34 -28
  44. data/lib/mongoid/identity.rb +62 -20
  45. data/lib/mongoid/inspection.rb +58 -0
  46. data/lib/mongoid/matchers.rb +20 -0
  47. data/lib/mongoid/multi_database.rb +11 -0
  48. data/lib/mongoid/nested_attributes.rb +41 -0
  49. data/lib/mongoid/paranoia.rb +3 -4
  50. data/lib/mongoid/paths.rb +1 -1
  51. data/lib/mongoid/persistence.rb +89 -90
  52. data/lib/mongoid/persistence/command.rb +20 -4
  53. data/lib/mongoid/persistence/insert.rb +13 -11
  54. data/lib/mongoid/persistence/insert_embedded.rb +8 -6
  55. data/lib/mongoid/persistence/remove.rb +6 -4
  56. data/lib/mongoid/persistence/remove_all.rb +6 -4
  57. data/lib/mongoid/persistence/remove_embedded.rb +8 -6
  58. data/lib/mongoid/persistence/update.rb +12 -10
  59. data/lib/mongoid/railtie.rb +2 -2
  60. data/lib/mongoid/railties/database.rake +10 -9
  61. data/lib/mongoid/relations.rb +104 -0
  62. data/lib/mongoid/relations/accessors.rb +154 -0
  63. data/lib/mongoid/relations/auto_save.rb +34 -0
  64. data/lib/mongoid/relations/binding.rb +24 -0
  65. data/lib/mongoid/relations/bindings.rb +9 -0
  66. data/lib/mongoid/relations/bindings/embedded/in.rb +77 -0
  67. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  68. data/lib/mongoid/relations/bindings/embedded/one.rb +65 -0
  69. data/lib/mongoid/relations/bindings/referenced/in.rb +78 -0
  70. data/lib/mongoid/relations/bindings/referenced/many.rb +93 -0
  71. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +94 -0
  72. data/lib/mongoid/relations/bindings/referenced/one.rb +63 -0
  73. data/lib/mongoid/relations/builder.rb +41 -0
  74. data/lib/mongoid/relations/builders.rb +79 -0
  75. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  76. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  77. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  78. data/lib/mongoid/relations/builders/nested_attributes/many.rb +116 -0
  79. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  80. data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
  81. data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
  82. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  83. data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
  84. data/lib/mongoid/relations/cascading.rb +55 -0
  85. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  86. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  87. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  88. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  89. data/lib/mongoid/relations/cyclic.rb +97 -0
  90. data/lib/mongoid/relations/embedded/in.rb +172 -0
  91. data/lib/mongoid/relations/embedded/many.rb +450 -0
  92. data/lib/mongoid/relations/embedded/one.rb +169 -0
  93. data/lib/mongoid/relations/macros.rb +302 -0
  94. data/lib/mongoid/relations/many.rb +185 -0
  95. data/lib/mongoid/relations/metadata.rb +529 -0
  96. data/lib/mongoid/relations/nested_builder.rb +52 -0
  97. data/lib/mongoid/relations/one.rb +29 -0
  98. data/lib/mongoid/relations/polymorphic.rb +54 -0
  99. data/lib/mongoid/relations/proxy.rb +122 -0
  100. data/lib/mongoid/relations/referenced/in.rb +214 -0
  101. data/lib/mongoid/relations/referenced/many.rb +358 -0
  102. data/lib/mongoid/relations/referenced/many_to_many.rb +379 -0
  103. data/lib/mongoid/relations/referenced/one.rb +204 -0
  104. data/lib/mongoid/relations/reflections.rb +45 -0
  105. data/lib/mongoid/safe.rb +11 -1
  106. data/lib/mongoid/safety.rb +122 -97
  107. data/lib/mongoid/scope.rb +14 -9
  108. data/lib/mongoid/state.rb +37 -3
  109. data/lib/mongoid/timestamps.rb +11 -0
  110. data/lib/mongoid/validations.rb +42 -3
  111. data/lib/mongoid/validations/associated.rb +8 -5
  112. data/lib/mongoid/validations/uniqueness.rb +23 -2
  113. data/lib/mongoid/version.rb +1 -1
  114. data/lib/mongoid/versioning.rb +25 -16
  115. data/lib/rails/generators/mongoid/model/templates/model.rb +3 -1
  116. metadata +95 -80
  117. data/lib/mongoid/associations.rb +0 -364
  118. data/lib/mongoid/associations/embedded_in.rb +0 -74
  119. data/lib/mongoid/associations/embeds_many.rb +0 -299
  120. data/lib/mongoid/associations/embeds_one.rb +0 -111
  121. data/lib/mongoid/associations/foreign_key.rb +0 -35
  122. data/lib/mongoid/associations/meta_data.rb +0 -38
  123. data/lib/mongoid/associations/options.rb +0 -78
  124. data/lib/mongoid/associations/proxy.rb +0 -60
  125. data/lib/mongoid/associations/referenced_in.rb +0 -70
  126. data/lib/mongoid/associations/references_many.rb +0 -254
  127. data/lib/mongoid/associations/references_many_as_array.rb +0 -128
  128. data/lib/mongoid/associations/references_one.rb +0 -104
  129. data/lib/mongoid/extensions/array/accessors.rb +0 -17
  130. data/lib/mongoid/extensions/array/assimilation.rb +0 -26
  131. data/lib/mongoid/extensions/hash/accessors.rb +0 -42
  132. data/lib/mongoid/extensions/hash/assimilation.rb +0 -40
  133. data/lib/mongoid/extensions/nil/assimilation.rb +0 -17
  134. data/lib/mongoid/memoization.rb +0 -33
@@ -1,47 +1,89 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc:
3
3
  class Identity #:nodoc:
4
- # Create the identity for the +Document+.
5
- #
6
- # The id will be set in either in the form of a Mongo
7
- # +ObjectID+ or a composite key set up by defining a key on the document.
4
+
5
+ attr_reader :document
6
+
7
+ # Create the identity for the document. The id will be set in either in
8
+ # the form of a Mongo object id or a composite key set up by defining
9
+ # a key on the document. The _type will be set to the document's class
10
+ # name.
8
11
  #
9
- # The _type will be set to the document's class name.
12
+ # @example Create the id and set the type.
13
+ # identity.create
10
14
  def create
11
- identify!; type!
15
+ identify and type
12
16
  end
13
17
 
14
18
  # Create the new identity generator - this will be expanded in the future
15
19
  # to support pk generators.
16
20
  #
17
- # Options:
21
+ # @example
22
+ # Identity.new(document)
23
+ #
24
+ # @param [ Document ] document The document to generate an id for.
18
25
  #
19
- # document: The document to generate an id for.
26
+ # @return [ Identity ] The new identity object.
20
27
  def initialize(document)
21
28
  @document = document
22
29
  end
23
30
 
24
- protected
25
- # Return the proper id for the document.
31
+ private
32
+
33
+ # Return the proper id for the document. Will be an object id or its string
34
+ # representation depending on the configuration.
35
+ #
36
+ # @example Generate the id.
37
+ # identity.generate_id
38
+ #
39
+ # @return [ Object ] The bson object id or its string equivalent.
26
40
  def generate_id
27
41
  id = BSON::ObjectId.new
28
- @document.using_object_ids? ? id : id.to_s
42
+ document.using_object_ids? ? id : id.to_s
29
43
  end
30
44
 
31
- # Set the id for the document.
32
- def identify!
33
- @document.id = compose.join(" ").identify if @document.primary_key
34
- @document.id = generate_id if @document.id.blank?
45
+ # Sets the id on the document. Will either set a newly generated id or
46
+ # build the composite key.
47
+ #
48
+ # @example Set the id.
49
+ # identity.identify
50
+ def identify
51
+ document.id = compose.join(" ").identify if document.primary_key
52
+ document.id = generate_id if document.id.blank?
35
53
  end
36
54
 
37
- # Set the _type field on the @document.
38
- def type!
39
- @document._type = @document.class.name if @document.hereditary? || @document.class.descendants.any?
55
+ # Set the _type field on the document if the document is hereditary or in a
56
+ # polymorphic relation.
57
+ #
58
+ # @example Set the type.
59
+ # identity.type
60
+ def type
61
+ document._type = document.class.name if typed?
40
62
  end
41
63
 
42
- # Generates the composite key for a @document.ment.
64
+ # Generates the array of keys to build the id.
65
+ #
66
+ # @example Build the array for the keys.
67
+ # identity.compose.
68
+ #
69
+ # @return [ Array<Object> ] The array of keys.
43
70
  def compose
44
- @document.primary_key.collect { |key| @document.attributes[key] }.reject { |val| val.nil? }
71
+ document.primary_key.collect do |key|
72
+ document.attributes[key]
73
+ end.reject { |val| val.nil? }
74
+ end
75
+
76
+ # Determines if the document stores the type information. This is if it is
77
+ # in a hierarchy, has subclasses, or is in a polymorphic relation.
78
+ #
79
+ # @example Check if the document is typed.
80
+ # identity.typed?
81
+ #
82
+ # @return [ true, false ] True if typed, false if not.
83
+ def typed?
84
+ document.hereditary? ||
85
+ document.class.descendants.any? ||
86
+ document.polymorphic?
45
87
  end
46
88
  end
47
89
  end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Inspection #:nodoc
4
+
5
+ # Returns the class name plus its attributes. If using dynamic fields will
6
+ # include those as well.
7
+ #
8
+ # Example:
9
+ #
10
+ # <tt>person.inspect</tt>
11
+ #
12
+ # Returns:
13
+ #
14
+ # A nice pretty string to look at.
15
+ def inspect
16
+ inspection = []
17
+ inspection.concat(inspect_fields).concat(inspect_dynamic_fields)
18
+ "#<#{self.class.name} _id: #{id}, #{inspection * ', '}>"
19
+ end
20
+
21
+ private
22
+
23
+ # Get an array of inspected fields for the document.
24
+ #
25
+ # Example:
26
+ #
27
+ # <tt>inspect_fields</tt>
28
+ #
29
+ # Returns:
30
+ #
31
+ # An array of pretty printed field values.
32
+ def inspect_fields
33
+ fields.map do |name, field|
34
+ "#{name}: #{@attributes[name].inspect}"
35
+ end
36
+ end
37
+
38
+ # Get an array of inspected dynamic fields for the document.
39
+ #
40
+ # Example:
41
+ #
42
+ # <tt>inspect_dynamic_fields</tt>
43
+ #
44
+ # Returns:
45
+ #
46
+ # An array of pretty printed dynamic field values.
47
+ def inspect_dynamic_fields
48
+ if Mongoid.allow_dynamic_fields
49
+ keys = @attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
50
+ return keys.map do |name|
51
+ "#{name}: #{@attributes[name].inspect}"
52
+ end
53
+ else
54
+ []
55
+ end
56
+ end
57
+ end
58
+ end
@@ -12,9 +12,20 @@ require "mongoid/matchers/nin"
12
12
  require "mongoid/matchers/size"
13
13
 
14
14
  module Mongoid #:nodoc:
15
+
16
+ # This module contains all the behavior for ruby implementations of MongoDB
17
+ # selectors.
15
18
  module Matchers
19
+
16
20
  # Determines if this document has the attributes to match the supplied
17
21
  # MongoDB selector. Used for matching on embedded associations.
22
+ #
23
+ # @example Does the document match?
24
+ # document.matches?(:title => { "$in" => [ "test" ] })
25
+ #
26
+ # @param [ Hash ] selector The MongoDB selector.
27
+ #
28
+ # @return [ true, false ] True if matches, false if not.
18
29
  def matches?(selector)
19
30
  selector.each_pair do |key, value|
20
31
  return false unless matcher(key, value).matches?(value)
@@ -22,8 +33,17 @@ module Mongoid #:nodoc:
22
33
  end
23
34
 
24
35
  protected
36
+
25
37
  # Get the matcher for the supplied key and value. Will determine the class
26
38
  # name from the key.
39
+ #
40
+ # @example Get the matcher.
41
+ # document.matcher(:title, { "$in" => [ "test" ] })
42
+ #
43
+ # @param [ Symbol, String ] key The field name.
44
+ # @param [ Object, Hash ] The value or selector.
45
+ #
46
+ # @return [ Matcher ] The matcher.
27
47
  def matcher(key, value)
28
48
  if value.is_a?(Hash)
29
49
  name = "Mongoid::Matchers::#{value.keys.first.gsub("$", "").camelize}"
@@ -0,0 +1,11 @@
1
+ module Mongoid::MultiDatabase
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+
6
+ def database; @database end
7
+ def set_database(name)
8
+ @database = name.to_s
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module NestedAttributes
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+
8
+ # Used when needing to update related models from a parent relation. Can
9
+ # be used on embedded or referenced relations.
10
+ #
11
+ # @example Defining nested attributes.
12
+ #
13
+ # class Person
14
+ # include Mongoid::Document
15
+ #
16
+ # embeds_many :addresses
17
+ # embeds_one :game
18
+ # references_many :posts
19
+ #
20
+ # accepts_nested_attributes_for :addresses, :game, :posts
21
+ # end
22
+ #
23
+ # @param [ Array<Symbol>, Hash ] *args A list of relation names, followed
24
+ # by a hash of options.
25
+ #
26
+ # @option *args [ true, false ] :allow_destroy Can deletion occur?
27
+ # @option *args [ Proc ] :reject_if Block to reject documents with.
28
+ # @option *args [ Integer ] :limit The max number to create.
29
+ # @option *args [ true, false ] :update_only Only update existing docs.
30
+ def accepts_nested_attributes_for(*args)
31
+ options = args.extract_options!
32
+ args.each do |name|
33
+ define_method("#{name}_attributes=") do |attrs|
34
+ relation = relations[name.to_s]
35
+ relation.nested_builder(attrs, options).build(self)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -84,21 +84,20 @@ module Mongoid #:nodoc:
84
84
  # Returns:
85
85
  #
86
86
  # A +Criteria+ for deleted_at not existing.
87
- def criteria
87
+ def criteria(embedded = false)
88
88
  super.where(:deleted_at.exists => false)
89
89
  end
90
-
90
+
91
91
  # Find deleted documents
92
92
  #
93
93
  # Examples:
94
94
  #
95
95
  # <tt>Person.deleted</tt> # all deleted employees
96
96
  # <tt>Company.first.employees.deleted</tt> # works with a join
97
- # <tt>Person.deleted.find("4c188dea7b17235a2a000001").first</tt> # retrieve by id a deleted person
97
+ # <tt>Person.deleted.find("4c188dea7b17235a2a000001").first</tt>
98
98
  def deleted
99
99
  where(:deleted_at.exists => true)
100
100
  end
101
-
102
101
  end
103
102
  end
104
103
  end
@@ -35,7 +35,7 @@ module Mongoid #:nodoc:
35
35
  # <tt>address.position</tt>
36
36
  def _position
37
37
  locator = _index ? (new_record? ? "" : ".#{_index}") : ""
38
- embedded? ? "#{_parent._position}#{"." unless _parent._position.blank?}#{@association_name}#{locator}" : ""
38
+ embedded? ? "#{_parent._position}#{"." unless _parent._position.blank?}#{metadata.name.to_s}#{locator}" : ""
39
39
  end
40
40
 
41
41
  # Get the removal modifier for the document. Will be nil on root
@@ -8,116 +8,121 @@ require "mongoid/persistence/remove_embedded"
8
8
  require "mongoid/persistence/update"
9
9
 
10
10
  module Mongoid #:nodoc:
11
+
11
12
  # The persistence module is a mixin to provide database accessor methods for
12
13
  # the document. These correspond to the appropriate accessors on a
13
- # +Mongo::Collection+ and retain the same DSL.
14
- #
15
- # Examples:
14
+ # mongo collection and retain the same DSL.
16
15
  #
17
- # <tt>document.insert</tt>
18
- # <tt>document.update</tt>
19
- # <tt>document.upsert</tt>
16
+ # @example Sample persistence operations.
17
+ # document.insert
18
+ # document.update
19
+ # document.upsert
20
20
  module Persistence
21
21
  extend ActiveSupport::Concern
22
22
 
23
- # Remove the +Document+ from the datbase with callbacks.
23
+ # Remove the document from the datbase with callbacks.
24
+ #
25
+ # @example Destroy a document.
26
+ # document.destroy
24
27
  #
25
- # Example:
28
+ # @param [ Hash ] options Options to pass to destroy.
26
29
  #
27
- # <tt>document.destroy</tt>
30
+ # @return [ true, false ] True if successful, false if not.
28
31
  def destroy(options = {})
29
- run_callbacks(:destroy) { _remove(options) }
32
+ run_callbacks(:destroy) { remove(options) }
30
33
  end
31
34
 
32
- # Insert a new +Document+ into the database. Will return the document
35
+ # Insert a new document into the database. Will return the document
33
36
  # itself whether or not the save was successful.
34
37
  #
35
- # Example:
38
+ # @example Insert a document.
39
+ # document.insert
36
40
  #
37
- # <tt>document.insert</tt>
41
+ # @param [ Hash ] options Options to pass to insert.
42
+ #
43
+ # @return [ Document ] The persisted document.
38
44
  def insert(options = {})
39
45
  Insert.new(self, options).persist
40
46
  end
41
47
 
42
- # Remove the +Document+ from the datbase.
48
+ # Remove the document from the datbase.
43
49
  #
44
- # Example:
50
+ # @example Remove the document.
51
+ # document.remove
45
52
  #
46
- # <tt>document._remove</tt>
53
+ # @param [ Hash ] options Options to pass to remove.
47
54
  #
48
- # TODO: Will get rid of other #remove once observable pattern killed.
49
- def _remove(options = {})
55
+ # @return [ TrueClass ] True.
56
+ def remove(options = {})
50
57
  if Remove.new(self, options).persist
51
58
  self.destroyed = true
52
- cascading_remove!
59
+ cascade!
53
60
  end; true
54
61
  end
55
-
56
- alias :delete :_remove
62
+ alias :delete :remove
57
63
 
58
64
  # Save the document - will perform an insert if the document is new, and
59
- # update if not. If a validation error occurs a
60
- # Mongoid::Errors::Validations error will get raised.
61
- #
62
- # Example:
65
+ # update if not. If a validation error occurs an error will get raised.
63
66
  #
64
- # <tt>document.save!</tt>
67
+ # @example Save the document.
68
+ # document.save!
65
69
  #
66
- # Returns:
70
+ # @param [ Hash ] options Options to pass to the save.
67
71
  #
68
- # +true+ if validation passed, will raise error otherwise.
72
+ # @return [ true, false ] True if validation passed.
69
73
  def save!(options = {})
70
74
  self.class.fail_validate!(self) unless upsert; true
71
75
  end
72
76
 
73
- # Update the +Document+ in the datbase.
77
+ # Update the document in the datbase.
74
78
  #
75
- # Example:
79
+ # @example Update an existing document.
80
+ # document.update
76
81
  #
77
- # <tt>document.update</tt>
82
+ # @param [ Hash ] options Options to pass to update.
83
+ #
84
+ # @return [ true, false ] True if succeeded, false if not.
78
85
  def update(options = {})
79
86
  Update.new(self, options).persist
80
87
  end
81
88
 
82
- # Update the +Document+ attributes in the datbase.
83
- #
84
- # Example:
89
+ # Update the document attributes in the datbase.
85
90
  #
86
- # <tt>document.update_attributes(:title => "Sir")</tt>
91
+ # @example Update the document's attributes
92
+ # document.update_attributes(:title => "Sir")
87
93
  #
88
- # Returns:
94
+ # @param [ Hash ] attributes The attributes to update.
89
95
  #
90
- # +true+ if validation passed, +false+ if not.
96
+ # @return [ true, false ] True if validation passed, false if not.
91
97
  def update_attributes(attributes = {})
92
98
  write_attributes(attributes); update
93
99
  end
94
100
 
95
- # Update the +Document+ attributes in the datbase.
96
- #
97
- # Example:
101
+ # Update the document attributes in the database and raise an error if
102
+ # validation failed.
98
103
  #
99
- # <tt>document.update_attributes(:title => "Sir")</tt>
104
+ # @example Update the document's attributes.
105
+ # document.update_attributes(:title => "Sir")
100
106
  #
101
- # Returns:
107
+ # @param [ Hash ] attributes The attributes to update.
102
108
  #
103
- # +true+ if validation passed, raises an error if not
109
+ # @return [ true, false ] True if validation passed.
104
110
  def update_attributes!(attributes = {})
105
111
  write_attributes(attributes)
106
- result = update
107
- self.class.fail_validate!(self) unless result
108
- result
112
+ update.tap do |result|
113
+ self.class.fail_validate!(self) unless result
114
+ end
109
115
  end
110
116
 
111
117
  # Upsert the document - will perform an insert if the document is new, and
112
118
  # update if not.
113
119
  #
114
- # Example:
115
- #
116
- # <tt>document.upsert</tt>
120
+ # @example Upsert the document.
121
+ # document.upsert
117
122
  #
118
- # Returns:
123
+ # @param [ Hash ] options Options to pass to the upsert.
119
124
  #
120
- # A +Boolean+ for updates.
125
+ # @return [ true, false ] True is success, false if not.
121
126
  def upsert(options = {})
122
127
  if new_record?
123
128
  insert(options).persisted?
@@ -125,53 +130,35 @@ module Mongoid #:nodoc:
125
130
  update(options)
126
131
  end
127
132
  end
128
-
129
- # Save is aliased so that users familiar with active record can have some
130
- # semblance of a familiar API.
131
- #
132
- # Example:
133
- #
134
- # <tt>document.save</tt>
135
133
  alias :save :upsert
136
134
 
137
- protected
138
-
139
- # Perform all cascading deletes or destroys.
140
- def cascading_remove!
141
- cascades.each do |name, option|
142
- association = send(name)
143
- if association
144
- documents = association.target.to_a
145
- documents.each { |doc| doc.send(option) }
146
- end
147
- end
148
- end
149
-
150
135
  module ClassMethods #:nodoc:
151
136
 
152
- # Create a new +Document+. This will instantiate a new document and
137
+ # Create a new document. This will instantiate a new document and
153
138
  # insert it in a single call. Will always return the document
154
139
  # whether save passed or not.
155
140
  #
156
- # Example:
141
+ # @example Create a new document.
142
+ # Person.create(:title => "Mr")
157
143
  #
158
- # <tt>Person.create(:title => "Mr")</tt>
144
+ # @param [ Hash ] attributes The attributes to create with.
159
145
  #
160
- # Returns: the +Document+.
146
+ # @return [ Document ] The newly created document.
161
147
  def create(attributes = {})
162
- new(attributes).tap(&:insert)
148
+ new(attributes).tap(&:save)
163
149
  end
164
150
 
165
- # Create a new +Document+. This will instantiate a new document and
151
+ # Create a new document. This will instantiate a new document and
166
152
  # insert it in a single call. Will always return the document
167
153
  # whether save passed or not, and if validation fails an error will be
168
154
  # raise.
169
155
  #
170
- # Example:
156
+ # @example Create a new document.
157
+ # Person.create!(:title => "Mr")
171
158
  #
172
- # <tt>Person.create!(:title => "Mr")</tt>
159
+ # @param [ Hash ] attributes The attributes to create with.
173
160
  #
174
- # Returns: the +Document+.
161
+ # @return [ Document ] The newly created document.
175
162
  def create!(attributes = {})
176
163
  document = new(attributes)
177
164
  fail_validate!(document) if document.insert.errors.any?
@@ -182,12 +169,15 @@ module Mongoid #:nodoc:
182
169
  # are passed, the entire collection will be dropped for performance
183
170
  # benefits. Does not fire any callbacks.
184
171
  #
185
- # Example:
172
+ # @example Delete matching documents from the collection.
173
+ # Person.delete_all(:conditions => { :title => "Sir" })
174
+ #
175
+ # @example Delete all documents from the collection.
176
+ # Person.delete_all
186
177
  #
187
- # <tt>Person.delete_all(:conditions => { :title => "Sir" })</tt>
188
- # <tt>Person.delete_all</tt>
178
+ # @param [ Hash ] conditions Optional conditions to delete by.
189
179
  #
190
- # Returns: true or raises an error.
180
+ # @return [ Integer ] The number of documents deleted.
191
181
  def delete_all(conditions = {})
192
182
  RemoveAll.new(
193
183
  self,
@@ -200,19 +190,28 @@ module Mongoid #:nodoc:
200
190
  # are passed, the entire collection will be dropped for performance
201
191
  # benefits. Fires the destroy callbacks if conditions were passed.
202
192
  #
203
- # Example:
193
+ # @example Destroy matching documents from the collection.
194
+ # Person.destroy_all(:conditions => { :title => "Sir" })
195
+ #
196
+ # @example Destroy all documents from the collection.
197
+ # Person.destroy_all
204
198
  #
205
- # <tt>Person.destroy_all(:conditions => { :title => "Sir" })</tt>
206
- # <tt>Person.destroy_all</tt>
199
+ # @param [ Hash ] conditions Optional conditions to destroy by.
207
200
  #
208
- # Returns: true or raises an error.
201
+ # @return [ Integer ] The number of documents destroyed.
209
202
  def destroy_all(conditions = {})
210
203
  documents = all(conditions)
211
- count = documents.count
212
- documents.each { |doc| doc.destroy }; count
204
+ documents.count.tap do
205
+ documents.each { |doc| doc.destroy }
206
+ end
213
207
  end
214
208
 
215
209
  # Raise an error if validation failed.
210
+ #
211
+ # @example Raise the validation error.
212
+ # Person.fail_validate!(person)
213
+ #
214
+ # @param [ Document ] document The document to fail.
216
215
  def fail_validate!(document)
217
216
  raise Errors::Validations.new(document)
218
217
  end