mongoid 2.3.0 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +56 -2
- data/lib/config/locales/bg.yml +2 -0
- data/lib/config/locales/de.yml +2 -0
- data/lib/config/locales/en-GB.yml +2 -0
- data/lib/config/locales/en.yml +2 -0
- data/lib/config/locales/es.yml +2 -0
- data/lib/config/locales/fr.yml +2 -0
- data/lib/config/locales/hi.yml +2 -0
- data/lib/config/locales/hu.yml +2 -0
- data/lib/config/locales/id.yml +2 -0
- data/lib/config/locales/it.yml +2 -0
- data/lib/config/locales/ja.yml +2 -0
- data/lib/config/locales/kr.yml +2 -0
- data/lib/config/locales/nl.yml +2 -0
- data/lib/config/locales/pl.yml +2 -0
- data/lib/config/locales/pt-BR.yml +2 -0
- data/lib/config/locales/pt.yml +2 -0
- data/lib/config/locales/ro.yml +2 -0
- data/lib/config/locales/ru.yml +2 -0
- data/lib/config/locales/sv.yml +2 -0
- data/lib/config/locales/vi.yml +2 -0
- data/lib/config/locales/zh-CN.yml +2 -0
- data/lib/mongoid/contexts/mongo.rb +1 -1
- data/lib/mongoid/criterion/inclusion.rb +39 -40
- data/lib/mongoid/criterion/selector.rb +5 -0
- data/lib/mongoid/dirty.rb +4 -26
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/invalid_time.rb +25 -0
- data/lib/mongoid/extensions.rb +2 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +1 -2
- data/lib/mongoid/extensions/object_id/conversions.rb +2 -4
- data/lib/mongoid/extensions/string/checks.rb +12 -0
- data/lib/mongoid/extensions/symbol/checks.rb +23 -0
- data/lib/mongoid/extras.rb +0 -22
- data/lib/mongoid/fields.rb +1 -1
- data/lib/mongoid/fields/serializable.rb +14 -7
- data/lib/mongoid/fields/serializable/timekeeping.rb +6 -2
- data/lib/mongoid/named_scope.rb +7 -3
- data/lib/mongoid/nested_attributes.rb +0 -12
- data/lib/mongoid/paranoia.rb +62 -8
- data/lib/mongoid/railties/database.rake +6 -3
- data/lib/mongoid/relations.rb +15 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -2
- data/lib/mongoid/relations/cascading.rb +0 -12
- data/lib/mongoid/relations/embedded/many.rb +28 -9
- data/lib/mongoid/relations/macros.rb +8 -18
- data/lib/mongoid/relations/metadata.rb +2 -5
- data/lib/mongoid/relations/polymorphic.rb +0 -25
- data/lib/mongoid/relations/referenced/many.rb +29 -10
- data/lib/mongoid/relations/referenced/many_to_many.rb +13 -3
- data/lib/mongoid/relations/targets/enumerable.rb +2 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +1 -13
- metadata +21 -19
data/lib/mongoid/errors.rb
CHANGED
@@ -8,6 +8,7 @@ require "mongoid/errors/invalid_database"
|
|
8
8
|
require "mongoid/errors/invalid_field"
|
9
9
|
require "mongoid/errors/invalid_find"
|
10
10
|
require "mongoid/errors/invalid_options"
|
11
|
+
require "mongoid/errors/invalid_time"
|
11
12
|
require "mongoid/errors/invalid_type"
|
12
13
|
require "mongoid/errors/mixed_relations"
|
13
14
|
require "mongoid/errors/too_many_nested_attribute_records"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc
|
3
|
+
module Errors #:nodoc
|
4
|
+
|
5
|
+
# This exception is raised when a bad value is attempted to be converted to
|
6
|
+
# a date or time.
|
7
|
+
class InvalidTime < MongoidError
|
8
|
+
|
9
|
+
attr_reader :klass, :value
|
10
|
+
|
11
|
+
# Create the new invalid date error.
|
12
|
+
#
|
13
|
+
# @example Create the new invalid date error.
|
14
|
+
# InvalidTime.new("this is not a time")
|
15
|
+
#
|
16
|
+
# @param [ Object ] value The value that was attempted.
|
17
|
+
#
|
18
|
+
# @since 2.3.1
|
19
|
+
def initialize(value)
|
20
|
+
@value = value
|
21
|
+
super(translate("invalid_time", { :value => value }))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/mongoid/extensions.rb
CHANGED
@@ -13,6 +13,7 @@ require "mongoid/extensions/proc/scoping"
|
|
13
13
|
require "mongoid/extensions/string/checks"
|
14
14
|
require "mongoid/extensions/string/conversions"
|
15
15
|
require "mongoid/extensions/string/inflections"
|
16
|
+
require "mongoid/extensions/symbol/checks"
|
16
17
|
require "mongoid/extensions/symbol/inflections"
|
17
18
|
require "mongoid/extensions/true_class/equality"
|
18
19
|
require "mongoid/extensions/object_id/conversions"
|
@@ -62,6 +63,7 @@ end
|
|
62
63
|
|
63
64
|
class Symbol #:nodoc
|
64
65
|
remove_method :size if instance_methods.include? :size # temporal fix for ruby 1.9
|
66
|
+
include Mongoid::Extensions::Symbol::Checks
|
65
67
|
include Mongoid::Extensions::Symbol::Inflections
|
66
68
|
end
|
67
69
|
|
@@ -17,8 +17,7 @@ module Mongoid #:nodoc:
|
|
17
17
|
def expand_complex_criteria
|
18
18
|
{}.tap do |hsh|
|
19
19
|
each_pair do |k,v|
|
20
|
-
|
21
|
-
when Mongoid::Criterion::Complex
|
20
|
+
if k.respond_to?(:key) && k.respond_to?(:to_mongo_query)
|
22
21
|
hsh[k.key] ||= {}
|
23
22
|
hsh[k.key].merge!(k.to_mongo_query(v))
|
24
23
|
else
|
@@ -38,7 +38,7 @@ module Mongoid #:nodoc:
|
|
38
38
|
if args.unconvertable_to_bson?
|
39
39
|
args
|
40
40
|
else
|
41
|
-
BSON::ObjectId.from_string(args)
|
41
|
+
BSON::ObjectId.legal?(args) ? BSON::ObjectId.from_string(args) : args
|
42
42
|
end
|
43
43
|
when ::Array
|
44
44
|
args.delete_if { |arg| arg.blank? } if reject_blank
|
@@ -47,9 +47,7 @@ module Mongoid #:nodoc:
|
|
47
47
|
args.tap do |hash|
|
48
48
|
hash.each_pair do |key, value|
|
49
49
|
next unless klass.object_id_field?(key)
|
50
|
-
|
51
|
-
hash[key] = convert(klass, value, reject_blank)
|
52
|
-
rescue BSON::InvalidObjectId; end
|
50
|
+
hash[key] = convert(klass, value, reject_blank)
|
53
51
|
end
|
54
52
|
end
|
55
53
|
else
|
@@ -7,6 +7,18 @@ module Mongoid #:nodoc:
|
|
7
7
|
module Checks #:nodoc:
|
8
8
|
attr_accessor :unconvertable_to_bson
|
9
9
|
|
10
|
+
# Is the string a valid value for a Mongoid id?
|
11
|
+
#
|
12
|
+
# @example Is the string an id value?
|
13
|
+
# "_id".mongoid_id?
|
14
|
+
#
|
15
|
+
# @return [ true, false ] If the string is id or _id.
|
16
|
+
#
|
17
|
+
# @since 2.3.1
|
18
|
+
def mongoid_id?
|
19
|
+
self =~ /^(|_)id$/
|
20
|
+
end
|
21
|
+
|
10
22
|
# Is the object not to be converted to bson on criteria creation?
|
11
23
|
#
|
12
24
|
# @example Is the object unconvertable?
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Extensions #:nodoc:
|
4
|
+
module Symbol #:nodoc:
|
5
|
+
|
6
|
+
# This module has object checks in it.
|
7
|
+
module Checks #:nodoc:
|
8
|
+
|
9
|
+
# Is the symbol a valid value for a Mongoid id?
|
10
|
+
#
|
11
|
+
# @example Is the string an id value?
|
12
|
+
# :_id.mongoid_id?
|
13
|
+
#
|
14
|
+
# @return [ true, false ] If the symbol is :id or :_id.
|
15
|
+
#
|
16
|
+
# @since 2.3.1
|
17
|
+
def mongoid_id?
|
18
|
+
to_s =~ /^(|_)id$/
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/mongoid/extras.rb
CHANGED
@@ -10,18 +10,6 @@ module Mongoid #:nodoc:
|
|
10
10
|
self.cached = false
|
11
11
|
end
|
12
12
|
|
13
|
-
# Is the class cached?
|
14
|
-
#
|
15
|
-
# @note Refactored from using delegate for class load performance.
|
16
|
-
#
|
17
|
-
# @example Is the class cached?
|
18
|
-
# person.cached?
|
19
|
-
#
|
20
|
-
# @return [ true, false ] If the class is cached.
|
21
|
-
def cached?
|
22
|
-
self.class.cached?
|
23
|
-
end
|
24
|
-
|
25
13
|
module ClassMethods #:nodoc
|
26
14
|
|
27
15
|
# Sets caching on for this class. This class level configuration will
|
@@ -38,16 +26,6 @@ module Mongoid #:nodoc:
|
|
38
26
|
def cache
|
39
27
|
self.cached = true
|
40
28
|
end
|
41
|
-
|
42
|
-
# Determines if the class is cached or not.
|
43
|
-
#
|
44
|
-
# @example Are class reads cached?
|
45
|
-
# Document.cached?
|
46
|
-
#
|
47
|
-
# @return [ true, false ] If the reads are cached.
|
48
|
-
def cached?
|
49
|
-
!!self.cached
|
50
|
-
end
|
51
29
|
end
|
52
30
|
end
|
53
31
|
end
|
data/lib/mongoid/fields.rb
CHANGED
@@ -231,7 +231,7 @@ module Mongoid #:nodoc
|
|
231
231
|
type = options[:localize] ? Fields::Serializable::Localized : options[:type]
|
232
232
|
Mappings.for(type, options[:identity]).instantiate(name, options).tap do |field|
|
233
233
|
fields[name] = field
|
234
|
-
defaults << name unless field.
|
234
|
+
defaults << name unless field.default_val.nil?
|
235
235
|
create_accessors(name, meth, options)
|
236
236
|
process_options(field)
|
237
237
|
define_attribute_method(name)
|
@@ -25,8 +25,15 @@ module Mongoid #:nodoc:
|
|
25
25
|
module Serializable
|
26
26
|
extend ActiveSupport::Concern
|
27
27
|
|
28
|
+
included do
|
29
|
+
# @todo: Durran: Pull out in 3.0.0
|
30
|
+
unless method_defined?(:default)
|
31
|
+
alias :default :default_val
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
28
35
|
# Set readers for the instance variables.
|
29
|
-
attr_accessor :
|
36
|
+
attr_accessor :default_val, :label, :localize, :name, :options
|
30
37
|
|
31
38
|
# When reading the field do we need to cast the value? This holds true when
|
32
39
|
# times are stored or for big decimals which are stored as strings.
|
@@ -82,10 +89,10 @@ module Mongoid #:nodoc:
|
|
82
89
|
#
|
83
90
|
# @since 2.1.8
|
84
91
|
def eval_default(doc)
|
85
|
-
if
|
86
|
-
serialize(doc.instance_exec(&
|
92
|
+
if default_val.respond_to?(:call)
|
93
|
+
serialize(doc.instance_exec(&default_val))
|
87
94
|
else
|
88
|
-
serialize(
|
95
|
+
serialize(default_val.duplicable? ? default_val.dup : default_val)
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
@@ -182,9 +189,9 @@ module Mongoid #:nodoc:
|
|
182
189
|
field.options = options
|
183
190
|
field.label = options[:label]
|
184
191
|
field.localize = options[:localize]
|
185
|
-
field.
|
186
|
-
unless field.
|
187
|
-
field.
|
192
|
+
field.default_val = options[:default]
|
193
|
+
unless field.default_val
|
194
|
+
field.default_val = {} if field.localized?
|
188
195
|
end
|
189
196
|
end
|
190
197
|
end
|
@@ -51,8 +51,12 @@ module Mongoid #:nodoc:
|
|
51
51
|
# @since 2.1.0
|
52
52
|
def serialize(object)
|
53
53
|
return nil if object.blank?
|
54
|
-
|
55
|
-
|
54
|
+
begin
|
55
|
+
time = convert_to_time(object)
|
56
|
+
strip_milliseconds(time).utc
|
57
|
+
rescue ArgumentError
|
58
|
+
raise Errors::InvalidTime.new(object)
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
# Convert the provided object to a UTC time to store in the database.
|
data/lib/mongoid/named_scope.rb
CHANGED
@@ -123,12 +123,16 @@ module Mongoid #:nodoc:
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
-
|
126
|
+
protected
|
127
127
|
|
128
128
|
def valid_scope_name?(name)
|
129
129
|
if !scopes[name] && respond_to?(name, true)
|
130
|
-
Mongoid.logger
|
131
|
-
|
130
|
+
if Mongoid.logger
|
131
|
+
Mongoid.logger.warn(
|
132
|
+
"Creating scope :#{name}. " +
|
133
|
+
"Overwriting existing method #{self.name}.#{name}."
|
134
|
+
)
|
135
|
+
end
|
132
136
|
end
|
133
137
|
end
|
134
138
|
end
|
@@ -10,18 +10,6 @@ module Mongoid #:nodoc:
|
|
10
10
|
self.nested_attributes = []
|
11
11
|
end
|
12
12
|
|
13
|
-
# Get the nested attributes.
|
14
|
-
#
|
15
|
-
# @note Refactored from using delegate for class load performance.
|
16
|
-
#
|
17
|
-
# @example Get the nested attributes.
|
18
|
-
# model.nested_attributes
|
19
|
-
#
|
20
|
-
# @return [ Array<String> ] The nested attributes methods.
|
21
|
-
def nested_attributes
|
22
|
-
self.class.nested_attributes
|
23
|
-
end
|
24
|
-
|
25
13
|
module ClassMethods #:nodoc:
|
26
14
|
|
27
15
|
REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |_, value| value.blank? } }
|
data/lib/mongoid/paranoia.rb
CHANGED
@@ -22,6 +22,10 @@ module Mongoid #:nodoc:
|
|
22
22
|
#
|
23
23
|
# @example Hard destroy the document.
|
24
24
|
# document.destroy!
|
25
|
+
#
|
26
|
+
# @return [ true, false ] If the operation succeeded.
|
27
|
+
#
|
28
|
+
# @since 1.0.0
|
25
29
|
def destroy!
|
26
30
|
run_callbacks(:destroy) { delete! }
|
27
31
|
end
|
@@ -30,8 +34,11 @@ module Mongoid #:nodoc:
|
|
30
34
|
#
|
31
35
|
# @example Hard delete the document.
|
32
36
|
# document.delete!
|
37
|
+
#
|
38
|
+
# @return [ true, false ] If the operation succeeded.
|
39
|
+
#
|
40
|
+
# @since 1.0.0
|
33
41
|
def delete!
|
34
|
-
@destroyed = true
|
35
42
|
Persistence::Operations.remove(self).persist
|
36
43
|
end
|
37
44
|
|
@@ -44,10 +51,19 @@ module Mongoid #:nodoc:
|
|
44
51
|
# @param [ Hash ] options The database options.
|
45
52
|
#
|
46
53
|
# @return [ true ] True.
|
54
|
+
#
|
55
|
+
# @since 1.0.0
|
47
56
|
def remove(options = {})
|
48
|
-
|
49
|
-
|
50
|
-
|
57
|
+
time = self.deleted_at = Time.now
|
58
|
+
paranoid_collection.update(
|
59
|
+
atomic_selector,
|
60
|
+
{ "$set" => { paranoid_field => time }},
|
61
|
+
Safety.merge_safety_options(options)
|
62
|
+
)
|
63
|
+
cascade!
|
64
|
+
@destroyed = true
|
65
|
+
IdentityMap.remove(self)
|
66
|
+
Threaded.clear_options!
|
51
67
|
true
|
52
68
|
end
|
53
69
|
alias :delete :remove
|
@@ -56,9 +72,10 @@ module Mongoid #:nodoc:
|
|
56
72
|
#
|
57
73
|
# @example Is the document destroyed?
|
58
74
|
# person.destroyed?
|
59
|
-
|
60
75
|
#
|
61
76
|
# @return [ true, false ] If the document is destroyed.
|
77
|
+
#
|
78
|
+
# @since 1.0.0
|
62
79
|
def destroyed?
|
63
80
|
@destroyed || !!deleted_at
|
64
81
|
end
|
@@ -68,9 +85,42 @@ module Mongoid #:nodoc:
|
|
68
85
|
#
|
69
86
|
# @example Restore the document from deleted state.
|
70
87
|
# document.restore
|
88
|
+
#
|
89
|
+
# @return [ Time ] The time the document had been deleted.
|
90
|
+
#
|
91
|
+
# @since 1.0.0
|
71
92
|
def restore
|
72
|
-
|
73
|
-
|
93
|
+
paranoid_collection.update(
|
94
|
+
atomic_selector,
|
95
|
+
{ "$unset" => { paranoid_field => true }}
|
96
|
+
)
|
97
|
+
attributes.delete("deleted_at")
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# Get the collection to be used for paranoid operations.
|
103
|
+
#
|
104
|
+
# @example Get the paranoid collection.
|
105
|
+
# document.paranoid_collection
|
106
|
+
#
|
107
|
+
# @return [ Collection ] The root collection.
|
108
|
+
#
|
109
|
+
# @since 2.3.1
|
110
|
+
def paranoid_collection
|
111
|
+
embedded? ? _root.collection : self.collection
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get the field to be used for paranoid operations.
|
115
|
+
#
|
116
|
+
# @example Get the paranoid field.
|
117
|
+
# document.paranoid_field
|
118
|
+
#
|
119
|
+
# @return [ String ] The deleted at field.
|
120
|
+
#
|
121
|
+
# @since 2.3.1
|
122
|
+
def paranoid_field
|
123
|
+
embedded? ? "#{atomic_position}.deleted_at" : "deleted_at"
|
74
124
|
end
|
75
125
|
|
76
126
|
module ClassMethods #:nodoc:
|
@@ -84,8 +134,10 @@ module Mongoid #:nodoc:
|
|
84
134
|
# @param [ Array ] args The arguments.
|
85
135
|
#
|
86
136
|
# @return [ Criteria ] The paranoid compliant criteria.
|
137
|
+
#
|
138
|
+
# @since 1.0.0
|
87
139
|
def criteria(embedded = false, scoped = true)
|
88
|
-
scoped ? super.
|
140
|
+
scoped ? super.where(:deleted_at => nil) : super
|
89
141
|
end
|
90
142
|
|
91
143
|
# Find deleted documents
|
@@ -96,6 +148,8 @@ module Mongoid #:nodoc:
|
|
96
148
|
# Person.deleted.find("4c188dea7b17235a2a000001").first
|
97
149
|
#
|
98
150
|
# @return [ Criteria ] The deleted criteria.
|
151
|
+
#
|
152
|
+
# @since 1.0.0
|
99
153
|
def deleted
|
100
154
|
where(:deleted_at.ne => nil)
|
101
155
|
end
|
@@ -2,9 +2,7 @@ namespace :db do
|
|
2
2
|
|
3
3
|
unless Rake::Task.task_defined?("db:drop")
|
4
4
|
desc 'Drops all the collections for the database for the current Rails.env'
|
5
|
-
task :drop => :
|
6
|
-
Mongoid.master.collections.select {|c| c.name !~ /system/ }.each { |c| c.drop }
|
7
|
-
end
|
5
|
+
task :drop => "mongoid:drop"
|
8
6
|
end
|
9
7
|
|
10
8
|
unless Rake::Task.task_defined?("db:seed")
|
@@ -171,6 +169,11 @@ namespace :db do
|
|
171
169
|
end
|
172
170
|
end
|
173
171
|
|
172
|
+
desc "Drops the database for the current Rails.env"
|
173
|
+
task :drop => :environment do
|
174
|
+
Mongoid.master.collections.select {|c| c.name !~ /system/ }.each { |c| c.drop }
|
175
|
+
end
|
176
|
+
|
174
177
|
########
|
175
178
|
# TODO: lots more useful db tasks can be added here. stuff like copyDatabase, etc
|
176
179
|
########
|
data/lib/mongoid/relations.rb
CHANGED
@@ -125,5 +125,20 @@ module Mongoid # :nodoc:
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
128
|
+
|
129
|
+
module ClassMethods #:nodoc:
|
130
|
+
|
131
|
+
# This is convenience for librarys still on the old API.
|
132
|
+
#
|
133
|
+
# @example Get the associations.
|
134
|
+
# Person.associations
|
135
|
+
#
|
136
|
+
# @return [ Hash ] The relations.
|
137
|
+
#
|
138
|
+
# @since 2.3.1
|
139
|
+
def associations
|
140
|
+
self.relations
|
141
|
+
end
|
142
|
+
end
|
128
143
|
end
|
129
144
|
end
|
@@ -31,7 +31,7 @@ module Mongoid # :nodoc:
|
|
31
31
|
if inverse_metadata != metadata && !inverse_metadata.nil?
|
32
32
|
base.metadata = inverse_metadata
|
33
33
|
if base.referenced_many?
|
34
|
-
target.send(inverse).push(base)
|
34
|
+
target.send(inverse).push(base) unless Mongoid.identity_map_enabled?
|
35
35
|
else
|
36
36
|
target.do_or_do_not(metadata.inverse_setter(target), base)
|
37
37
|
end
|