mongoid-pre 2.0.0.beta1

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.
Files changed (246) hide show
  1. data/.gitignore +6 -0
  2. data/.watchr +24 -0
  3. data/MIT_LICENSE +20 -0
  4. data/README.rdoc +49 -0
  5. data/Rakefile +52 -0
  6. data/VERSION +1 -0
  7. data/caliper.yml +4 -0
  8. data/lib/mongoid.rb +135 -0
  9. data/lib/mongoid/associations.rb +263 -0
  10. data/lib/mongoid/associations/belongs_to_related.rb +59 -0
  11. data/lib/mongoid/associations/embedded_in.rb +64 -0
  12. data/lib/mongoid/associations/embeds_many.rb +193 -0
  13. data/lib/mongoid/associations/embeds_one.rb +95 -0
  14. data/lib/mongoid/associations/has_many_related.rb +133 -0
  15. data/lib/mongoid/associations/has_one_related.rb +81 -0
  16. data/lib/mongoid/associations/meta_data.rb +28 -0
  17. data/lib/mongoid/associations/options.rb +52 -0
  18. data/lib/mongoid/associations/proxy.rb +31 -0
  19. data/lib/mongoid/attributes.rb +185 -0
  20. data/lib/mongoid/callbacks.rb +18 -0
  21. data/lib/mongoid/collection.rb +119 -0
  22. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  23. data/lib/mongoid/collections/master.rb +28 -0
  24. data/lib/mongoid/collections/mimic.rb +46 -0
  25. data/lib/mongoid/collections/operations.rb +41 -0
  26. data/lib/mongoid/collections/slaves.rb +44 -0
  27. data/lib/mongoid/commands.rb +161 -0
  28. data/lib/mongoid/commands/create.rb +19 -0
  29. data/lib/mongoid/commands/delete.rb +16 -0
  30. data/lib/mongoid/commands/delete_all.rb +25 -0
  31. data/lib/mongoid/commands/deletion.rb +18 -0
  32. data/lib/mongoid/commands/destroy.rb +17 -0
  33. data/lib/mongoid/commands/destroy_all.rb +25 -0
  34. data/lib/mongoid/commands/save.rb +30 -0
  35. data/lib/mongoid/components.rb +31 -0
  36. data/lib/mongoid/config.rb +86 -0
  37. data/lib/mongoid/contexts.rb +25 -0
  38. data/lib/mongoid/contexts/enumerable.rb +151 -0
  39. data/lib/mongoid/contexts/ids.rb +25 -0
  40. data/lib/mongoid/contexts/mongo.rb +285 -0
  41. data/lib/mongoid/contexts/paging.rb +42 -0
  42. data/lib/mongoid/criteria.rb +239 -0
  43. data/lib/mongoid/criterion/complex.rb +21 -0
  44. data/lib/mongoid/criterion/exclusion.rb +65 -0
  45. data/lib/mongoid/criterion/inclusion.rb +93 -0
  46. data/lib/mongoid/criterion/optional.rb +136 -0
  47. data/lib/mongoid/cursor.rb +82 -0
  48. data/lib/mongoid/deprecation.rb +22 -0
  49. data/lib/mongoid/dirty.rb +203 -0
  50. data/lib/mongoid/document.rb +306 -0
  51. data/lib/mongoid/errors.rb +77 -0
  52. data/lib/mongoid/extensions.rb +99 -0
  53. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  54. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  55. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  56. data/lib/mongoid/extensions/array/conversions.rb +27 -0
  57. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  58. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  59. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  60. data/lib/mongoid/extensions/boolean/conversions.rb +16 -0
  61. data/lib/mongoid/extensions/date/conversions.rb +15 -0
  62. data/lib/mongoid/extensions/datetime/conversions.rb +17 -0
  63. data/lib/mongoid/extensions/float/conversions.rb +16 -0
  64. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  65. data/lib/mongoid/extensions/hash/assimilation.rb +30 -0
  66. data/lib/mongoid/extensions/hash/conversions.rb +15 -0
  67. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  68. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  69. data/lib/mongoid/extensions/integer/conversions.rb +16 -0
  70. data/lib/mongoid/extensions/nil/assimilation.rb +13 -0
  71. data/lib/mongoid/extensions/object/conversions.rb +27 -0
  72. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  73. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  74. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  75. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  76. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  77. data/lib/mongoid/extensions/time/conversions.rb +18 -0
  78. data/lib/mongoid/extras.rb +61 -0
  79. data/lib/mongoid/factory.rb +19 -0
  80. data/lib/mongoid/field.rb +52 -0
  81. data/lib/mongoid/fields.rb +62 -0
  82. data/lib/mongoid/finders.rb +136 -0
  83. data/lib/mongoid/identity.rb +39 -0
  84. data/lib/mongoid/indexes.rb +27 -0
  85. data/lib/mongoid/javascript.rb +21 -0
  86. data/lib/mongoid/javascript/functions.yml +37 -0
  87. data/lib/mongoid/matchers.rb +36 -0
  88. data/lib/mongoid/matchers/all.rb +11 -0
  89. data/lib/mongoid/matchers/default.rb +26 -0
  90. data/lib/mongoid/matchers/exists.rb +13 -0
  91. data/lib/mongoid/matchers/gt.rb +11 -0
  92. data/lib/mongoid/matchers/gte.rb +11 -0
  93. data/lib/mongoid/matchers/in.rb +11 -0
  94. data/lib/mongoid/matchers/lt.rb +11 -0
  95. data/lib/mongoid/matchers/lte.rb +11 -0
  96. data/lib/mongoid/matchers/ne.rb +11 -0
  97. data/lib/mongoid/matchers/nin.rb +11 -0
  98. data/lib/mongoid/matchers/size.rb +11 -0
  99. data/lib/mongoid/memoization.rb +27 -0
  100. data/lib/mongoid/named_scope.rb +42 -0
  101. data/lib/mongoid/observable.rb +30 -0
  102. data/lib/mongoid/paths.rb +54 -0
  103. data/lib/mongoid/persistence.rb +27 -0
  104. data/lib/mongoid/persistence/command.rb +20 -0
  105. data/lib/mongoid/persistence/insert.rb +71 -0
  106. data/lib/mongoid/persistence/update.rb +78 -0
  107. data/lib/mongoid/scope.rb +75 -0
  108. data/lib/mongoid/state.rb +32 -0
  109. data/lib/mongoid/timestamps.rb +27 -0
  110. data/lib/mongoid/validations.rb +51 -0
  111. data/lib/mongoid/validations/associated.rb +32 -0
  112. data/lib/mongoid/validations/locale/en.yml +4 -0
  113. data/lib/mongoid/validations/uniqueness.rb +22 -0
  114. data/lib/mongoid/versioning.rb +26 -0
  115. data/mongoid.gemspec +413 -0
  116. data/perf/benchmark.rb +77 -0
  117. data/spec/integration/mongoid/associations_spec.rb +340 -0
  118. data/spec/integration/mongoid/attributes_spec.rb +22 -0
  119. data/spec/integration/mongoid/commands_spec.rb +230 -0
  120. data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
  121. data/spec/integration/mongoid/criteria_spec.rb +272 -0
  122. data/spec/integration/mongoid/dirty_spec.rb +70 -0
  123. data/spec/integration/mongoid/document_spec.rb +650 -0
  124. data/spec/integration/mongoid/extensions_spec.rb +22 -0
  125. data/spec/integration/mongoid/finders_spec.rb +119 -0
  126. data/spec/integration/mongoid/inheritance_spec.rb +137 -0
  127. data/spec/integration/mongoid/named_scope_spec.rb +46 -0
  128. data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
  129. data/spec/models/address.rb +39 -0
  130. data/spec/models/animal.rb +6 -0
  131. data/spec/models/callbacks.rb +18 -0
  132. data/spec/models/comment.rb +8 -0
  133. data/spec/models/country_code.rb +6 -0
  134. data/spec/models/employer.rb +5 -0
  135. data/spec/models/game.rb +7 -0
  136. data/spec/models/inheritance.rb +56 -0
  137. data/spec/models/location.rb +5 -0
  138. data/spec/models/mixed_drink.rb +4 -0
  139. data/spec/models/name.rb +13 -0
  140. data/spec/models/namespacing.rb +11 -0
  141. data/spec/models/patient.rb +6 -0
  142. data/spec/models/person.rb +99 -0
  143. data/spec/models/pet.rb +7 -0
  144. data/spec/models/pet_owner.rb +6 -0
  145. data/spec/models/phone.rb +7 -0
  146. data/spec/models/post.rb +15 -0
  147. data/spec/models/translation.rb +5 -0
  148. data/spec/models/vet_visit.rb +5 -0
  149. data/spec/spec.opts +3 -0
  150. data/spec/spec_helper.rb +31 -0
  151. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +145 -0
  152. data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
  153. data/spec/unit/mongoid/associations/embeds_many_spec.rb +516 -0
  154. data/spec/unit/mongoid/associations/embeds_one_spec.rb +282 -0
  155. data/spec/unit/mongoid/associations/has_many_related_spec.rb +418 -0
  156. data/spec/unit/mongoid/associations/has_one_related_spec.rb +179 -0
  157. data/spec/unit/mongoid/associations/meta_data_spec.rb +88 -0
  158. data/spec/unit/mongoid/associations/options_spec.rb +192 -0
  159. data/spec/unit/mongoid/associations_spec.rb +595 -0
  160. data/spec/unit/mongoid/attributes_spec.rb +507 -0
  161. data/spec/unit/mongoid/callbacks_spec.rb +55 -0
  162. data/spec/unit/mongoid/collection_spec.rb +187 -0
  163. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  164. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  165. data/spec/unit/mongoid/collections/mimic_spec.rb +43 -0
  166. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  167. data/spec/unit/mongoid/commands/create_spec.rb +31 -0
  168. data/spec/unit/mongoid/commands/delete_all_spec.rb +59 -0
  169. data/spec/unit/mongoid/commands/delete_spec.rb +38 -0
  170. data/spec/unit/mongoid/commands/destroy_all_spec.rb +21 -0
  171. data/spec/unit/mongoid/commands/destroy_spec.rb +51 -0
  172. data/spec/unit/mongoid/commands/save_spec.rb +107 -0
  173. data/spec/unit/mongoid/commands_spec.rb +270 -0
  174. data/spec/unit/mongoid/config_spec.rb +176 -0
  175. data/spec/unit/mongoid/contexts/enumerable_spec.rb +421 -0
  176. data/spec/unit/mongoid/contexts/mongo_spec.rb +682 -0
  177. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  178. data/spec/unit/mongoid/criteria_spec.rb +824 -0
  179. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  180. data/spec/unit/mongoid/criterion/exclusion_spec.rb +91 -0
  181. data/spec/unit/mongoid/criterion/inclusion_spec.rb +219 -0
  182. data/spec/unit/mongoid/criterion/optional_spec.rb +319 -0
  183. data/spec/unit/mongoid/cursor_spec.rb +74 -0
  184. data/spec/unit/mongoid/deprecation_spec.rb +24 -0
  185. data/spec/unit/mongoid/dirty_spec.rb +286 -0
  186. data/spec/unit/mongoid/document_spec.rb +818 -0
  187. data/spec/unit/mongoid/errors_spec.rb +103 -0
  188. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  189. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  190. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +35 -0
  191. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  192. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +22 -0
  193. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
  194. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  195. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +102 -0
  196. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +67 -0
  197. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  198. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  199. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +46 -0
  200. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +21 -0
  201. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  202. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  203. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  204. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +24 -0
  205. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +57 -0
  206. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  207. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +17 -0
  208. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  209. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +91 -0
  210. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +70 -0
  211. data/spec/unit/mongoid/extras_spec.rb +102 -0
  212. data/spec/unit/mongoid/factory_spec.rb +31 -0
  213. data/spec/unit/mongoid/field_spec.rb +143 -0
  214. data/spec/unit/mongoid/fields_spec.rb +181 -0
  215. data/spec/unit/mongoid/finders_spec.rb +404 -0
  216. data/spec/unit/mongoid/identity_spec.rb +109 -0
  217. data/spec/unit/mongoid/indexes_spec.rb +93 -0
  218. data/spec/unit/mongoid/javascript_spec.rb +48 -0
  219. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  220. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  221. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  222. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  223. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  224. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  225. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  226. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  227. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  228. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  229. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  230. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  231. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  232. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  233. data/spec/unit/mongoid/observable_spec.rb +46 -0
  234. data/spec/unit/mongoid/paths_spec.rb +124 -0
  235. data/spec/unit/mongoid/persistence/insert_spec.rb +175 -0
  236. data/spec/unit/mongoid/persistence/update_spec.rb +148 -0
  237. data/spec/unit/mongoid/persistence_spec.rb +40 -0
  238. data/spec/unit/mongoid/scope_spec.rb +240 -0
  239. data/spec/unit/mongoid/state_spec.rb +83 -0
  240. data/spec/unit/mongoid/timestamps_spec.rb +25 -0
  241. data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
  242. data/spec/unit/mongoid/validations/uniqueness_spec.rb +47 -0
  243. data/spec/unit/mongoid/validations_spec.rb +190 -0
  244. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  245. data/spec/unit/mongoid_spec.rb +46 -0
  246. metadata +476 -0
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ class CyclicIterator
5
+
6
+ attr_reader :counter
7
+
8
+ # Performs iteration over an array, if the array gets to the end then loop
9
+ # back to the first.
10
+ #
11
+ # Example:
12
+ #
13
+ # <tt>CyclicIterator.new([ first, second ])</tt>
14
+ def initialize(array)
15
+ @array, @counter = array, -1
16
+ end
17
+
18
+ # Get the next element in the array. If the element is the last in the
19
+ # array then return the first.
20
+ #
21
+ # Example:
22
+ #
23
+ # <tt>iterator.next</tt>
24
+ #
25
+ # Returns:
26
+ #
27
+ # The next element in the array.
28
+ def next
29
+ (@counter == @array.size - 1) ? @counter = 0 : @counter = @counter + 1
30
+ @array[@counter]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ class Master
5
+ include Mimic
6
+
7
+ attr_reader :collection
8
+
9
+ # All read and write operations should delegate to the master connection.
10
+ # These operations mimic the methods on a Mongo:Collection.
11
+ #
12
+ # Example:
13
+ #
14
+ # <tt>collection.save({ :name => "Al" })</tt>
15
+ proxy(:collection, Operations::ALL)
16
+
17
+ # Create the new database writer. Will create a collection from the
18
+ # master database.
19
+ #
20
+ # Example:
21
+ #
22
+ # <tt>Master.new(master, "mongoid_people")</tt>
23
+ def initialize(master, name)
24
+ @collection = master.collection(name)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ module Mimic #:nodoc:
5
+ def self.included(base)
6
+ base.class_eval do
7
+ include InstanceMethods
8
+ extend ClassMethods
9
+ end
10
+ end
11
+
12
+ module InstanceMethods #:nodoc:
13
+ # Retry the supplied operation until the reconnect time has expired,
14
+ # defined in the mongoid Config module.
15
+ #
16
+ # Example:
17
+ #
18
+ # <tt>master.attempt(operation)</tt>
19
+ def attempt(operation, start)
20
+ begin
21
+ elapsed = (Time.now - start)
22
+ operation.call
23
+ rescue Mongo::ConnectionFailure => error
24
+ (elapsed < Mongoid.reconnect_time) ? retry : (raise error)
25
+ end
26
+ end
27
+ end
28
+
29
+ module ClassMethods #:nodoc:
30
+ # Proxy all the supplied operations to the internal collection or target.
31
+ #
32
+ # Example:
33
+ #
34
+ # <tt>proxy Operations::ALL, :collection</tt>
35
+ def proxy(target, operations)
36
+ operations.each do |name|
37
+ define_method(name) do |*args|
38
+ operation = lambda { send(target).send(name, *args) }
39
+ attempt(operation, Time.now)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ module Operations #:nodoc:
5
+ # Constant definining all the read operations available for a
6
+ # Mongo:Collection. This is used in delegation.
7
+ READ = [
8
+ :[],
9
+ :db,
10
+ :count,
11
+ :distinct,
12
+ :find,
13
+ :find_one,
14
+ :group,
15
+ :index_information,
16
+ :map_reduce,
17
+ :mapreduce,
18
+ :options
19
+ ]
20
+
21
+ # Constant definining all the write operations available for a
22
+ # Mongo:Collection. This is used in delegation.
23
+ WRITE = [
24
+ :<<,
25
+ :create_index,
26
+ :drop,
27
+ :drop_index,
28
+ :drop_indexes,
29
+ :insert,
30
+ :remove,
31
+ :rename,
32
+ :save,
33
+ :update
34
+ ]
35
+
36
+ # Convenience constant for getting back all collection operations.
37
+ ALL = (READ + WRITE)
38
+ PROXIED = ALL - [ :find, :find_one, :map_reduce, :mapreduce ]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Collections #:nodoc:
4
+ class Slaves
5
+ include Mimic
6
+
7
+ attr_reader :iterator
8
+
9
+ # All read operations should delegate to the slave connections.
10
+ # These operations mimic the methods on a Mongo:Collection.
11
+ #
12
+ # Example:
13
+ #
14
+ # <tt>collection.save({ :name => "Al" })</tt>
15
+ proxy(:collection, Operations::READ)
16
+
17
+ # Is the collection of slaves empty or not?
18
+ #
19
+ # Return:
20
+ #
21
+ # True is the iterator is not set, false if not.
22
+ def empty?
23
+ @iterator.nil?
24
+ end
25
+
26
+ # Create the new database reader. Will create a collection from the
27
+ # slave databases and cycle through them on each read.
28
+ #
29
+ # Example:
30
+ #
31
+ # <tt>Reader.new(slaves, "mongoid_people")</tt>
32
+ def initialize(slaves, name)
33
+ unless slaves.blank?
34
+ @iterator = CyclicIterator.new(slaves.collect { |db| db.collection(name) })
35
+ end
36
+ end
37
+
38
+ protected
39
+ def collection
40
+ @iterator.next
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,161 @@
1
+ # encoding: utf-8
2
+ require "mongoid/commands/create"
3
+ require "mongoid/commands/deletion"
4
+ require "mongoid/commands/delete"
5
+ require "mongoid/commands/delete_all"
6
+ require "mongoid/commands/destroy"
7
+ require "mongoid/commands/destroy_all"
8
+ require "mongoid/commands/save"
9
+
10
+ module Mongoid #:nodoc:
11
+
12
+ # This module is included in the +Document+ to provide all the persistence
13
+ # methods required on the +Document+ object and class.
14
+ module Commands
15
+ extend ActiveSupport::Concern
16
+ module InstanceMethods
17
+
18
+ # Delete the +Document+ from the database. This method is an optimized
19
+ # delete that does not force any callbacks.
20
+ #
21
+ # Example:
22
+ #
23
+ # <tt>document.delete</tt>
24
+ #
25
+ # Returns: true unless an error occurs.
26
+ def delete
27
+ Delete.execute(self)
28
+ end
29
+
30
+ # Destroy the +Document+. This will delete the document from the database
31
+ # and run the before and after destroy callbacks.
32
+ #
33
+ # Example:
34
+ #
35
+ # <tt>document.destroy</tt>
36
+ #
37
+ # Returns: true unless an error occurs.
38
+ def destroy
39
+ Destroy.execute(self)
40
+ end
41
+
42
+ # Save the +Document+. If the document is new, then the before and after
43
+ # create callbacks will get executed as well as the save callbacks.
44
+ # Otherwise only the save callbacks will run.
45
+ #
46
+ # Options:
47
+ #
48
+ # validate: Run validations or not. Defaults to true.
49
+ #
50
+ # Example:
51
+ #
52
+ # <tt>document.save # save with validations</tt>
53
+ # <tt>document.save(false) # save without validations</tt>
54
+ #
55
+ # Returns: true if validation passes, false if not.
56
+ def save(validate = true)
57
+ save = lambda { Save.execute(self, validate) }
58
+ new_record? ? run_callbacks(:create, &save) : save.call
59
+ end
60
+
61
+ # Save the +Document+, dangerously. Before and after save callbacks will
62
+ # get run. If validation fails an error will get raised.
63
+ #
64
+ # Example:
65
+ #
66
+ # <tt>document.save!</tt>
67
+ #
68
+ # Returns: true if validation passes
69
+ def save!
70
+ save(true) || (raise Errors::Validations.new(self.errors))
71
+ end
72
+
73
+ # Update the document attributes and persist the document to the
74
+ # database. Will delegate to save with all callbacks.
75
+ #
76
+ # Example:
77
+ #
78
+ # <tt>document.update_attributes(:title => "Test")</tt>
79
+ def update_attributes(attrs = {})
80
+ set_attributes(attrs); save
81
+ end
82
+
83
+ # Update the document attributes and persist the document to the
84
+ # database. Will delegate to save!
85
+ #
86
+ # Example:
87
+ #
88
+ # <tt>document.update_attributes!(:title => "Test")</tt>
89
+ def update_attributes!(attrs = {})
90
+ set_attributes(attrs); save!
91
+ end
92
+
93
+ protected
94
+ def set_attributes(attrs = {})
95
+ run_callbacks(:update) { write_attributes(attrs) }
96
+ end
97
+
98
+ end
99
+
100
+ module ClassMethods
101
+
102
+ # Create a new +Document+. This will instantiate a new document and save
103
+ # it in a single call. Will always return the document whether save
104
+ # passed or not.
105
+ #
106
+ # Example:
107
+ #
108
+ # <tt>Person.create(:title => "Mr")</tt>
109
+ #
110
+ # Returns: the +Document+.
111
+ def create(attributes = {})
112
+ document = new(attributes)
113
+ Create.execute(document)
114
+ document
115
+ end
116
+
117
+ # Create a new +Document+. This will instantiate a new document and save
118
+ # it in a single call. Will always return the document whether save
119
+ # passed or not. Will raise an error if validation fails.
120
+ #
121
+ # Example:
122
+ #
123
+ # <tt>Person.create!(:title => "Mr")</tt>
124
+ #
125
+ # Returns: the +Document+.
126
+ def create!(attributes = {})
127
+ document = Create.execute(new(attributes), true)
128
+ raise Errors::Validations.new(document.errors) unless document.errors.empty?
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
+ DeleteAll.execute(self, conditions)
144
+ end
145
+
146
+ # Delete all documents given the supplied conditions. If no conditions
147
+ # are passed, the entire collection will be dropped for performance
148
+ # benefits. Fires the destroy callbacks if conditions were passed.
149
+ #
150
+ # Example:
151
+ #
152
+ # <tt>Person.destroy_all(:conditions => { :title => "Sir" })</tt>
153
+ # <tt>Person.destroy_all</tt>
154
+ #
155
+ # Returns: true or raises an error.
156
+ def destroy_all(conditions = {})
157
+ DestroyAll.execute(self, conditions)
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Commands
4
+ class Create
5
+ # Performs a create of the supplied Document, with the necessary
6
+ # callbacks. It then delegates to the Save command.
7
+ #
8
+ # Options:
9
+ #
10
+ # doc: A new +Document+ that is going to be persisted.
11
+ #
12
+ # Returns: +Document+.
13
+ def self.execute(doc, validate = true)
14
+ doc.run_callbacks(:create) { Save.execute(doc, validate) }
15
+ doc
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Commands
4
+ class Delete
5
+ extend Deletion
6
+ # Performs a delete of the supplied +Document+ without any callbacks.
7
+ #
8
+ # Options:
9
+ #
10
+ # doc: A new +Document+ that is going to be deleted.
11
+ def self.execute(doc)
12
+ doc.destroyed = true if delete(doc)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Commands
4
+ class DeleteAll
5
+ # Performs a delete of the all the +Documents+ that match the criteria
6
+ # supplied.
7
+ #
8
+ # Options:
9
+ #
10
+ # params: A set of conditions to find the +Documents+ by.
11
+ # klass: The class of the +Document+ to execute the find on.
12
+ #
13
+ # Example:
14
+ #
15
+ # <tt>DeleteAll.execute(Person, :conditions => { :field => "value" })</tt>
16
+ def self.execute(klass, params = {})
17
+ safe = Mongoid.persist_in_safe_mode
18
+ collection = klass.collection
19
+ selector = (params[:conditions] || {}).merge(:_type => klass.name)
20
+ matching = collection.find(selector).count
21
+ collection.remove(selector, :safe => safe) ? matching : 0
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Commands #:nodoc
4
+ module Deletion #:nodoc
5
+ # If the +Document+ has a parent, delete it from the parent's attributes,
6
+ # otherwise delete it from it's collection.
7
+ def delete(doc)
8
+ parent = doc._parent
9
+ if parent
10
+ parent.remove(doc)
11
+ parent.save
12
+ else
13
+ doc.collection.remove(:_id => doc.id)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Commands
4
+ class Destroy
5
+ extend Deletion
6
+ # Performs a destroy of the supplied +Document+, with the necessary
7
+ # callbacks. It then deletes the record from the collection.
8
+ #
9
+ # Options:
10
+ #
11
+ # doc: A new +Document+ that is going to be destroyed.
12
+ def self.execute(doc)
13
+ doc.run_callbacks(:destroy) { doc.destroyed = true if delete(doc) }
14
+ end
15
+ end
16
+ end
17
+ end