mongoid 4.0.0 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -1
- data/README.md +6 -2
- data/lib/config/locales/en.yml +2 -2
- data/lib/mongoid/atomic.rb +2 -2
- data/lib/mongoid/attributes.rb +2 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
- data/lib/mongoid/contextual/mongo.rb +3 -3
- data/lib/mongoid/criteria/#findable.rb# +141 -0
- data/lib/mongoid/document.rb +5 -5
- data/lib/mongoid/query_cache.rb +10 -2
- data/lib/mongoid/railtie.rb +2 -15
- data/lib/mongoid/railties/database.rake +1 -1
- data/lib/mongoid/relations/accessors.rb +2 -2
- data/lib/mongoid/relations/binding.rb +1 -1
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +1 -1
- data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/counter_cache.rb +2 -2
- data/lib/mongoid/relations/one.rb +1 -1
- data/lib/mongoid/relations/referenced/many.rb +4 -4
- data/lib/mongoid/relations/referenced/many_to_many.rb +5 -5
- data/lib/mongoid/relations/synchronization.rb +4 -4
- data/lib/mongoid/relations/targets/enumerable.rb +10 -10
- data/lib/mongoid/reloadable.rb +3 -3
- data/lib/mongoid/threaded.rb +26 -15
- data/lib/mongoid/traversable.rb +6 -2
- data/lib/mongoid/validatable/uniqueness.rb +3 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
- data/spec/app/models/id_key.rb +6 -0
- data/spec/mongoid/#atomic_spec.rb# +365 -0
- data/spec/mongoid/attributes_spec.rb +36 -0
- data/spec/mongoid/contextual/atomic_spec.rb +7 -13
- data/spec/mongoid/criteria_spec.rb +86 -75
- data/spec/mongoid/document_spec.rb +2 -2
- data/spec/mongoid/findable_spec.rb +2 -2
- data/spec/mongoid/positional_spec.rb +5 -10
- data/spec/mongoid/query_cache_spec.rb +32 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +23 -0
- data/spec/mongoid/reloadable_spec.rb +23 -0
- data/spec/spec_helper.rb +2 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b25a1415535c09fc18f98e85225d38fd4e39877
|
4
|
+
data.tar.gz: 7dcb8aa291c865b59a10f2a7fa1508d2ae999850
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6087a7ef04b49630a195f2019c575ca50abb1fd46b96739f77a8dba22a9cc3b5c5bcf49771a91785bb88a68e68c4227589b1560da18e7555e872f0c3c5776329
|
7
|
+
data.tar.gz: a0a0c271e5fe084d0e2360cab8f4296629907f85422a0ce4d46212b348428bc49c8eaab9a713faf4a63aebd41acca86bc0cefdfd1932c143c0d9336509c86e5e
|
data/CHANGELOG.md
CHANGED
@@ -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
|
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
|
|
data/lib/config/locales/en.yml
CHANGED
@@ -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
|
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
|
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
|
data/lib/mongoid/atomic.rb
CHANGED
@@ -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(
|
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.
|
209
|
+
doc._id
|
210
210
|
end
|
211
211
|
pulls[path] = { "_id" => { "$in" => ids }} and path = nil
|
212
212
|
end
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -81,7 +81,7 @@ module Mongoid
|
|
81
81
|
if block_given?
|
82
82
|
super()
|
83
83
|
else
|
84
|
-
count > 0 ? super(0) { |doc| doc.
|
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.
|
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.
|
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] }
|
353
|
+
normalized_select.keys.map { |n| doc[n] }
|
354
354
|
end
|
355
|
-
end
|
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
|
data/lib/mongoid/document.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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(:
|
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(:
|
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
|
|
data/lib/mongoid/query_cache.rb
CHANGED
@@ -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
|
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
|
data/lib/mongoid/railtie.rb
CHANGED
@@ -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.
|
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
|
88
|
+
# This will happen for every request in development, once in other
|
102
89
|
# environments.
|
103
90
|
#
|
104
91
|
# @since 2.0.0
|
@@ -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, { :
|
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.
|
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.
|
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.
|
@@ -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(
|
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)
|