mongoid 4.0.0 → 4.0.1

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -1
  3. data/README.md +6 -2
  4. data/lib/config/locales/en.yml +2 -2
  5. data/lib/mongoid/atomic.rb +2 -2
  6. data/lib/mongoid/attributes.rb +2 -0
  7. data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
  8. data/lib/mongoid/contextual/mongo.rb +3 -3
  9. data/lib/mongoid/criteria/#findable.rb# +141 -0
  10. data/lib/mongoid/document.rb +5 -5
  11. data/lib/mongoid/query_cache.rb +10 -2
  12. data/lib/mongoid/railtie.rb +2 -15
  13. data/lib/mongoid/railties/database.rake +1 -1
  14. data/lib/mongoid/relations/accessors.rb +2 -2
  15. data/lib/mongoid/relations/binding.rb +1 -1
  16. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +1 -1
  17. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  18. data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
  19. data/lib/mongoid/relations/counter_cache.rb +2 -2
  20. data/lib/mongoid/relations/one.rb +1 -1
  21. data/lib/mongoid/relations/referenced/many.rb +4 -4
  22. data/lib/mongoid/relations/referenced/many_to_many.rb +5 -5
  23. data/lib/mongoid/relations/synchronization.rb +4 -4
  24. data/lib/mongoid/relations/targets/enumerable.rb +10 -10
  25. data/lib/mongoid/reloadable.rb +3 -3
  26. data/lib/mongoid/threaded.rb +26 -15
  27. data/lib/mongoid/traversable.rb +6 -2
  28. data/lib/mongoid/validatable/uniqueness.rb +3 -3
  29. data/lib/mongoid/version.rb +1 -1
  30. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  31. data/spec/app/models/id_key.rb +6 -0
  32. data/spec/mongoid/#atomic_spec.rb# +365 -0
  33. data/spec/mongoid/attributes_spec.rb +36 -0
  34. data/spec/mongoid/contextual/atomic_spec.rb +7 -13
  35. data/spec/mongoid/criteria_spec.rb +86 -75
  36. data/spec/mongoid/document_spec.rb +2 -2
  37. data/spec/mongoid/findable_spec.rb +2 -2
  38. data/spec/mongoid/positional_spec.rb +5 -10
  39. data/spec/mongoid/query_cache_spec.rb +32 -0
  40. data/spec/mongoid/relations/referenced/many_spec.rb +23 -0
  41. data/spec/mongoid/reloadable_spec.rb +23 -0
  42. data/spec/spec_helper.rb +2 -0
  43. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f25ce5318d49b1e171f4e6fa2d4067eb933ecf0d
4
- data.tar.gz: 94846f4aff6c2ba1ccf34a63789b7503e536611b
3
+ metadata.gz: 1b25a1415535c09fc18f98e85225d38fd4e39877
4
+ data.tar.gz: 7dcb8aa291c865b59a10f2a7fa1508d2ae999850
5
5
  SHA512:
6
- metadata.gz: 96e54337599c2679fcb56acc7c817b1d119730f40d58eda3b0c8d2d4d66867c5c92ff6c475ce770ac52230fe8666ee29a1ecc81be1e8801a13359708bef76caf
7
- data.tar.gz: 693af581fa3e7c64cf8014a9ca3a4eb1c90baddfcb26c5162d1bd842da149092ad8c1d7ec34d5d4c45f9b58c739431e8f0a3a7794346798cb1cb469e08aa16d5
6
+ metadata.gz: 6087a7ef04b49630a195f2019c575ca50abb1fd46b96739f77a8dba22a9cc3b5c5bcf49771a91785bb88a68e68c4227589b1560da18e7555e872f0c3c5776329
7
+ data.tar.gz: a0a0c271e5fe084d0e2360cab8f4296629907f85422a0ce4d46212b348428bc49c8eaab9a713faf4a63aebd41acca86bc0cefdfd1932c143c0d9336509c86e5e
@@ -3,6 +3,23 @@
3
3
  For instructions on upgrading to newer versions, visit
4
4
  [mongoid.org](http://mongoid.org/en/mongoid/docs/upgrading.html).
5
5
 
6
+ ## 4.0.1
7
+
8
+ ### Resolved Issues
9
+
10
+ * \#3911 Fix relations named "parent". (nkriege)
11
+
12
+ * \#3792/\#3881 Fix many internal calls to #_id instead of #id to avoid issues
13
+ when overloading #id (Gauthier Delacroix)
14
+
15
+ * \#3847 Fix 'QueryCache#get_more' result, when collection has more documents than first query batch. (Angelica Korsun)
16
+
17
+ * \#3684 Dont raise MissingAttributeError, when using a only() scope. (Arthur Neves)
18
+
19
+ * \#3703 pluck method should not compact the values. (Arthur Neves)
20
+
21
+ * \#3773 Use nanoseconds for cache_key timestamp instead of plain seconds. (Máximo Mussini)
22
+
6
23
  ## 4.0.0
7
24
 
8
25
  ### Major Changes (Backwards Incompatible)
@@ -138,7 +155,7 @@ For instructions on upgrading to newer versions, visit
138
155
 
139
156
  * \#3138 `update_attributes` can now be accessed simply by calling `update`.
140
157
 
141
- * \#3083 A new rake task: `rake mongoid:remove_undefined_indexes` has been added to
158
+ * \#3083 A new rake task: `rake db:mongoid:remove_undefined_indexes` has been added to
142
159
  remove indexes from the database that are not explicitly defined in the models.
143
160
  (Aidan Feldman)
144
161
 
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
- Mongoid [![Build Status](https://travis-ci.org/mongoid/mongoid.svg)](https://travis-ci.org/mongoid/mongoid) [![Code Climate](https://codeclimate.com/github/mongoid/mongoid.png)](https://codeclimate.com/github/mongoid/mongoid) [![Coverage Status](https://coveralls.io/repos/mongoid/mongoid/badge.png?branch=master)](https://coveralls.io/r/mongoid/mongoid?branch=master) [![Gem Version](https://badge.fury.io/rb/mongoid.png)](http://badge.fury.io/rb/mongoid) [![Dependency Status](https://www.versioneye.com/ruby/mongoid/3.1.6/badge.png)](https://www.versioneye.com/ruby/mongoid/3.1.6)
2
- ========
1
+ # Mongoid
2
+ [![Build Status](https://travis-ci.org/mongoid/mongoid.svg)](https://travis-ci.org/mongoid/mongoid)
3
+ [![Code Climate](https://codeclimate.com/github/mongoid/mongoid.svg)](https://codeclimate.com/github/mongoid/mongoid)
4
+ [![Coverage Status](https://img.shields.io/coveralls/mongoid/mongoid/master.svg)](https://coveralls.io/r/mongoid/mongoid?branch=master)
5
+ [![Dependency Status](https://www.versioneye.com/ruby/mongoid/4.0.0/badge.svg)](https://www.versioneye.com/ruby/mongoid/4.0.0)
6
+
3
7
 
4
8
  Mongoid is an ODM (Object-Document-Mapper) framework for MongoDB in Ruby.
5
9
 
@@ -19,7 +19,7 @@ en:
19
19
  message: "Calling %{method} on %{klass} resulted in a false return
20
20
  from a callback."
21
21
  summary: "If a before callback returns false when using Document.create!,
22
- Document#save!, or Documnet#update_attributes! this error will get raised
22
+ Document#save!, or Document#update_attributes! this error will get raised
23
23
  since the document did not actually get saved."
24
24
  resolution: "Double check all before callbacks to make sure they are
25
25
  not unintentionally returning false."
@@ -336,7 +336,7 @@ en:
336
336
  %{klass}.create! without setting the parent document as an
337
337
  attribute."
338
338
  resolution: "Ensure that you've set the parent relation if
339
- instantiating the embedded document direcly, or always create new
339
+ instantiating the embedded document directly, or always create new
340
340
  embedded documents via the parent relation."
341
341
  no_session_config:
342
342
  message: "No configuration could be found for a session named
@@ -125,7 +125,7 @@ module Mongoid
125
125
  # @return [ Hash ] The updates and their modifiers.
126
126
  #
127
127
  # @since 2.1.0
128
- def atomic_updates(use_indexes = false)
128
+ def atomic_updates(_use_indexes = false)
129
129
  process_flagged_destroys
130
130
  mods = Modifiers.new
131
131
  generate_atomic_updates(mods, self)
@@ -206,7 +206,7 @@ module Mongoid
206
206
  path = nil
207
207
  ids = docs.map do |doc|
208
208
  path ||= doc.flag_as_destroyed
209
- doc.id
209
+ doc._id
210
210
  end
211
211
  pulls[path] = { "_id" => { "$in" => ids }} and path = nil
212
212
  end
@@ -31,6 +31,8 @@ module Mongoid
31
31
  def attribute_present?(name)
32
32
  attribute = read_attribute(name)
33
33
  !attribute.blank? || attribute == false
34
+ rescue ActiveModel::MissingAttributeError
35
+ false
34
36
  end
35
37
 
36
38
  # Get the attributes that have not been cast.
@@ -81,7 +81,7 @@ module Mongoid
81
81
  if block_given?
82
82
  super()
83
83
  else
84
- count > 0 ? super(0) { |doc| doc.send(field) } : 0
84
+ count > 0 ? super(0) { |doc| doc.public_send(field) } : 0
85
85
  end
86
86
  end
87
87
 
@@ -101,7 +101,7 @@ module Mongoid
101
101
  #
102
102
  # @since 3.0.0
103
103
  def aggregate_by(field, method)
104
- count > 0 ? send(method) { |doc| doc.send(field) }.send(field) : nil
104
+ count > 0 ? send(method) { |doc| doc.public_send(field) }.public_send(field) : nil
105
105
  end
106
106
  end
107
107
  end
@@ -54,7 +54,7 @@ module Mongoid
54
54
  def count(document = false, &block)
55
55
  return super(&block) if block_given?
56
56
  if document.is_a?(Document)
57
- return collection.find(criteria.and(_id: document.id).selector).count
57
+ return collection.find(criteria.and(_id: document._id).selector).count
58
58
  end
59
59
  return query.count(document) if document
60
60
  try_cache(:count) { query.count }
@@ -350,9 +350,9 @@ module Mongoid
350
350
  if normalized_select.size == 1
351
351
  doc[normalized_select.keys.first]
352
352
  else
353
- normalized_select.keys.map { |n| doc[n] }.compact
353
+ normalized_select.keys.map { |n| doc[n] }
354
354
  end
355
- end.compact
355
+ end
356
356
  end
357
357
 
358
358
  # Skips the provided number of documents.
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ class Criteria
4
+ module Findable
5
+
6
+ # Execute the criteria or raise an error if no documents found.
7
+ #
8
+ # @example Execute or raise
9
+ # criteria.execute_or_raise(id)
10
+ #
11
+ # @param [ Object ] args The arguments passed.
12
+ #
13
+ # @raise [ Errors::DocumentNotFound ] If nothing returned.
14
+ #
15
+ # @return [ Document, Array<Document> ] The document(s).
16
+ #
17
+ # @since 2.0.0
18
+ def execute_or_raise(ids, multi)
19
+ result = multiple_from_db(ids)
20
+ check_for_missing_documents!(result, ids)
21
+ multi ? result : result.first
22
+ end
23
+
24
+ # Find the matchind document(s) in the criteria for the provided ids.
25
+ #
26
+ # @example Find by an id.
27
+ # criteria.find(BSON::ObjectId.new)
28
+ #
29
+ # @example Find by multiple ids.
30
+ # criteria.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
31
+ #
32
+ # @param [ Array<BSON::ObjectId> ] args The ids to search for.
33
+ #
34
+ # @return [ Array<Document>, Document ] The matching document(s).
35
+ #
36
+ # @since 1.0.0
37
+ def find(*args)
38
+ ids = args.__find_args__
39
+ raise_invalid if ids.any?(&:nil?)
40
+ p "YOOO"
41
+ p ids
42
+ for_ids(ids).execute_or_raise(ids, args.multi_arged?)
43
+ end
44
+
45
+ # Adds a criterion to the +Criteria+ that specifies an id that must be matched.
46
+ #
47
+ # @example Add a single id criteria.
48
+ # criteria.for_ids([ 1 ])
49
+ #
50
+ # @example Add multiple id criteria.
51
+ # criteria.for_ids([ 1, 2 ])
52
+ #
53
+ # @param [ Array ] ids The array of ids.
54
+ #
55
+ # @return [ Criteria ] The cloned criteria.
56
+ def for_ids(ids)
57
+ ids = mongoize_ids(ids)
58
+ if ids.size > 1
59
+ send(id_finder, { _id: { "$in" => ids }})
60
+ else
61
+ send(id_finder, { _id: ids.first })
62
+ end
63
+ end
64
+
65
+ # Get the documents from the identity map, and if not found hit the
66
+ # database.
67
+ #
68
+ # @example Get the documents from the map or criteria.
69
+ # criteria.multiple_from_map_or_db(ids)
70
+ #
71
+ # @param [ ids ] The searched ids.
72
+ #
73
+ # @return [ Array<Document> ] The found documents.
74
+ def multiple_from_db(ids)
75
+ return entries if embedded?
76
+ ids = mongoize_ids(ids)
77
+ ids.empty? ? [] : from_database(ids)
78
+ end
79
+
80
+ private
81
+
82
+ # Get the finder used to generate the id query.
83
+ #
84
+ # @api private
85
+ #
86
+ # @example Get the id finder.
87
+ # criteria.id_finder
88
+ #
89
+ # @return [ Symbol ] The name of the finder method.
90
+ #
91
+ # @since 3.1.0
92
+ def id_finder
93
+ @id_finder ||= extract_id ? :all_of : :where
94
+ end
95
+
96
+ # Get documents from the database only.
97
+ #
98
+ # @api private
99
+ #
100
+ # @example Get documents from the database.
101
+ # criteria.from_database(ids)
102
+ #
103
+ # @param [ Array<Object> ] ids The ids to fetch with.
104
+ #
105
+ # @return [ Array<Document> ] The matching documents.
106
+ #
107
+ # @since 3.0.0
108
+ def from_database(ids)
109
+ (ids.size > 1 ? any_in(id: ids) : where(id: ids.first)).entries
110
+ end
111
+
112
+ # Convert all the ids to their proper types.
113
+ #
114
+ # @api private
115
+ #
116
+ # @example Convert the ids.
117
+ # criteria.mongoize_ids(ids)
118
+ #
119
+ # @param [ Array<Object> ] ids The ids to convert.
120
+ #
121
+ # @return [ Array<Object> ] The converted ids.
122
+ #
123
+ # @since 3.0.0
124
+ def mongoize_ids(ids)
125
+ ids.map{ |id| klass.fields["_id"].mongoize(id) }
126
+ end
127
+
128
+ # Convenience method of raising an invalid options error.
129
+ #
130
+ # @example Raise the error.
131
+ # criteria.raise_invalid
132
+ #
133
+ # @raise [ Errors::InvalidOptions ] The error.
134
+ #
135
+ # @since 2.0.0
136
+ def raise_invalid
137
+ raise Errors::InvalidFind.new
138
+ end
139
+ end
140
+ end
141
+ end
@@ -78,11 +78,11 @@ module Mongoid
78
78
  # @example Get the identity
79
79
  # document.identity
80
80
  #
81
- # @return [ Array ] An array containing [document.class, document.id]
81
+ # @return [ Array ] An array containing [document.class, document._id]
82
82
  #
83
83
  # @since 3.0.0
84
84
  def identity
85
- [ self.class, self.id ]
85
+ [ self.class, self._id ]
86
86
  end
87
87
 
88
88
  # Instantiate a new +Document+, setting the Document's attributes if
@@ -199,7 +199,7 @@ module Mongoid
199
199
  end
200
200
 
201
201
  became = klass.new(clone_document)
202
- became.id = id
202
+ became._id = _id
203
203
  became.instance_variable_set(:@changed_attributes, changed_attributes)
204
204
  became.instance_variable_set(:@errors, ActiveModel::Errors.new(became))
205
205
  became.errors.instance_variable_set(:@messages, errors.instance_variable_get(:@messages))
@@ -225,7 +225,7 @@ module Mongoid
225
225
  # plural model name.
226
226
  #
227
227
  # If new_record? - will append /new
228
- # If not - will append /id-updated_at.to_s(:number)
228
+ # If not - will append /id-updated_at.to_s(:nsec)
229
229
  # Without updated_at - will append /id
230
230
  #
231
231
  # This is usually called insode a cache() block
@@ -238,7 +238,7 @@ module Mongoid
238
238
  # @since 2.4.0
239
239
  def cache_key
240
240
  return "#{model_key}/new" if new_record?
241
- return "#{model_key}/#{id}-#{updated_at.utc.to_s(:number)}" if do_or_do_not(:updated_at)
241
+ return "#{model_key}/#{id}-#{updated_at.utc.to_s(:nsec)}" if do_or_do_not(:updated_at)
242
242
  "#{model_key}/#{id}"
243
243
  end
244
244
 
@@ -131,12 +131,16 @@ module Mongoid
131
131
 
132
132
  private
133
133
 
134
- def with_cache(context = :cursor, &block)
134
+ def with_cache(context = :cursor, more = false, &block)
135
135
  return yield unless QueryCache.enabled?
136
136
  return yield if system_collection?
137
137
  key = cache_key.push(context)
138
138
 
139
- if QueryCache.cache_table.has_key?(key)
139
+ if more
140
+ docs = yield
141
+ QueryCache.cache_table[key].push(*docs)
142
+ docs
143
+ elsif QueryCache.cache_table.has_key?(key)
140
144
  instrument(key) { QueryCache.cache_table[key] }
141
145
  else
142
146
  QueryCache.cache_table[key] = yield
@@ -230,6 +234,10 @@ module Mongoid
230
234
  with_cache { super }
231
235
  end
232
236
 
237
+ def get_more
238
+ with_cache(:cursor, true) { super }
239
+ end
240
+
233
241
  private
234
242
 
235
243
  def cache_key
@@ -13,19 +13,6 @@ module Rails
13
13
  # @since 2.0.0
14
14
  class Railtie < Rails::Railtie
15
15
 
16
- # Determine which generator to use. app_generators was introduced after
17
- # 3.0.0.
18
- #
19
- # @example Get the generators method.
20
- # railtie.generators
21
- #
22
- # @return [ Symbol ] The method name to use.
23
- #
24
- # @since 2.0.0.rc.4
25
- def self.generator
26
- config.respond_to?(:app_generators) ? :app_generators : :generators
27
- end
28
-
29
16
  # Mapping of rescued exceptions to HTTP responses
30
17
  #
31
18
  # @example
@@ -41,7 +28,7 @@ module Rails
41
28
  }
42
29
  end
43
30
 
44
- config.send(generator).orm :mongoid, migration: false
31
+ config.app_generators.orm :mongoid, migration: false
45
32
 
46
33
  if config.action_dispatch.rescue_responses
47
34
  config.action_dispatch.rescue_responses.merge!(rescue_responses)
@@ -98,7 +85,7 @@ module Rails
98
85
  # Due to all models not getting loaded and messing up inheritance queries
99
86
  # and indexing, we need to preload the models in order to address this.
100
87
  #
101
- # This will happen every request in development, once in ther other
88
+ # This will happen for every request in development, once in other
102
89
  # environments.
103
90
  #
104
91
  # @since 2.0.0
@@ -67,7 +67,7 @@ namespace :db do
67
67
 
68
68
  namespace :mongoid do
69
69
  task :load_models do
70
- ::Rails.application.eager_load!
70
+ ::Rails.application.eager_load! if defined?(Rails)
71
71
  end
72
72
  end
73
73
  end
@@ -12,7 +12,7 @@ module Mongoid
12
12
  # document is nil, then sets the relation on this document.
13
13
  #
14
14
  # @example Build the relation.
15
- # person.__build__(:addresses, { :id => 1 }, metadata)
15
+ # person.__build__(:addresses, { :_id => 1 }, metadata)
16
16
  #
17
17
  # @param [ String, Symbol ] name The name of the relation.
18
18
  # @param [ Hash, BSON::ObjectId ] object The id or attributes to use.
@@ -110,7 +110,7 @@ module Mongoid
110
110
 
111
111
  def needs_no_database_query?(object, metadata)
112
112
  object.is_a?(Document) && !object.embedded? &&
113
- object.id == attributes[metadata.key]
113
+ object._id == attributes[metadata.key]
114
114
  end
115
115
 
116
116
  # Is the current code executing without autobuild functionality?
@@ -91,7 +91,7 @@ module Mongoid
91
91
  # @api private
92
92
  #
93
93
  # @example Bind the foreign key.
94
- # binding.bind_foreign_key(post, person.id)
94
+ # binding.bind_foreign_key(post, person._id)
95
95
  #
96
96
  # @param [ Document ] keyed The document that stores the foreign key.
97
97
  # @param [ Object ] id The id of the bound document.
@@ -55,7 +55,7 @@ module Mongoid
55
55
  if inverse_metadata
56
56
  base.__send__(inverse_metadata.primary_key)
57
57
  else
58
- base.id
58
+ base._id
59
59
  end
60
60
  end
61
61
 
@@ -15,7 +15,7 @@ module Mongoid
15
15
  # @param [ String ] type Not used in this context.
16
16
  #
17
17
  # @return [ Document ] A single document.
18
- def build(type = nil)
18
+ def build(_type = nil)
19
19
  return object unless object.is_a?(Hash)
20
20
  if _loading? && base.persisted?
21
21
  Factory.from_db(klass, object)