mongoid 4.0.0 → 4.0.1

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