mongoid 4.0.0.alpha2 → 4.0.0.beta1

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