mongoid 4.0.0.alpha2 → 4.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +13 -0
  5. data/lib/mongoid.rb +3 -1
  6. data/lib/mongoid/atomic.rb +1 -1
  7. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  8. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  9. data/lib/mongoid/attributes.rb +23 -1
  10. data/lib/mongoid/attributes/processing.rb +1 -1
  11. data/lib/mongoid/composable.rb +3 -2
  12. data/lib/mongoid/contextual/command.rb +0 -26
  13. data/lib/mongoid/contextual/geo_near.rb +1 -1
  14. data/lib/mongoid/contextual/mongo.rb +6 -29
  15. data/lib/mongoid/contextual/text_search.rb +3 -5
  16. data/lib/mongoid/criteria.rb +1 -1
  17. data/lib/mongoid/criteria/modifiable.rb +27 -7
  18. data/lib/mongoid/criteria/permission.rb +70 -0
  19. data/lib/mongoid/document.rb +5 -6
  20. data/lib/mongoid/errors.rb +2 -0
  21. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  22. data/lib/mongoid/errors/readonly_document.rb +24 -0
  23. data/lib/mongoid/extensions/boolean.rb +1 -0
  24. data/lib/mongoid/extensions/hash.rb +1 -1
  25. data/lib/mongoid/factory.rb +5 -3
  26. data/lib/mongoid/fields.rb +32 -0
  27. data/lib/mongoid/fields/localized.rb +1 -1
  28. data/lib/mongoid/fields/standard.rb +1 -1
  29. data/lib/mongoid/findable.rb +1 -0
  30. data/lib/mongoid/interceptable.rb +11 -6
  31. data/lib/mongoid/log_subscriber.rb +34 -1
  32. data/lib/mongoid/persistable/deletable.rb +1 -0
  33. data/lib/mongoid/persistable/destroyable.rb +7 -2
  34. data/lib/mongoid/persistable/updatable.rb +27 -26
  35. data/lib/mongoid/query_cache.rb +246 -0
  36. data/lib/mongoid/railties/database.rake +4 -26
  37. data/lib/mongoid/relations.rb +8 -22
  38. data/lib/mongoid/relations/accessors.rb +0 -3
  39. data/lib/mongoid/relations/binding.rb +1 -1
  40. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  41. data/lib/mongoid/relations/eager.rb +5 -6
  42. data/lib/mongoid/relations/eager/base.rb +97 -5
  43. data/lib/mongoid/relations/eager/belongs_to.rb +1 -0
  44. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +16 -9
  45. data/lib/mongoid/relations/eager/has_many.rb +1 -0
  46. data/lib/mongoid/relations/eager/has_one.rb +1 -0
  47. data/lib/mongoid/relations/embedded/batchable.rb +1 -1
  48. data/lib/mongoid/relations/embedded/in.rb +4 -4
  49. data/lib/mongoid/relations/embedded/many.rb +7 -5
  50. data/lib/mongoid/relations/embedded/one.rb +1 -1
  51. data/lib/mongoid/relations/macros.rb +1 -0
  52. data/lib/mongoid/relations/marshalable.rb +3 -3
  53. data/lib/mongoid/relations/proxy.rb +12 -10
  54. data/lib/mongoid/relations/referenced/in.rb +2 -2
  55. data/lib/mongoid/relations/referenced/many.rb +9 -9
  56. data/lib/mongoid/relations/referenced/many_to_many.rb +7 -7
  57. data/lib/mongoid/relations/referenced/one.rb +4 -4
  58. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  59. data/lib/mongoid/tasks/database.rake +31 -0
  60. data/lib/mongoid/tasks/database.rb +107 -0
  61. data/lib/mongoid/threaded.rb +0 -47
  62. data/lib/mongoid/validatable/uniqueness.rb +4 -16
  63. data/lib/mongoid/version.rb +1 -1
  64. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +0 -3
  65. data/lib/rails/mongoid.rb +0 -124
  66. data/spec/app/models/edit.rb +5 -0
  67. data/spec/app/models/even.rb +7 -0
  68. data/spec/app/models/line_item.rb +1 -1
  69. data/spec/app/models/note.rb +2 -0
  70. data/spec/app/models/odd.rb +7 -0
  71. data/spec/app/models/record.rb +5 -0
  72. data/spec/app/models/wiki_page.rb +1 -1
  73. data/spec/mongoid/attributes_spec.rb +76 -1
  74. data/spec/mongoid/changeable_spec.rb +6 -2
  75. data/spec/mongoid/contextual/mongo_spec.rb +3 -1
  76. data/spec/mongoid/contextual/text_search_spec.rb +3 -1
  77. data/spec/mongoid/criteria/modifiable_spec.rb +192 -0
  78. data/spec/mongoid/criteria_spec.rb +6 -2
  79. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  80. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  81. data/spec/mongoid/fields/localized_spec.rb +15 -0
  82. data/spec/mongoid/fields_spec.rb +88 -2
  83. data/spec/mongoid/log_subscriber_spec.rb +3 -3
  84. data/spec/mongoid/persistable/deletable_spec.rb +14 -1
  85. data/spec/mongoid/persistable/destroyable_spec.rb +45 -1
  86. data/spec/mongoid/persistable/savable_spec.rb +34 -5
  87. data/spec/mongoid/query_cache_spec.rb +197 -0
  88. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +2 -2
  89. data/spec/mongoid/relations/builders/referenced/many_spec.rb +1 -1
  90. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +11 -37
  91. data/spec/mongoid/relations/eager/has_one_spec.rb +1 -1
  92. data/spec/mongoid/relations/embedded/in_spec.rb +1 -1
  93. data/spec/mongoid/relations/embedded/many_spec.rb +10 -10
  94. data/spec/mongoid/relations/embedded/one_spec.rb +10 -2
  95. data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
  96. data/spec/mongoid/relations/referenced/many_spec.rb +37 -2
  97. data/spec/mongoid/relations/touchable_spec.rb +20 -0
  98. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +26 -1
  99. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  100. data/spec/mongoid/tasks/database_spec.rb +148 -0
  101. data/spec/mongoid/validatable/uniqueness_spec.rb +7 -0
  102. data/spec/rails/mongoid_spec.rb +0 -316
  103. data/spec/spec_helper.rb +1 -0
  104. metadata +30 -8
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  module Mongoid
2
3
  module Relations
3
4
  module Eager
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  module Mongoid
2
3
  module Relations
3
4
  module Eager
@@ -9,18 +10,24 @@ module Mongoid
9
10
  set_relation(d, [])
10
11
  end
11
12
 
12
- entries = Hash.new { |hash, key| hash[key] = [] }
13
+ entries = {}
13
14
  each_loaded_document do |doc|
15
+ entries[doc.send(key)] = doc
16
+ end
14
17
 
15
- ids = doc.send(key)
16
- ids.each do |id|
17
- entries[id] << doc
18
- end
18
+ @docs.each do |d|
19
+ keys = d.send(group_by_key)
20
+ docs = entries.values_at(*keys)
21
+ set_relation(d, docs)
19
22
  end
23
+ end
20
24
 
21
- entries.each do |id, docs|
22
- set_on_parent(id, docs)
25
+ def keys_from_docs
26
+ keys = Set.new
27
+ @docs.each do |d|
28
+ keys += d.send(group_by_key)
23
29
  end
30
+ keys.to_a
24
31
  end
25
32
 
26
33
  def set_relation(doc, element)
@@ -28,11 +35,11 @@ module Mongoid
28
35
  end
29
36
 
30
37
  def group_by_key
31
- @metadata.primary_key
38
+ @metadata.foreign_key
32
39
  end
33
40
 
34
41
  def key
35
- @metadata.inverse_foreign_key
42
+ @metadata.primary_key
36
43
  end
37
44
  end
38
45
  end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  module Mongoid
2
3
  module Relations
3
4
  module Eager
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  module Mongoid
2
3
  module Relations
3
4
  module Eager
@@ -198,7 +198,7 @@ module Mongoid
198
198
  def normalize_docs(docs)
199
199
  if docs.first.is_a?(::Hash)
200
200
  docs.map do |doc|
201
- attributes = { metadata: metadata, _parent: base }
201
+ attributes = { __metadata: __metadata, _parent: base }
202
202
  attributes.merge!(doc)
203
203
  Factory.build(klass, attributes)
204
204
  end
@@ -61,7 +61,7 @@ module Mongoid
61
61
  #
62
62
  # @since 2.0.0.rc.1
63
63
  def binding
64
- Bindings::Embedded::In.new(base, target, metadata)
64
+ Bindings::Embedded::In.new(base, target, __metadata)
65
65
  end
66
66
 
67
67
  # Characterize the document.
@@ -73,8 +73,8 @@ module Mongoid
73
73
  #
74
74
  # @since 2.1.0
75
75
  def characterize_one(document)
76
- unless base.metadata
77
- base.metadata = metadata.inverse_metadata(document)
76
+ unless base.__metadata
77
+ base.__metadata = __metadata.inverse_metadata(document)
78
78
  end
79
79
  end
80
80
 
@@ -209,7 +209,7 @@ module Mongoid
209
209
  #
210
210
  # @since 2.1.0
211
211
  def valid_options
212
- [ :autobuild, :cyclic, :polymorphic ]
212
+ [ :autobuild, :cyclic, :polymorphic, :touch ]
213
213
  end
214
214
 
215
215
  # Get the default validation setting for the relation. Determines if
@@ -79,7 +79,7 @@ module Mongoid
79
79
  #
80
80
  # @return [ Document ] The new document.
81
81
  def build(attributes = {}, type = nil)
82
- doc = Factory.build(type || metadata.klass, attributes)
82
+ doc = Factory.build(type || __metadata.klass, attributes)
83
83
  append(doc)
84
84
  doc.apply_post_processed_defaults
85
85
  yield(doc) if block_given?
@@ -341,7 +341,7 @@ module Mongoid
341
341
  #
342
342
  # @since 2.0.0.rc.1
343
343
  def binding
344
- Bindings::Embedded::Many.new(base, target, metadata)
344
+ Bindings::Embedded::Many.new(base, target, __metadata)
345
345
  end
346
346
 
347
347
  # Returns the criteria object for the target class with its documents set
@@ -355,7 +355,9 @@ module Mongoid
355
355
  criterion = klass.scoped
356
356
  criterion.embedded = true
357
357
  criterion.documents = target
358
- Many.apply_ordering(criterion, metadata)
358
+ criterion.parent_document = base
359
+ criterion.metadata = relation_metadata
360
+ Many.apply_ordering(criterion, __metadata)
359
361
  end
360
362
 
361
363
  # Deletes one document from the target and unscoped.
@@ -443,8 +445,8 @@ module Mongoid
443
445
  #
444
446
  # @since 2.4.0
445
447
  def scope(docs)
446
- return docs unless metadata.order || metadata.klass.default_scoping?
447
- crit = metadata.klass.order_by(metadata.order)
448
+ return docs unless __metadata.order || __metadata.klass.default_scoping?
449
+ crit = __metadata.klass.order_by(__metadata.order)
448
450
  crit.embedded = true
449
451
  crit.documents = docs
450
452
  crit.entries
@@ -66,7 +66,7 @@ module Mongoid
66
66
  #
67
67
  # @since 2.0.0.rc.1
68
68
  def binding
69
- Bindings::Embedded::One.new(base, target, metadata)
69
+ Bindings::Embedded::One.new(base, target, __metadata)
70
70
  end
71
71
 
72
72
  # Are we able to persist this relation?
@@ -55,6 +55,7 @@ module Mongoid
55
55
  self.embedded = true
56
56
  relate(name, meta)
57
57
  builder(name, meta).creator(name, meta)
58
+ touchable(meta)
58
59
  add_counter_cache_callbacks(meta) if meta.counter_cached?
59
60
  meta
60
61
  end
@@ -12,7 +12,7 @@ module Mongoid
12
12
  #
13
13
  # @since 3.0.15
14
14
  def marshal_dump
15
- [ base, target, metadata ]
15
+ [ base, target, __metadata ]
16
16
  end
17
17
 
18
18
  # Takes the provided data and sets it back on the proxy.
@@ -24,8 +24,8 @@ module Mongoid
24
24
  #
25
25
  # @since 3.0.15
26
26
  def marshal_load(data)
27
- @base, @target, @metadata = data
28
- extend_proxy(metadata.extension) if metadata.extension?
27
+ @base, @target, @__metadata = data
28
+ extend_proxy(__metadata.extension) if __metadata.extension?
29
29
  end
30
30
  end
31
31
  end
@@ -18,10 +18,11 @@ module Mongoid
18
18
  include Threaded::Lifecycle
19
19
  include Marshalable
20
20
 
21
- attr_accessor :base, :metadata, :target
21
+ attr_accessor :base, :__metadata, :target
22
+ alias :relation_metadata :__metadata
22
23
 
23
24
  # Backwards compatibility with Mongoid beta releases.
24
- delegate :foreign_key, :inverse_foreign_key, to: :metadata
25
+ delegate :foreign_key, :inverse_foreign_key, to: :__metadata
25
26
  delegate :bind_one, :unbind_one, to: :binding
26
27
  delegate :collection_name, to: :base
27
28
 
@@ -37,7 +38,7 @@ module Mongoid
37
38
  #
38
39
  # @since 2.0.0.rc.1
39
40
  def init(base, target, metadata)
40
- @base, @target, @metadata = base, target, metadata
41
+ @base, @target, @__metadata = base, target, metadata
41
42
  yield(self) if block_given?
42
43
  extend_proxies(metadata.extension) if metadata.extension?
43
44
  end
@@ -56,7 +57,7 @@ module Mongoid
56
57
  #
57
58
  # @since 3.0.15
58
59
  def klass
59
- metadata ? metadata.klass : nil
60
+ __metadata ? __metadata.klass : nil
60
61
  end
61
62
 
62
63
  # Resets the criteria inside the relation proxy. Used by many to many
@@ -137,7 +138,7 @@ module Mongoid
137
138
  #
138
139
  # @since 2.0.0.rc.4
139
140
  def characterize_one(document)
140
- document.metadata = metadata unless document.metadata
141
+ document.__metadata = __metadata unless document.__metadata
141
142
  end
142
143
 
143
144
  # Default behavior of method missing should be to delegate all calls
@@ -159,7 +160,7 @@ module Mongoid
159
160
  #
160
161
  # @since 2.0.0
161
162
  def raise_mixed
162
- raise Errors::MixedRelations.new(base.class, metadata.klass)
163
+ raise Errors::MixedRelations.new(base.class, __metadata.klass)
163
164
  end
164
165
 
165
166
  # When the base is not yet saved and the user calls create or create!
@@ -189,11 +190,12 @@ module Mongoid
189
190
  # @since 3.1.0
190
191
  def callback_method(callback_name)
191
192
  methods = []
192
- if metadata[callback_name]
193
- if metadata[callback_name].is_a? Array
194
- methods.concat(metadata[callback_name])
193
+ metadata = __metadata[callback_name]
194
+ if metadata
195
+ if metadata.is_a?(Array)
196
+ methods.concat(metadata)
195
197
  else
196
- methods << metadata[callback_name]
198
+ methods << metadata
197
199
  end
198
200
  end
199
201
  methods
@@ -71,7 +71,7 @@ module Mongoid
71
71
  #
72
72
  # @since 2.0.0.rc.1
73
73
  def binding
74
- Bindings::Referenced::In.new(base, target, metadata)
74
+ Bindings::Referenced::In.new(base, target, __metadata)
75
75
  end
76
76
 
77
77
  # Normalize the value provided as a replacement for substitution.
@@ -88,7 +88,7 @@ module Mongoid
88
88
  # @since 3.1.5
89
89
  def normalize(replacement)
90
90
  return replacement if replacement.is_a?(Document)
91
- metadata.builder(klass, replacement).build
91
+ __metadata.builder(klass, replacement).build
92
92
  end
93
93
 
94
94
  # Are we able to persist this relation?
@@ -245,7 +245,7 @@ module Mongoid
245
245
  #
246
246
  # @since 2.0.0.beta.1
247
247
  def purge
248
- unless metadata.destructive?
248
+ unless __metadata.destructive?
249
249
  nullify
250
250
  else
251
251
  after_remove_error = nil
@@ -304,7 +304,7 @@ module Mongoid
304
304
  # @since 2.4.0
305
305
  def unscoped
306
306
  klass.unscoped.where(
307
- foreign_key => Conversions.flag(base.id, metadata)
307
+ foreign_key => Conversions.flag(base.id, __metadata)
308
308
  )
309
309
  end
310
310
 
@@ -340,7 +340,7 @@ module Mongoid
340
340
  #
341
341
  # @since 2.0.0.rc.1
342
342
  def binding
343
- Bindings::Referenced::Many.new(base, target, metadata)
343
+ Bindings::Referenced::Many.new(base, target, __metadata)
344
344
  end
345
345
 
346
346
  # Get the collection of the relation in question.
@@ -366,8 +366,8 @@ module Mongoid
366
366
  # @since 2.0.0.beta.1
367
367
  def criteria
368
368
  Many.criteria(
369
- metadata,
370
- Conversions.flag(base.send(metadata.primary_key), metadata),
369
+ __metadata,
370
+ Conversions.flag(base.send(__metadata.primary_key), __metadata),
371
371
  base.class
372
372
  )
373
373
  end
@@ -385,8 +385,8 @@ module Mongoid
385
385
  # @since 2.1.0
386
386
  def cascade!(document)
387
387
  if persistable?
388
- if metadata.destructive?
389
- document.send(metadata.dependent)
388
+ if __metadata.destructive?
389
+ document.send(__metadata.dependent)
390
390
  else
391
391
  document.save
392
392
  end
@@ -486,7 +486,7 @@ module Mongoid
486
486
  # @since 2.4.0
487
487
  def remove_not_in(ids)
488
488
  removed = criteria.not_in(_id: ids)
489
- if metadata.destructive?
489
+ if __metadata.destructive?
490
490
  removed.delete_all
491
491
  else
492
492
  removed.update_all(foreign_key => nil)
@@ -495,7 +495,7 @@ module Mongoid
495
495
  if !ids.include?(doc.id)
496
496
  unbind_one(doc)
497
497
  target.delete(doc)
498
- if metadata.destructive?
498
+ if __metadata.destructive?
499
499
  doc.destroyed = true
500
500
  end
501
501
  end
@@ -29,7 +29,7 @@ module Mongoid
29
29
  return concat(docs) if docs.size > 1
30
30
  if doc = docs.first
31
31
  append(doc)
32
- base.add_to_set(foreign_key => doc.send(metadata.primary_key))
32
+ base.add_to_set(foreign_key => doc.send(__metadata.primary_key))
33
33
  if child_persistable?(doc)
34
34
  doc.save
35
35
  end
@@ -114,7 +114,7 @@ module Mongoid
114
114
  def delete(document)
115
115
  doc = super
116
116
  if doc && persistable?
117
- base.pull(foreign_key => doc.send(metadata.primary_key))
117
+ base.pull(foreign_key => doc.send(__metadata.primary_key))
118
118
  target._unloaded = criteria
119
119
  unsynced(base, foreign_key)
120
120
  end
@@ -133,7 +133,7 @@ module Mongoid
133
133
  target.each do |doc|
134
134
  execute_callback :before_remove, doc
135
135
  end
136
- unless metadata.forced_nil_inverse?
136
+ unless __metadata.forced_nil_inverse?
137
137
  criteria.pull(inverse_foreign_key => base.id)
138
138
  end
139
139
  if persistable?
@@ -142,7 +142,7 @@ module Mongoid
142
142
  after_remove_error = nil
143
143
  many_to_many = target.clear do |doc|
144
144
  unbind_one(doc)
145
- unless metadata.forced_nil_inverse?
145
+ unless __metadata.forced_nil_inverse?
146
146
  doc.changed_attributes.delete(inverse_foreign_key)
147
147
  end
148
148
  begin
@@ -221,7 +221,7 @@ module Mongoid
221
221
  #
222
222
  # @since 2.0.0.rc.1
223
223
  def binding
224
- Bindings::Referenced::ManyToMany.new(base, target, metadata)
224
+ Bindings::Referenced::ManyToMany.new(base, target, __metadata)
225
225
  end
226
226
 
227
227
  # Determine if the child document should be persisted.
@@ -238,7 +238,7 @@ module Mongoid
238
238
  # @since 3.0.20
239
239
  def child_persistable?(doc)
240
240
  (persistable? || _creating?) &&
241
- !(doc.persisted? && metadata.forced_nil_inverse?)
241
+ !(doc.persisted? && __metadata.forced_nil_inverse?)
242
242
  end
243
243
 
244
244
  # Returns the criteria object for the target class with its documents set
@@ -249,7 +249,7 @@ module Mongoid
249
249
  #
250
250
  # @return [ Criteria ] A new criteria.
251
251
  def criteria
252
- ManyToMany.criteria(metadata, base.send(foreign_key))
252
+ ManyToMany.criteria(__metadata, base.send(foreign_key))
253
253
  end
254
254
 
255
255
  # Flag the base as unsynced with respect to the foreign key.
@@ -53,13 +53,13 @@ module Mongoid
53
53
  def substitute(replacement)
54
54
  unbind_one
55
55
  if persistable?
56
- if metadata.destructive?
57
- send(metadata.dependent)
56
+ if __metadata.destructive?
57
+ send(__metadata.dependent)
58
58
  else
59
59
  save if persisted?
60
60
  end
61
61
  end
62
- One.new(base, replacement, metadata) if replacement
62
+ One.new(base, replacement, __metadata) if replacement
63
63
  end
64
64
 
65
65
  private
@@ -73,7 +73,7 @@ module Mongoid
73
73
  #
74
74
  # @return [ Binding ] The binding object.
75
75
  def binding
76
- Bindings::Referenced::One.new(base, target, metadata)
76
+ Bindings::Referenced::One.new(base, target, __metadata)
77
77
  end
78
78
 
79
79
  # Are we able to persist this relation?
@@ -3,7 +3,7 @@ module Mongoid
3
3
 
4
4
  # This module contains the behaviour for getting the various states a
5
5
  # document can transition through.
6
- module State
6
+ module Stateful
7
7
 
8
8
  attr_writer :destroyed, :flagged_for_destroy, :new_record
9
9
 
@@ -70,6 +70,18 @@ module Mongoid
70
70
  !_parent.delayed_atomic_sets[atomic_path]
71
71
  end
72
72
 
73
+ # Is the document readonly?
74
+ #
75
+ # @example Is the document readonly?
76
+ # document.readonly?
77
+ #
78
+ # @return [ true, false ] If the document is readonly.
79
+ #
80
+ # @since 4.0.0
81
+ def readonly?
82
+ __selected_fields != nil
83
+ end
84
+
73
85
  # Determine if the document can be set.
74
86
  #
75
87
  # @example Is this settable?