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

Sign up to get free protection for your applications and to get access to all the features.
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"