mongoid 2.0.0.alpha → 2.0.0.beta.5

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 (216) hide show
  1. data/lib/mongoid.rb +11 -5
  2. data/lib/mongoid/associations.rb +112 -107
  3. data/lib/mongoid/associations/belongs_to_related.rb +2 -3
  4. data/lib/mongoid/associations/embedded_in.rb +12 -4
  5. data/lib/mongoid/associations/{embed_many.rb → embeds_many.rb} +101 -32
  6. data/lib/mongoid/associations/{embed_one.rb → embeds_one.rb} +10 -10
  7. data/lib/mongoid/associations/has_many_related.rb +51 -5
  8. data/lib/mongoid/associations/has_one_related.rb +9 -5
  9. data/lib/mongoid/associations/meta_data.rb +2 -1
  10. data/lib/mongoid/associations/options.rb +15 -6
  11. data/lib/mongoid/associations/proxy.rb +14 -21
  12. data/lib/mongoid/attributes.rb +34 -13
  13. data/lib/mongoid/callbacks.rb +1 -2
  14. data/lib/mongoid/collection.rb +4 -3
  15. data/lib/mongoid/collections.rb +41 -0
  16. data/lib/mongoid/collections/master.rb +3 -2
  17. data/lib/mongoid/collections/slaves.rb +3 -2
  18. data/lib/mongoid/components.rb +4 -1
  19. data/lib/mongoid/config.rb +163 -13
  20. data/lib/mongoid/contexts.rb +1 -2
  21. data/lib/mongoid/contexts/enumerable.rb +1 -1
  22. data/lib/mongoid/contexts/mongo.rb +1 -1
  23. data/lib/mongoid/contexts/paging.rb +10 -2
  24. data/lib/mongoid/criteria.rb +13 -22
  25. data/lib/mongoid/criterion/exclusion.rb +3 -3
  26. data/lib/mongoid/criterion/inclusion.rb +17 -0
  27. data/lib/mongoid/criterion/optional.rb +1 -1
  28. data/lib/mongoid/dirty.rb +253 -0
  29. data/lib/mongoid/document.rb +40 -85
  30. data/lib/mongoid/errors.rb +48 -1
  31. data/lib/mongoid/extensions.rb +11 -9
  32. data/lib/mongoid/extensions/big_decimal/conversions.rb +2 -2
  33. data/lib/mongoid/extensions/boolean/conversions.rb +8 -2
  34. data/lib/mongoid/extensions/date/conversions.rb +13 -4
  35. data/lib/mongoid/extensions/datetime/conversions.rb +1 -6
  36. data/lib/mongoid/extensions/float/conversions.rb +5 -1
  37. data/lib/mongoid/extensions/hash/assimilation.rb +12 -3
  38. data/lib/mongoid/extensions/hash/conversions.rb +34 -4
  39. data/lib/mongoid/extensions/integer/conversions.rb +5 -1
  40. data/lib/mongoid/extensions/nil/assimilation.rb +4 -0
  41. data/lib/mongoid/extensions/object/conversions.rb +3 -3
  42. data/lib/mongoid/extensions/string/conversions.rb +1 -1
  43. data/lib/mongoid/extensions/symbol/inflections.rb +5 -2
  44. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  45. data/lib/mongoid/factory.rb +2 -1
  46. data/lib/mongoid/field.rb +15 -2
  47. data/lib/mongoid/fields.rb +1 -1
  48. data/lib/mongoid/identity.rb +3 -3
  49. data/lib/mongoid/indexes.rb +3 -3
  50. data/lib/mongoid/matchers.rb +1 -2
  51. data/lib/mongoid/memoization.rb +8 -2
  52. data/lib/mongoid/named_scope.rb +0 -5
  53. data/lib/mongoid/observable.rb +1 -1
  54. data/lib/mongoid/paths.rb +30 -22
  55. data/lib/mongoid/persistence.rb +218 -0
  56. data/lib/mongoid/persistence/command.rb +39 -0
  57. data/lib/mongoid/persistence/insert.rb +47 -0
  58. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  59. data/lib/mongoid/persistence/remove.rb +39 -0
  60. data/lib/mongoid/persistence/remove_all.rb +37 -0
  61. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  62. data/lib/mongoid/persistence/update.rb +63 -0
  63. data/lib/mongoid/railtie.rb +53 -0
  64. data/lib/mongoid/railties/database.rake +37 -0
  65. data/lib/mongoid/timestamps.rb +2 -2
  66. data/lib/mongoid/validations.rb +2 -2
  67. data/lib/mongoid/validations/associated.rb +2 -2
  68. data/lib/mongoid/validations/uniqueness.rb +13 -2
  69. data/lib/mongoid/version.rb +4 -0
  70. data/lib/mongoid/versioning.rb +3 -2
  71. data/lib/rails/generators/mongoid/config/config_generator.rb +41 -0
  72. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
  73. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  74. data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
  75. data/lib/rails/generators/mongoid_generator.rb +61 -0
  76. metadata +76 -301
  77. data/.gitignore +0 -6
  78. data/.watchr +0 -29
  79. data/Rakefile +0 -52
  80. data/VERSION +0 -1
  81. data/caliper.yml +0 -4
  82. data/lib/mongoid/collections/mimic.rb +0 -46
  83. data/lib/mongoid/commands.rb +0 -161
  84. data/lib/mongoid/commands/create.rb +0 -19
  85. data/lib/mongoid/commands/delete.rb +0 -16
  86. data/lib/mongoid/commands/delete_all.rb +0 -23
  87. data/lib/mongoid/commands/deletion.rb +0 -18
  88. data/lib/mongoid/commands/destroy.rb +0 -17
  89. data/lib/mongoid/commands/destroy_all.rb +0 -23
  90. data/lib/mongoid/commands/save.rb +0 -29
  91. data/lib/mongoid/extensions/time/conversions.rb +0 -18
  92. data/mongoid.gemspec +0 -408
  93. data/perf/benchmark.rb +0 -77
  94. data/spec/integration/mongoid/associations_spec.rb +0 -340
  95. data/spec/integration/mongoid/attributes_spec.rb +0 -22
  96. data/spec/integration/mongoid/commands_spec.rb +0 -227
  97. data/spec/integration/mongoid/contexts/enumerable_spec.rb +0 -33
  98. data/spec/integration/mongoid/criteria_spec.rb +0 -272
  99. data/spec/integration/mongoid/document_spec.rb +0 -650
  100. data/spec/integration/mongoid/extensions_spec.rb +0 -22
  101. data/spec/integration/mongoid/finders_spec.rb +0 -119
  102. data/spec/integration/mongoid/inheritance_spec.rb +0 -137
  103. data/spec/integration/mongoid/named_scope_spec.rb +0 -46
  104. data/spec/models/address.rb +0 -39
  105. data/spec/models/animal.rb +0 -6
  106. data/spec/models/callbacks.rb +0 -18
  107. data/spec/models/comment.rb +0 -8
  108. data/spec/models/country_code.rb +0 -6
  109. data/spec/models/employer.rb +0 -5
  110. data/spec/models/game.rb +0 -7
  111. data/spec/models/inheritance.rb +0 -56
  112. data/spec/models/location.rb +0 -5
  113. data/spec/models/mixed_drink.rb +0 -4
  114. data/spec/models/name.rb +0 -13
  115. data/spec/models/namespacing.rb +0 -11
  116. data/spec/models/patient.rb +0 -4
  117. data/spec/models/person.rb +0 -99
  118. data/spec/models/pet.rb +0 -7
  119. data/spec/models/pet_owner.rb +0 -6
  120. data/spec/models/phone.rb +0 -7
  121. data/spec/models/post.rb +0 -15
  122. data/spec/models/translation.rb +0 -5
  123. data/spec/models/vet_visit.rb +0 -5
  124. data/spec/spec.opts +0 -3
  125. data/spec/spec_helper.rb +0 -31
  126. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +0 -145
  127. data/spec/unit/mongoid/associations/embed_many_spec.rb +0 -516
  128. data/spec/unit/mongoid/associations/embed_one_spec.rb +0 -282
  129. data/spec/unit/mongoid/associations/embedded_in_spec.rb +0 -193
  130. data/spec/unit/mongoid/associations/has_many_related_spec.rb +0 -418
  131. data/spec/unit/mongoid/associations/has_one_related_spec.rb +0 -179
  132. data/spec/unit/mongoid/associations/meta_data_spec.rb +0 -88
  133. data/spec/unit/mongoid/associations/options_spec.rb +0 -192
  134. data/spec/unit/mongoid/associations_spec.rb +0 -595
  135. data/spec/unit/mongoid/attributes_spec.rb +0 -507
  136. data/spec/unit/mongoid/callbacks_spec.rb +0 -55
  137. data/spec/unit/mongoid/collection_spec.rb +0 -187
  138. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +0 -75
  139. data/spec/unit/mongoid/collections/master_spec.rb +0 -41
  140. data/spec/unit/mongoid/collections/mimic_spec.rb +0 -43
  141. data/spec/unit/mongoid/collections/slaves_spec.rb +0 -81
  142. data/spec/unit/mongoid/commands/create_spec.rb +0 -31
  143. data/spec/unit/mongoid/commands/delete_all_spec.rb +0 -58
  144. data/spec/unit/mongoid/commands/delete_spec.rb +0 -38
  145. data/spec/unit/mongoid/commands/destroy_all_spec.rb +0 -21
  146. data/spec/unit/mongoid/commands/destroy_spec.rb +0 -51
  147. data/spec/unit/mongoid/commands/save_spec.rb +0 -107
  148. data/spec/unit/mongoid/commands_spec.rb +0 -270
  149. data/spec/unit/mongoid/config_spec.rb +0 -172
  150. data/spec/unit/mongoid/contexts/enumerable_spec.rb +0 -421
  151. data/spec/unit/mongoid/contexts/mongo_spec.rb +0 -682
  152. data/spec/unit/mongoid/contexts_spec.rb +0 -25
  153. data/spec/unit/mongoid/criteria_spec.rb +0 -824
  154. data/spec/unit/mongoid/criterion/complex_spec.rb +0 -19
  155. data/spec/unit/mongoid/criterion/exclusion_spec.rb +0 -91
  156. data/spec/unit/mongoid/criterion/inclusion_spec.rb +0 -219
  157. data/spec/unit/mongoid/criterion/optional_spec.rb +0 -319
  158. data/spec/unit/mongoid/cursor_spec.rb +0 -74
  159. data/spec/unit/mongoid/deprecation_spec.rb +0 -24
  160. data/spec/unit/mongoid/document_spec.rb +0 -818
  161. data/spec/unit/mongoid/errors_spec.rb +0 -103
  162. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +0 -50
  163. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +0 -24
  164. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +0 -35
  165. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +0 -20
  166. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +0 -22
  167. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +0 -22
  168. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +0 -49
  169. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +0 -102
  170. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +0 -67
  171. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +0 -61
  172. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +0 -184
  173. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +0 -46
  174. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +0 -21
  175. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +0 -17
  176. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +0 -14
  177. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +0 -61
  178. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +0 -24
  179. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +0 -57
  180. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +0 -34
  181. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +0 -17
  182. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +0 -208
  183. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +0 -91
  184. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +0 -70
  185. data/spec/unit/mongoid/extras_spec.rb +0 -102
  186. data/spec/unit/mongoid/factory_spec.rb +0 -31
  187. data/spec/unit/mongoid/field_spec.rb +0 -143
  188. data/spec/unit/mongoid/fields_spec.rb +0 -181
  189. data/spec/unit/mongoid/finders_spec.rb +0 -404
  190. data/spec/unit/mongoid/identity_spec.rb +0 -109
  191. data/spec/unit/mongoid/indexes_spec.rb +0 -93
  192. data/spec/unit/mongoid/javascript_spec.rb +0 -48
  193. data/spec/unit/mongoid/matchers/all_spec.rb +0 -27
  194. data/spec/unit/mongoid/matchers/default_spec.rb +0 -27
  195. data/spec/unit/mongoid/matchers/exists_spec.rb +0 -56
  196. data/spec/unit/mongoid/matchers/gt_spec.rb +0 -39
  197. data/spec/unit/mongoid/matchers/gte_spec.rb +0 -49
  198. data/spec/unit/mongoid/matchers/in_spec.rb +0 -27
  199. data/spec/unit/mongoid/matchers/lt_spec.rb +0 -39
  200. data/spec/unit/mongoid/matchers/lte_spec.rb +0 -49
  201. data/spec/unit/mongoid/matchers/ne_spec.rb +0 -27
  202. data/spec/unit/mongoid/matchers/nin_spec.rb +0 -27
  203. data/spec/unit/mongoid/matchers/size_spec.rb +0 -27
  204. data/spec/unit/mongoid/matchers_spec.rb +0 -329
  205. data/spec/unit/mongoid/memoization_spec.rb +0 -75
  206. data/spec/unit/mongoid/named_scope_spec.rb +0 -123
  207. data/spec/unit/mongoid/observable_spec.rb +0 -46
  208. data/spec/unit/mongoid/paths_spec.rb +0 -124
  209. data/spec/unit/mongoid/scope_spec.rb +0 -240
  210. data/spec/unit/mongoid/state_spec.rb +0 -83
  211. data/spec/unit/mongoid/timestamps_spec.rb +0 -25
  212. data/spec/unit/mongoid/validations/associated_spec.rb +0 -103
  213. data/spec/unit/mongoid/validations/uniqueness_spec.rb +0 -47
  214. data/spec/unit/mongoid/validations_spec.rb +0 -190
  215. data/spec/unit/mongoid/versioning_spec.rb +0 -41
  216. data/spec/unit/mongoid_spec.rb +0 -46
@@ -21,13 +21,15 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  require "rubygems"
23
23
 
24
- gem "activemodel", ">= 3.0.pre"
25
- gem "will_paginate", ">= 3.0.pre"
26
- gem "mongo", ">= 0.19.1"
24
+ gem "activemodel", "3.0.0.beta3"
25
+ gem "will_paginate", "3.0.pre"
26
+ gem "mongo", "~>1.0.1"
27
+ gem "bson", "~>1.0.1"
27
28
 
28
29
  require "delegate"
29
30
  require "singleton"
30
31
  require "time"
32
+ require "ostruct"
31
33
  require "active_support/core_ext"
32
34
  require 'active_support/json'
33
35
  require "active_support/inflector"
@@ -44,16 +46,18 @@ require "active_model/validator"
44
46
  require "active_model/validations"
45
47
  require "will_paginate/collection"
46
48
  require "mongo"
49
+ require "mongoid/observable"
47
50
  require "mongoid/associations"
48
51
  require "mongoid/attributes"
49
52
  require "mongoid/callbacks"
50
53
  require "mongoid/collection"
51
- require "mongoid/commands"
54
+ require "mongoid/collections"
52
55
  require "mongoid/config"
53
56
  require "mongoid/contexts"
54
57
  require "mongoid/criteria"
55
58
  require "mongoid/cursor"
56
59
  require "mongoid/deprecation"
60
+ require "mongoid/dirty"
57
61
  require "mongoid/extensions"
58
62
  require "mongoid/extras"
59
63
  require "mongoid/errors"
@@ -67,8 +71,8 @@ require "mongoid/javascript"
67
71
  require "mongoid/matchers"
68
72
  require "mongoid/memoization"
69
73
  require "mongoid/named_scope"
70
- require "mongoid/observable"
71
74
  require "mongoid/paths"
75
+ require "mongoid/persistence"
72
76
  require "mongoid/scope"
73
77
  require "mongoid/state"
74
78
  require "mongoid/timestamps"
@@ -79,6 +83,8 @@ require "mongoid/document"
79
83
 
80
84
  module Mongoid #:nodoc
81
85
 
86
+ MONGODB_VERSION = "1.4.0"
87
+
82
88
  class << self
83
89
 
84
90
  # Sets the Mongoid configuration options. Best used by passing a block.
@@ -2,8 +2,8 @@
2
2
  require "mongoid/associations/proxy"
3
3
  require "mongoid/associations/belongs_to_related"
4
4
  require "mongoid/associations/embedded_in"
5
- require "mongoid/associations/embed_many"
6
- require "mongoid/associations/embed_one"
5
+ require "mongoid/associations/embeds_many"
6
+ require "mongoid/associations/embeds_one"
7
7
  require "mongoid/associations/has_many_related"
8
8
  require "mongoid/associations/has_one_related"
9
9
  require "mongoid/associations/options"
@@ -13,9 +13,13 @@ module Mongoid # :nodoc:
13
13
  module Associations #:nodoc:
14
14
  extend ActiveSupport::Concern
15
15
  included do
16
- # Associations need to inherit down the chain.
16
+ cattr_accessor :embedded
17
+ self.embedded = false
18
+
17
19
  class_inheritable_accessor :associations
18
20
  self.associations = {}
21
+
22
+ delegate :embedded, :embedded?, :to => "self.class"
19
23
  end
20
24
 
21
25
  module InstanceMethods
@@ -24,9 +28,15 @@ module Mongoid # :nodoc:
24
28
  self.class.associations
25
29
  end
26
30
 
27
- # Updates all the one-to-many relational associations for the name.
28
- def update_associations(name)
29
- send(name).each { |doc| doc.save } if new_record?
31
+ # are we in an embeds_many?
32
+ def embedded_many?
33
+ embedded? and _parent.associations[association_name].association == EmbedsMany
34
+ end
35
+
36
+ # Update all the dirty child documents after an update.
37
+ def update_embedded(name)
38
+ association = send(name)
39
+ association.to_a.each { |doc| doc.save if doc.changed? || doc.new_record? } unless association.blank?
30
40
  end
31
41
 
32
42
  # Update the one-to-one relational association for the name.
@@ -34,14 +44,46 @@ module Mongoid # :nodoc:
34
44
  association = send(name)
35
45
  association.save if new_record? && !association.nil?
36
46
  end
47
+
48
+ # Updates all the one-to-many relational associations for the name.
49
+ def update_associations(name)
50
+ send(name).each { |doc| doc.save } if new_record?
51
+ end
37
52
  end
38
53
 
39
54
  module ClassMethods
55
+ # Adds a relational association from the child Document to a Document in
56
+ # another database or collection.
57
+ #
58
+ # Options:
59
+ #
60
+ # name: A +Symbol+ that is the related class name.
61
+ #
62
+ # Example:
63
+ #
64
+ # class Game
65
+ # include Mongoid::Document
66
+ # belongs_to_related :person
67
+ # end
68
+ #
69
+ def belongs_to_related(name, options = {}, &block)
70
+ opts = optionize(name, options, fk(name, options), &block)
71
+ associate(Associations::BelongsToRelated, opts)
72
+ field(opts.foreign_key, :type => Mongoid.use_object_ids ? BSON::ObjectID : String)
73
+ index(opts.foreign_key) unless embedded?
74
+ end
40
75
 
41
- # Deprecated: Document.belongs_to will become Document.embedded_in
42
- def belongs_to(name, options = {}, &block)
43
- Mongoid.deprecate("Document.belongs_to will become Document.embedded_in")
44
- embedded_in(name, options, &block)
76
+ # Gets whether or not the document is embedded.
77
+ #
78
+ # Example:
79
+ #
80
+ # <tt>Person.embedded?</tt>
81
+ #
82
+ # Returns:
83
+ #
84
+ # <tt>true</tt> if embedded, <tt>false</tt> if not.
85
+ def embedded?
86
+ !!self.embedded
45
87
  end
46
88
 
47
89
  # Adds the association back to the parent document. This macro is
@@ -57,7 +99,7 @@ module Mongoid # :nodoc:
57
99
  #
58
100
  # class Person
59
101
  # include Mongoid::Document
60
- # embed_many :addresses
102
+ # embeds_many :addresses
61
103
  # end
62
104
  #
63
105
  # class Address
@@ -66,48 +108,40 @@ module Mongoid # :nodoc:
66
108
  # end
67
109
  def embedded_in(name, options = {}, &block)
68
110
  unless options.has_key?(:inverse_of)
69
- raise Errors::InvalidOptions.new("Options for belongs_to association must include :inverse_of")
111
+ raise Errors::InvalidOptions.new("Options for embedded_in association must include :inverse_of")
70
112
  end
71
113
  self.embedded = true
72
- add_association(
73
- Associations::EmbeddedIn,
74
- Associations::Options.new(
75
- options.merge(:name => name, :extend => block)
76
- )
77
- )
114
+ associate(Associations::EmbeddedIn, optionize(name, options, nil, &block))
78
115
  end
79
116
 
80
- # Adds a relational association from the child Document to a Document in
81
- # another database or collection.
117
+ # Adds the association from a parent document to its children. The name
118
+ # of the association needs to be a pluralized form of the child class
119
+ # name.
82
120
  #
83
121
  # Options:
84
122
  #
85
- # name: A +Symbol+ that is the related class name.
123
+ # name: A +Symbol+ that is the plural child class name.
86
124
  #
87
125
  # Example:
88
126
  #
89
- # class Game
127
+ # class Person
90
128
  # include Mongoid::Document
91
- # belongs_to_related :person
129
+ # embeds_many :addresses
92
130
  # end
93
131
  #
94
- def belongs_to_related(name, options = {}, &block)
95
- opts = Associations::Options.new(
96
- options.merge(:name => name, :extend => block, :foreign_key => foreign_key(name, options))
97
- )
98
- add_association(Associations::BelongsToRelated, opts)
99
- field(opts.foreign_key, :type => Mongoid.use_object_ids ? Mongo::ObjectID : String)
100
- index(opts.foreign_key) unless self.embedded
132
+ # class Address
133
+ # include Mongoid::Document
134
+ # embedded_in :person, :inverse_of => :addresses
135
+ # end
136
+ def embeds_many(name, options = {}, &block)
137
+ associate(Associations::EmbedsMany, optionize(name, options, nil, &block))
138
+ set_callback(:update, :after) { |document| document.update_embedded(name) } unless name == :versions
101
139
  end
102
140
 
103
- # Deprecated: Document.has_many will become Document.embed_many
104
- def has_many(name, options = {}, &block)
105
- Mongoid.deprecate("Document.has_many will become Document.embed_many")
106
- embed_many(name, options, &block)
107
- end
141
+ alias :embed_many :embeds_many
108
142
 
109
- # Adds the association from a parent document to its children. The name
110
- # of the association needs to be a pluralized form of the child class
143
+ # Adds the association from a parent document to its child. The name
144
+ # of the association needs to be a singular form of the child class
111
145
  # name.
112
146
  #
113
147
  # Options:
@@ -118,22 +152,24 @@ module Mongoid # :nodoc:
118
152
  #
119
153
  # class Person
120
154
  # include Mongoid::Document
121
- # embed_many :addresses
155
+ # embeds_one :name
122
156
  # end
123
157
  #
124
- # class Address
158
+ # class Name
125
159
  # include Mongoid::Document
126
- # embedded_in :person, :inverse_of => :addresses
160
+ # embedded_in :person
127
161
  # end
128
- def embed_many(name, options = {}, &block)
129
- add_association(
130
- Associations::EmbedMany,
131
- Associations::Options.new(
132
- options.merge(:name => name, :extend => block)
133
- )
134
- )
162
+ def embeds_one(name, options = {}, &block)
163
+ opts = optionize(name, options, nil, &block)
164
+ type = Associations::EmbedsOne
165
+ associate(type, opts)
166
+ add_builder(type, opts)
167
+ add_creator(type, opts)
168
+ set_callback(:update, :after) { |document| document.update_embedded(name) }
135
169
  end
136
170
 
171
+ alias :embed_one :embeds_one
172
+
137
173
  # Adds a relational association from the Document to many Documents in
138
174
  # another database or collection.
139
175
  #
@@ -149,51 +185,12 @@ module Mongoid # :nodoc:
149
185
  # end
150
186
  #
151
187
  def has_many_related(name, options = {}, &block)
152
- add_association(Associations::HasManyRelated,
153
- Associations::Options.new(
154
- options.merge(:name => name, :foreign_key => foreign_key(self.name, options), :extend => block)
155
- )
156
- )
157
- before_save do |document|
188
+ associate(Associations::HasManyRelated, optionize(name, options, fk(self.name, options), &block))
189
+ set_callback :save, :before do |document|
158
190
  document.update_associations(name)
159
191
  end
160
192
  end
161
193
 
162
- # Deprecated: Document.has_one will become Document.embed_one
163
- def has_one(name, options = {}, &block)
164
- Mongoid.deprecate("Document.has_one will become Document.embed_one")
165
- embed_one(name, options, &block)
166
- end
167
-
168
- # Adds the association from a parent document to its child. The name
169
- # of the association needs to be a singular form of the child class
170
- # name.
171
- #
172
- # Options:
173
- #
174
- # name: A +Symbol+ that is the plural child class name.
175
- #
176
- # Example:
177
- #
178
- # class Person
179
- # include Mongoid::Document
180
- # embed_one :name
181
- # end
182
- #
183
- # class Name
184
- # include Mongoid::Document
185
- # embedded_in :person
186
- # end
187
- def embed_one(name, options = {}, &block)
188
- opts = Associations::Options.new(
189
- options.merge(:name => name, :extend => block)
190
- )
191
- type = Associations::EmbedOne
192
- add_association(type, opts)
193
- add_builder(type, opts)
194
- add_creator(type, opts)
195
- end
196
-
197
194
  # Adds a relational association from the Document to one Document in
198
195
  # another database or collection.
199
196
  #
@@ -208,19 +205,14 @@ module Mongoid # :nodoc:
208
205
  # has_one_related :game
209
206
  # end
210
207
  def has_one_related(name, options = {}, &block)
211
- add_association(
212
- Associations::HasOneRelated,
213
- Associations::Options.new(
214
- options.merge(:name => name, :foreign_key => foreign_key(name, options), :extend => block)
215
- )
216
- )
217
- before_save do |document|
208
+ associate(Associations::HasOneRelated, optionize(name, options, fk(self.name, options), &block))
209
+ set_callback :save, :before do |document|
218
210
  document.update_association(name)
219
211
  end
220
212
  end
221
213
 
222
214
  # Returns the macro associated with the supplied association name. This
223
- # will return has_one, has_many, belongs_to or nil.
215
+ # will return embeds_on, embeds_many, embedded_in or nil.
224
216
  #
225
217
  # Options:
226
218
  #
@@ -238,14 +230,17 @@ module Mongoid # :nodoc:
238
230
  # Adds the association to the associations hash with the type as the key,
239
231
  # then adds the accessors for the association. The defined setters and
240
232
  # getters for the associations will perform the necessary memoization.
241
- def add_association(type, options)
233
+ #
234
+ # Example:
235
+ #
236
+ # <tt>Person.associate(EmbedsMany, { :name => :addresses })</tt>
237
+ def associate(type, options)
242
238
  name = options.name.to_s
243
239
  associations[name] = MetaData.new(type, options)
244
- define_method(name) do
245
- memoized(name) { type.instantiate(self, options) }
246
- end
240
+ define_method(name) { memoized(name) { type.instantiate(self, options) } }
247
241
  define_method("#{name}=") do |object|
248
- reset(name) { type.update(object, self, options) }
242
+ unmemoize(name)
243
+ memoized(name) { type.update(object, self, options) }
249
244
  end
250
245
  end
251
246
 
@@ -253,8 +248,10 @@ module Mongoid # :nodoc:
253
248
  # build_name(attributes)
254
249
  def add_builder(type, options)
255
250
  name = options.name.to_s
256
- define_method("build_#{name}") do |attrs|
257
- reset(name) { type.new(self, (attrs || {}).stringify_keys, options) }
251
+ define_method("build_#{name}") do |*params|
252
+ attrs = params[0]
253
+ attr_options = params[1] || {}
254
+ reset(name) { type.new(self, (attrs || {}).stringify_keys, options) } unless type == Associations::EmbedsOne && attr_options[:update_only]
258
255
  end
259
256
  end
260
257
 
@@ -262,14 +259,22 @@ module Mongoid # :nodoc:
262
259
  # create_name(attributes)
263
260
  def add_creator(type, options)
264
261
  name = options.name.to_s
265
- define_method("create_#{name}") do |attrs|
266
- document = send("build_#{name}", attrs)
267
- document.run_callbacks(:create) { document.save }; document
262
+ define_method("create_#{name}") do |*params|
263
+ attrs = params[0]
264
+ attr_options = params[1] || {}
265
+ send("build_#{name}", attrs, attr_options).tap(&:save) unless type == Associations::EmbedsOne && attr_options[:update_only]
268
266
  end
269
267
  end
270
268
 
269
+ # build the options given the params.
270
+ def optionize(name, options, foreign_key, &block)
271
+ Associations::Options.new(
272
+ options.merge(:name => name, :foreign_key => foreign_key, :extend => block)
273
+ )
274
+ end
275
+
271
276
  # Find the foreign key.
272
- def foreign_key(name, options)
277
+ def fk(name, options)
273
278
  options[:foreign_key] || name.to_s.foreign_key
274
279
  end
275
280
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc:
3
3
  module Associations #:nodoc:
4
- class BelongsToRelated #:nodoc:
5
- include Proxy
4
+ # Represents a relational association to a "parent" object.
5
+ class BelongsToRelated < Proxy
6
6
 
7
7
  # Initializing a related association only requires looking up the object
8
8
  # by its id.
@@ -53,7 +53,6 @@ module Mongoid #:nodoc:
53
53
  instantiate(document, options, target)
54
54
  end
55
55
  end
56
-
57
56
  end
58
57
  end
59
58
  end
@@ -1,8 +1,9 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc:
3
3
  module Associations #:nodoc:
4
- class EmbeddedIn #:nodoc:
5
- include Proxy
4
+ # Represents an association that is embedded within another document in the
5
+ # database, either as one or many.
6
+ class EmbeddedIn < Proxy
6
7
 
7
8
  # Creates the new association by setting the internal
8
9
  # target as the passed in Document. This should be the
@@ -48,16 +49,23 @@ module Mongoid #:nodoc:
48
49
 
49
50
  # Perform an update of the relationship of the parent and child. This
50
51
  # is initialized by setting a parent object as the association on the
51
- # +Document+. Will properly set an embed_one or an embed_many.
52
+ # +Document+. Will properly set an embeds_one or an embeds_many.
52
53
  #
53
54
  # Returns:
54
55
  #
55
56
  # A new +EmbeddedIn+ association proxy.
56
57
  def update(target, child, options)
57
- child.parentize(target, options.inverse_of)
58
+ child.parentize(target, determine_name(target, options))
58
59
  child.notify
59
60
  instantiate(child, options)
60
61
  end
62
+
63
+ protected
64
+ def determine_name(target, options)
65
+ inverse = options.inverse_of
66
+ return inverse unless inverse.is_a?(Array)
67
+ inverse.detect { |name| target.respond_to?(name) }
68
+ end
61
69
  end
62
70
  end
63
71
  end