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,128 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Associations #:nodoc:
4
- # Represents an relational one-to-many association with an object in a
5
- # separate collection or database, stored as an array of ids on the parent
6
- # document.
7
- class ReferencesManyAsArray < ReferencesMany
8
-
9
- # Append a document to this association. This will also set the appended
10
- # document's id on the inverse association as well.
11
- #
12
- # Example:
13
- #
14
- # <tt>person.preferences << Preference.new(:name => "VGA")</tt>
15
- def <<(*objects)
16
- @target = @target.entries
17
- objects.flatten.each do |object|
18
- # First set the documents id on the parent array of ids.
19
- @parent.send(@foreign_key) << object.id
20
- # Then we need to set the parent's id on the documents array of ids
21
- # to get the inverse side of the association as well. Note, need a
22
- # clean way to handle this with new documents - we want to set the
23
- # actual objects as well, but dont want to get in an infinite loop
24
- # while doing so.
25
- if inverse?
26
- reverse_key = reverse_key(object)
27
- case inverse_of(object).macro
28
- when :references_many
29
- object.send(reverse_key) << @parent.id
30
- when :referenced_in
31
- object.send("#{reverse_key}=", @parent.id)
32
- end
33
- end
34
- @target << object
35
- object.save unless @parent.new_record?
36
- end
37
- @parent.save unless @parent.new_record?
38
- end
39
-
40
- alias :concat :<<
41
- alias :push :<<
42
-
43
- # Builds a new Document and adds it to the association collection. The
44
- # document created will be of the same class as the others in the
45
- # association, and the attributes will be passed into the constructor.
46
- #
47
- # Returns the newly created object.
48
- def build(attributes = {},type=nil)
49
- load_target
50
- document = (type || @klass).instantiate(attributes)
51
- push(document); document
52
- end
53
-
54
- # Destroy all the associated objects.
55
- #
56
- # Example:
57
- #
58
- # <tt>person.posts.destroy_all</tt>
59
- #
60
- # Returns:
61
- #
62
- # The number of objects destroyed.
63
- def destroy_all(conditions = {})
64
- removed = query.call.destroy_all(:conditions => conditions)
65
- reset; removed
66
- end
67
-
68
- # Delete all the associated objects.
69
- #
70
- # Example:
71
- #
72
- # <tt>person.posts.delete_all</tt>
73
- #
74
- # Returns:
75
- #
76
- # The number of objects deleted.
77
- def delete_all(conditions = {})
78
- removed = query.call.delete_all(:conditions => conditions)
79
- reset; removed
80
- end
81
-
82
- protected
83
-
84
- # Find the inverse key for the supplied document.
85
- def reverse_key(document)
86
- inverse_of(document).options.foreign_key
87
- end
88
-
89
- # Returns +true+ if there is an inverse association on the referenced
90
- # model.
91
- def inverse?
92
- !!@options.inverse_of
93
- end
94
-
95
- # Returns the association on +document+ which is the inverse of this
96
- # association.
97
- def inverse_of(document)
98
- document.class.associations[@options.inverse_of.to_s]
99
- end
100
-
101
- # The default query used for retrieving the documents from the database.
102
- def query
103
- @query ||= lambda { @klass.any_in(:_id => @parent.send(@foreign_key)) }
104
- end
105
-
106
- class << self
107
- # Perform an update of the relationship of the parent and child. This
108
- # will assimilate the child +Document+ into the parent's object graph.
109
- #
110
- # Options:
111
- #
112
- # related: The related object
113
- # parent: The parent +Document+ to update.
114
- # options: The association +Options+
115
- #
116
- # Example:
117
- #
118
- # <tt>ReferencesManyAsArray.update(preferences, person, options)</tt>
119
- def update(target, document, options)
120
- target.each do |child|
121
- document.send(options.name) << child
122
- end
123
- instantiate(document, options, target)
124
- end
125
- end
126
- end
127
- end
128
- end
@@ -1,104 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Associations #:nodoc:
4
- # Represents an relational one-to-one association with an object in a
5
- # separate collection or database.
6
- class ReferencesOne < Proxy
7
-
8
- # Builds a new Document and sets it as the association.
9
- #
10
- # Returns the newly created object.
11
- def build(attributes = {})
12
- target = @klass.instantiate(attributes)
13
- replace(target)
14
- target
15
- end
16
-
17
- # Builds a new Document and sets it as the association, then saves the
18
- # newly created document.
19
- #
20
- # Returns the newly created object.
21
- def create(attributes = {})
22
- build(attributes).tap(&:save)
23
- end
24
-
25
- # Replaces the target with a new object
26
- #
27
- # Returns the association proxy
28
- def replace(obj)
29
- @target = obj
30
- inverse = @target.associations.values.detect do |metadata|
31
- metadata.options.klass == @parent.class
32
- end
33
- name = inverse.name
34
- @target.send("#{name}=", @parent)
35
-
36
- self
37
- end
38
-
39
- # Initializing a related association only requires looking up the objects
40
- # by their ids.
41
- #
42
- # Options:
43
- #
44
- # document: The +Document+ that contains the relationship.
45
- # options: The association +Options+.
46
- def initialize(document, options)
47
- @parent, @klass = document, options.klass
48
- @foreign_key = options.foreign_key
49
- @target = @klass.first(:conditions => { @foreign_key => @parent.id })
50
- extends(options)
51
- end
52
-
53
- # Used for setting the association via a nested attributes setter on the
54
- # parent +Document+. Called when using accepts_nested_attributes_for.
55
- #
56
- # Options:
57
- #
58
- # attributes: The attributes for the new association
59
- #
60
- # Returns:
61
- #
62
- # A new target document.
63
- def nested_build(attributes, options = nil)
64
- options ||= {}
65
- _destroy = Boolean.set(attributes.delete('_destroy'))
66
- if options[:allow_destroy] && _destroy
67
- @target.destroy
68
- @target = nil
69
- elsif @target.present? || !options[:update_only]
70
- build(attributes)
71
- end
72
- @target
73
- end
74
-
75
- class << self
76
- # Returns the macro used to create the association.
77
- def macro
78
- :references_one
79
- end
80
-
81
- # Perform an update of the relationship of the parent and child. This
82
- # will assimilate the child +Document+ into the parent's object graph.
83
- #
84
- # Options:
85
- #
86
- # related: The related object to update.
87
- # document: The parent +Document+.
88
- # options: The association +Options+
89
- #
90
- # Example:
91
- #
92
- # <tt>HasOneToRelated.update(game, person, options)</tt>
93
- def update(target, document, options)
94
- if target
95
- name = document.class.to_s.underscore
96
- proxy = new(document, options)
97
- proxy.replace(target)
98
- end
99
- proxy
100
- end
101
- end
102
- end
103
- end
104
- end
@@ -1,17 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Extensions #:nodoc:
4
- module Array #:nodoc:
5
- module Accessors #:nodoc:
6
- # If the attributes already exists in the array then they will be
7
- # updated, otherwise they will be appended.
8
- def update(attributes)
9
- delete_if { |e| attributes["_id"] && (e["_id"] == attributes["_id"]) }
10
- self.<< attributes
11
- end
12
-
13
- alias :merge! :update
14
- end
15
- end
16
- end
17
- end
@@ -1,26 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Extensions #:nodoc:
4
- module Array #:nodoc:
5
- module Assimilation #:nodoc:
6
- # Introduces a child object into the +Document+ object graph. This will
7
- # set up the relationships between the parent and child and update the
8
- # attributes of the parent +Document+.
9
- #
10
- # Options:
11
- #
12
- # parent: The +Document+ to assimilate into.
13
- # options: The association +Options+ for the child.
14
- #
15
- # Example:
16
- #
17
- # <tt>[{:street => "Queen St."}, {:street => "King St."}].assimilate(person, options)</tt>
18
- #
19
- # Returns: The child +Document+.
20
- def assimilate(parent, options)
21
- each { |child| child.assimilate(parent, options) }
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,42 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Extensions #:nodoc:
4
- module Hash #:nodoc:
5
- module Accessors #:nodoc:
6
-
7
- # Remove a set of attributes from a hash. If the attributes are
8
- # contained in an array it will remove it from the array, otherwise it
9
- # will delete the child attribute completely.
10
- def remove(key, attrs)
11
- elements = self[key]
12
- if elements
13
- key.singular? ? self[key] = nil : elements.delete(attrs)
14
- end
15
- end
16
-
17
- # Inserts new attributes into the hash. If the elements are present in
18
- # the hash it will update them, otherwise it will add the new
19
- # attributes into the hash as either a child hash or child array of
20
- # hashes.
21
- def insert(key, attrs)
22
- elements = self[key]
23
- if elements
24
- if elements.kind_of?(::Array)
25
- elements.merge!(attrs)
26
- else
27
- self[key] = attrs.reverse_merge!(elements)
28
- end
29
- else
30
- self[key] = key.singular? ? attrs : [attrs]
31
- end
32
- end
33
-
34
- # If a _type key exists in the hash, return the class for the value.
35
- def klass
36
- class_name = self["_type"]
37
- class_name ? class_name.constantize : nil
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Extensions #:nodoc:
4
- module Hash #:nodoc:
5
- module Assimilation #:nodoc:
6
- # Introduces a child object into the +Document+ object graph. This will
7
- # set up the relationships between the parent and child and update the
8
- # attributes of the parent +Document+.
9
- #
10
- # Options:
11
- #
12
- # parent: The +Document+ to assimilate into.
13
- # options: The association +Options+ for the child.
14
- #
15
- # Example:
16
- #
17
- # <tt>{:first_name => "Hank", :last_name => "Moody"}.assimilate(name, options)</tt>
18
- #
19
- # Returns: The child +Document+.
20
- def assimilate(parent, options, type = nil)
21
- klass = self.klass || (type ? type : options.klass)
22
- child = klass.instantiate("_id" => self["_id"])
23
- self.merge("_type" => klass.name) if klass.hereditary?
24
- init(parent, child, options)
25
- end
26
-
27
- protected
28
-
29
- def init(parent, child, options)
30
- child.parentize(parent, options.name)
31
- child.write_attributes(self)
32
- child.identify
33
- child.reset_modifications
34
- child.notify
35
- child
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,17 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Extensions #:nodoc:
4
- module Nil #:nodoc:
5
- module Assimilation #:nodoc:
6
- # Will remove the child object from the parent.
7
- def assimilate(parent, options, type = nil)
8
- parent.remove_attribute(options.name); self
9
- end
10
-
11
- def collectionize
12
- to_s.collectionize
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,33 +0,0 @@
1
- module Mongoid #:nodoc
2
- module Memoization
3
-
4
- # Handles cases when accessing an association that should be memoized in
5
- # the Mongoid specific manner. Does not memoize nil values though
6
- def memoized(name, &block)
7
- var = "@#{name}"
8
- if instance_variable_defined?(var)
9
- return instance_variable_get(var)
10
- end
11
- value = yield
12
- instance_variable_set(var, value) if value
13
- end
14
-
15
- # Removes an memozied association if it exists
16
- def unmemoize(name)
17
- var = "@#{name}"
18
- remove_instance_variable(var) if instance_variable_defined?(var)
19
- end
20
-
21
- # Mongoid specific behavior is to remove the memoized object when setting
22
- # the association, or if it wasn't previously memoized it will get set.
23
- def reset(name, &block)
24
- var = "@#{name}"
25
- value = yield
26
- if instance_variable_defined?(var)
27
- remove_instance_variable(var)
28
- else
29
- instance_variable_set(var, value)
30
- end
31
- end
32
- end
33
- end