mongoid 2.0.0.rc.6 → 2.0.0.rc.7

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 (64) hide show
  1. data/Rakefile +2 -2
  2. data/lib/config/locales/bg.yml +3 -6
  3. data/lib/config/locales/de.yml +2 -5
  4. data/lib/config/locales/en.yml +2 -5
  5. data/lib/config/locales/es.yml +2 -5
  6. data/lib/config/locales/fr.yml +2 -5
  7. data/lib/config/locales/hu.yml +2 -5
  8. data/lib/config/locales/it.yml +2 -5
  9. data/lib/config/locales/kr.yml +2 -5
  10. data/lib/config/locales/nl.yml +2 -5
  11. data/lib/config/locales/pl.yml +2 -5
  12. data/lib/config/locales/pt-br.yml +2 -5
  13. data/lib/config/locales/pt.yml +2 -5
  14. data/lib/config/locales/ro.yml +2 -5
  15. data/lib/config/locales/ru.yml +41 -0
  16. data/lib/config/locales/sv.yml +2 -5
  17. data/lib/config/locales/zh-CN.yml +3 -6
  18. data/lib/mongoid/atomicity.rb +2 -2
  19. data/lib/mongoid/attributes.rb +40 -69
  20. data/lib/mongoid/attributes/processing.rb +142 -0
  21. data/lib/mongoid/collections.rb +1 -0
  22. data/lib/mongoid/components.rb +1 -1
  23. data/lib/mongoid/config.rb +0 -1
  24. data/lib/mongoid/contexts/mongo.rb +13 -9
  25. data/lib/mongoid/criteria.rb +15 -1
  26. data/lib/mongoid/criterion/inclusion.rb +36 -11
  27. data/lib/mongoid/criterion/inspection.rb +3 -1
  28. data/lib/mongoid/criterion/optional.rb +2 -2
  29. data/lib/mongoid/dirty.rb +1 -0
  30. data/lib/mongoid/document.rb +11 -5
  31. data/lib/mongoid/extensions/integer/conversions.rb +2 -2
  32. data/lib/mongoid/extensions/object_id/conversions.rb +62 -32
  33. data/lib/mongoid/field.rb +5 -2
  34. data/lib/mongoid/identity.rb +2 -1
  35. data/lib/mongoid/matchers.rb +5 -32
  36. data/lib/mongoid/matchers/default.rb +53 -10
  37. data/lib/mongoid/matchers/or.rb +30 -0
  38. data/lib/mongoid/matchers/strategies.rb +63 -0
  39. data/lib/mongoid/multi_parameter_attributes.rb +4 -2
  40. data/lib/mongoid/nested_attributes.rb +8 -0
  41. data/lib/mongoid/persistence.rb +2 -1
  42. data/lib/mongoid/persistence/insert.rb +3 -3
  43. data/lib/mongoid/persistence/insert_embedded.rb +2 -1
  44. data/lib/mongoid/relations.rb +2 -1
  45. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
  46. data/lib/mongoid/relations/builders/nested_attributes/many.rb +2 -0
  47. data/lib/mongoid/relations/cascading.rb +1 -1
  48. data/lib/mongoid/relations/cascading/nullify.rb +1 -1
  49. data/lib/mongoid/relations/constraint.rb +42 -0
  50. data/lib/mongoid/relations/cyclic.rb +6 -0
  51. data/lib/mongoid/relations/embedded/many.rb +4 -4
  52. data/lib/mongoid/relations/macros.rb +1 -1
  53. data/lib/mongoid/relations/many.rb +1 -0
  54. data/lib/mongoid/relations/metadata.rb +12 -4
  55. data/lib/mongoid/relations/nested_builder.rb +1 -3
  56. data/lib/mongoid/relations/referenced/many.rb +11 -18
  57. data/lib/mongoid/relations/referenced/many_to_many.rb +19 -32
  58. data/lib/mongoid/relations/referenced/one.rb +3 -1
  59. data/lib/mongoid/timestamps.rb +1 -1
  60. data/lib/mongoid/validations/associated.rb +11 -9
  61. data/lib/mongoid/validations/uniqueness.rb +1 -1
  62. data/lib/mongoid/version.rb +1 -1
  63. data/lib/mongoid/versioning.rb +2 -2
  64. metadata +9 -4
@@ -7,6 +7,10 @@ module Mongoid # :nodoc:
7
7
  module Cyclic
8
8
  extend ActiveSupport::Concern
9
9
 
10
+ included do
11
+ class_attribute :cyclic
12
+ end
13
+
10
14
  module ClassMethods #:nodoc:
11
15
 
12
16
  # Create a cyclic embedded relation that creates a tree hierarchy for
@@ -32,6 +36,7 @@ module Mongoid # :nodoc:
32
36
  #
33
37
  # @since 2.0.0.rc.1
34
38
  def recursively_embeds_many
39
+ self.cyclic = true
35
40
  embeds_many cyclic_child_name, :class_name => self.name, :cyclic => true
36
41
  embedded_in cyclic_parent_name, :class_name => self.name, :cyclic => true
37
42
  end
@@ -59,6 +64,7 @@ module Mongoid # :nodoc:
59
64
  #
60
65
  # @since 2.0.0.rc.1
61
66
  def recursively_embeds_one
67
+ self.cyclic = true
62
68
  embeds_one cyclic_child_name(false), :class_name => self.name, :cyclic => true
63
69
  embedded_in cyclic_parent_name, :class_name => self.name, :cyclic => true
64
70
  end
@@ -259,15 +259,15 @@ module Mongoid # :nodoc:
259
259
  # Get this relation as as its representation in the database.
260
260
  #
261
261
  # @example Convert the relation to an attributes hash.
262
- # person.addresses.to_hash
262
+ # person.addresses.as_document
263
263
  #
264
264
  # @return [ Array<Hash> ] The relation as stored in the db.
265
265
  #
266
266
  # @since 2.0.0.rc.1
267
- def to_hash
267
+ def as_document
268
268
  target.inject([]) do |attributes, doc|
269
269
  attributes.tap do |attr|
270
- attr << doc.to_hash
270
+ attr << doc.as_document
271
271
  end
272
272
  end
273
273
  end
@@ -354,7 +354,7 @@ module Mongoid # :nodoc:
354
354
  load!(:binding => true) and return super if target.respond_to?(name)
355
355
  klass = metadata.klass
356
356
  klass.send(:with_scope, criteria) do
357
- klass.send(name, *args)
357
+ criteria.send(name, *args)
358
358
  end
359
359
  end
360
360
 
@@ -297,7 +297,7 @@ module Mongoid # :nodoc:
297
297
  # @param [ Symbol ] name The name of the relation.
298
298
  # @param [ Metadata ] metadata The metadata for the relation.
299
299
  def relate(name, metadata)
300
- relations[name.to_s] = metadata
300
+ self.relations = relations.merge(name.to_s => metadata)
301
301
  getter(name, metadata).setter(name, metadata)
302
302
  end
303
303
  end
@@ -22,6 +22,7 @@ module Mongoid #:nodoc:
22
22
  def <<(*args)
23
23
  options = default_options(args)
24
24
  args.flatten.each do |doc|
25
+ return doc unless doc
25
26
  append(doc, options)
26
27
  doc.save if base.persisted? && !options[:binding]
27
28
  end
@@ -6,7 +6,7 @@ module Mongoid # :nodoc:
6
6
  # contains everything you could ever possible want to know.
7
7
  class Metadata < Hash
8
8
 
9
- delegate :foreign_key_default, :to => :relation
9
+ delegate :foreign_key_default, :stores_foreign_key?, :to => :relation
10
10
 
11
11
  # Gets a relation builder associated with the relation this metadata is
12
12
  # for.
@@ -55,6 +55,10 @@ module Mongoid # :nodoc:
55
55
  @class_name ||= (self[:class_name] || classify)
56
56
  end
57
57
 
58
+ def constraint
59
+ @constraint ||= Constraint.new(self)
60
+ end
61
+
58
62
  # Will determine if the relation is an embedded one or not. Currently
59
63
  # only checks against embeds one and many.
60
64
  #
@@ -420,12 +424,16 @@ module Mongoid # :nodoc:
420
424
  suffix = relation.foreign_key_suffix
421
425
  if relation.stores_foreign_key?
422
426
  if relation.macro == :references_and_referenced_in_many
423
- name.to_s.singularize << suffix
427
+ "#{name.to_s.singularize}#{suffix}"
424
428
  else
425
- name.to_s << suffix
429
+ "#{name}#{suffix}"
426
430
  end
427
431
  else
428
- polymorphic? ? "#{self[:as]}#{suffix}" : inverse_class_name.foreign_key
432
+ if polymorphic?
433
+ "#{self[:as]}#{suffix}"
434
+ else
435
+ inverse_of ? "#{inverse_of}#{suffix}" : inverse_class_name.foreign_key
436
+ end
429
437
  end
430
438
  end
431
439
 
@@ -61,9 +61,7 @@ module Mongoid # :nodoc:
61
61
  #
62
62
  # @since 2.0.0.rc.6
63
63
  def convert_id(id)
64
- return nil unless id
65
- model = metadata.klass
66
- model.using_object_ids? ? BSON::ObjectId.cast!(model, id) : id.class.set(id)
64
+ metadata.constraint.convert(id)
67
65
  end
68
66
  end
69
67
  end
@@ -36,9 +36,9 @@ module Mongoid #:nodoc:
36
36
  # person.posts.clear
37
37
  #
38
38
  # @return [ Many ] The relation emptied.
39
- def clear
39
+ def clear(options = {})
40
40
  load! and tap do |relation|
41
- relation.unbind(default_options)
41
+ relation.unbind(default_options(options))
42
42
  target.clear
43
43
  end
44
44
  end
@@ -155,12 +155,8 @@ module Mongoid #:nodoc:
155
155
  #
156
156
  # @return [ Document, Criteria ] The matching document(s).
157
157
  def find(arg, options = {})
158
- klass = metadata.klass
159
- return klass.criteria.id_criteria(arg) unless arg.is_a?(Symbol)
160
- selector = (options[:conditions] || {}).merge(
161
- metadata.foreign_key => base.id
162
- )
163
- klass.find(arg, :conditions => selector)
158
+ return criteria.id_criteria(arg) unless arg.is_a?(Symbol)
159
+ criteria.find(arg, :conditions => options[:conditions] || {})
164
160
  end
165
161
 
166
162
  # Instantiate a new references_many relation. Will set the foreign key
@@ -204,13 +200,7 @@ module Mongoid #:nodoc:
204
200
  #
205
201
  # @since 2.0.0.rc.1
206
202
  def nullify
207
- load! and target.each do |doc|
208
- doc.send(metadata.foreign_key_setter, nil)
209
- doc.send(
210
- :remove_instance_variable, "@#{metadata.inverse(doc)}"
211
- )
212
- doc.save
213
- end
203
+ clear(:binding => true, :continue => true, :nullify => true)
214
204
  end
215
205
  alias :nullify_all :nullify
216
206
 
@@ -252,7 +242,10 @@ module Mongoid #:nodoc:
252
242
  # @since 2.0.0.rc.1
253
243
  def unbind(options = {})
254
244
  binding.unbind(options)
255
- target.each(&:delete) if base.persisted?
245
+ if base.persisted?
246
+ target.each(&:delete) unless options[:binding]
247
+ target.each(&:save) if options[:nullify]
248
+ end
256
249
  []
257
250
  end
258
251
 
@@ -312,7 +305,7 @@ module Mongoid #:nodoc:
312
305
  load!(:binding => true) and return super if [].respond_to?(name)
313
306
  klass = metadata.klass
314
307
  klass.send(:with_scope, criteria) do
315
- klass.send(name, *args)
308
+ criteria.send(name, *args)
316
309
  end
317
310
  end
318
311
 
@@ -347,7 +340,7 @@ module Mongoid #:nodoc:
347
340
  #
348
341
  # @since 2.0.0.rc.1
349
342
  def builder(meta, object)
350
- Builders::Referenced::Many.new(meta, object)
343
+ Builders::Referenced::Many.new(meta, object || [])
351
344
  end
352
345
 
353
346
  # Returns true if the relation is an embedded one. In this case
@@ -7,6 +7,25 @@ module Mongoid # :nodoc:
7
7
  # many-to-many between documents in different collections.
8
8
  class ManyToMany < Referenced::Many
9
9
 
10
+ # Appends a document or array of documents to the relation. Will set
11
+ # the parent and update the index in the process.
12
+ #
13
+ # @example Append a document.
14
+ # person.addresses << address
15
+ #
16
+ # @example Push a document.
17
+ # person.addresses.push(address)
18
+ #
19
+ # @example Concat with other documents.
20
+ # perosn.addresses.concat([ address_one, address_two ])
21
+ #
22
+ # @param [ Document, Array<Document> ] *args Any number of documents.
23
+ def <<(*args)
24
+ options = default_options(args)
25
+ super(args)
26
+ base.save if base.persisted? && !options[:binding]
27
+ end
28
+
10
29
  # Creates a new document on the references many relation. This will
11
30
  # save the document if the parent has been persisted.
12
31
  #
@@ -94,38 +113,6 @@ module Mongoid # :nodoc:
94
113
  metadata.klass.destroy_all(:conditions => selector.merge(scoping))
95
114
  end
96
115
 
97
- # Find the matchind document on the association, either based on id or
98
- # conditions.
99
- #
100
- # @example Find by an id.
101
- # person.preferences.find(BSON::ObjectId.new)
102
- #
103
- # @example Find by multiple ids.
104
- # person.preferences.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
105
- #
106
- # @example Conditionally find all matching documents.
107
- # person.preferences.find(:all, :conditions => { :title => "Sir" })
108
- #
109
- # @example Conditionally find the first document.
110
- # person.preferences.find(:first, :conditions => { :title => "Sir" })
111
- #
112
- # @example Conditionally find the last document.
113
- # person.preferences.find(:last, :conditions => { :title => "Sir" })
114
- #
115
- # @param [ Symbol, BSON::ObjectId, Array<BSON::ObjectId> ] arg The
116
- # argument to search with.
117
- # @param [ Hash ] options The options to search with.
118
- #
119
- # @return [ Document, Criteria ] The matching document(s).
120
- def find(arg, options = {})
121
- klass = metadata.klass
122
- return klass.criteria.id_criteria(arg) unless arg.is_a?(Symbol)
123
- selector = (options[:conditions] || {}).merge(
124
- "_id" => { "$in" => base.send(metadata.foreign_key) }
125
- )
126
- klass.find(arg, :conditions => selector)
127
- end
128
-
129
116
  # Removes all associations between the base document and the target
130
117
  # documents by deleting the foreign keys and the references, orphaning
131
118
  # the target documents in the process.
@@ -77,7 +77,9 @@ module Mongoid # :nodoc:
77
77
  # @since 2.0.0.rc.1
78
78
  def unbind(old_target, options = {})
79
79
  binding(old_target).unbind(options)
80
- old_target.delete if base.persisted? && !old_target.destroyed?
80
+ if base.persisted? && !old_target.destroyed? && !options[:binding]
81
+ old_target.delete
82
+ end
81
83
  end
82
84
 
83
85
  private
@@ -11,7 +11,7 @@ module Mongoid #:nodoc:
11
11
  field :updated_at, :type => Time
12
12
 
13
13
  set_callback :create, :before, :set_created_at
14
- set_callback :save, :before, :set_updated_at
14
+ set_callback :save, :before, :set_updated_at, :if => Proc.new {|d| d.new_record? || d.changed? }
15
15
 
16
16
  class_attribute :record_timestamps
17
17
  self.record_timestamps = true
@@ -27,15 +27,17 @@ module Mongoid #:nodoc:
27
27
  # @param [ Symbol ] attribute The relation to validate.
28
28
  # @param [ Object ] value The value of the relation.
29
29
  def validate_each(document, attribute, value)
30
- unless document.validated?
31
- document.validated = true
32
- valid = value.to_a.collect { |doc| doc.nil? || doc.valid? }.all?
33
- document.validated = false
34
- return if valid
35
- document.errors.add(attribute, :invalid, options.merge(:value => value))
36
- else
37
- document.validated = false
38
- end
30
+ document.validated = true
31
+ valid = Array.wrap(value).collect do |doc|
32
+ if doc.nil?
33
+ true
34
+ else
35
+ doc.validated? ? true : doc.valid?
36
+ end
37
+ end.all?
38
+ document.validated = false
39
+ return if valid
40
+ document.errors.add(attribute, :invalid, options.merge(:value => value))
39
41
  end
40
42
  end
41
43
  end
@@ -51,7 +51,7 @@ module Mongoid #:nodoc:
51
51
  document.errors.add(
52
52
  attribute,
53
53
  :taken,
54
- options.except(:case_sensistive, :scope).merge(:value => value)
54
+ options.except(:case_sensitive, :scope).merge(:value => value)
55
55
  )
56
56
  end
57
57
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc
3
- VERSION = "2.0.0.rc.6"
3
+ VERSION = "2.0.0.rc.7"
4
4
  end
@@ -10,7 +10,7 @@ module Mongoid #:nodoc:
10
10
  included do
11
11
  field :version, :type => Integer, :default => 1
12
12
  embeds_many :versions, :class_name => self.name, :validate => false
13
- set_callback :save, :before, :revise
13
+ set_callback :save, :before, :revise, :if => :changed?
14
14
 
15
15
  delegate :version_max, :to => "self.class"
16
16
  end
@@ -28,7 +28,7 @@ module Mongoid #:nodoc:
28
28
  versions.target << last_version.clone
29
29
  versions.shift if version_max.present? && versions.length > version_max
30
30
  self.version = (version || 1 ) + 1
31
- @modifications["versions"] = [ nil, versions.to_hash ] if @modifications
31
+ @modifications["versions"] = [ nil, versions.as_document ] if @modifications
32
32
  end
33
33
  end
34
34
 
metadata CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
7
7
  - 0
8
8
  - 0
9
9
  - rc
10
- - 6
11
- version: 2.0.0.rc.6
10
+ - 7
11
+ version: 2.0.0.rc.7
12
12
  platform: ruby
13
13
  authors:
14
14
  - Durran Jordan
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-01-19 00:00:00 +01:00
19
+ date: 2011-01-29 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -157,9 +157,11 @@ files:
157
157
  - lib/config/locales/pt-br.yml
158
158
  - lib/config/locales/pt.yml
159
159
  - lib/config/locales/ro.yml
160
+ - lib/config/locales/ru.yml
160
161
  - lib/config/locales/sv.yml
161
162
  - lib/config/locales/zh-CN.yml
162
163
  - lib/mongoid/atomicity.rb
164
+ - lib/mongoid/attributes/processing.rb
163
165
  - lib/mongoid/attributes.rb
164
166
  - lib/mongoid/callbacks.rb
165
167
  - lib/mongoid/collection.rb
@@ -254,7 +256,9 @@ files:
254
256
  - lib/mongoid/matchers/lte.rb
255
257
  - lib/mongoid/matchers/ne.rb
256
258
  - lib/mongoid/matchers/nin.rb
259
+ - lib/mongoid/matchers/or.rb
257
260
  - lib/mongoid/matchers/size.rb
261
+ - lib/mongoid/matchers/strategies.rb
258
262
  - lib/mongoid/matchers.rb
259
263
  - lib/mongoid/modifiers/command.rb
260
264
  - lib/mongoid/modifiers/inc.rb
@@ -303,6 +307,7 @@ files:
303
307
  - lib/mongoid/relations/cascading/nullify.rb
304
308
  - lib/mongoid/relations/cascading/strategy.rb
305
309
  - lib/mongoid/relations/cascading.rb
310
+ - lib/mongoid/relations/constraint.rb
306
311
  - lib/mongoid/relations/cyclic.rb
307
312
  - lib/mongoid/relations/embedded/in.rb
308
313
  - lib/mongoid/relations/embedded/many.rb
@@ -355,7 +360,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
355
360
  requirements:
356
361
  - - ">="
357
362
  - !ruby/object:Gem::Version
358
- hash: 1229276417221731393
363
+ hash: -2421077816225192598
359
364
  segments:
360
365
  - 0
361
366
  version: "0"