mongoid 2.3.5 → 2.4.0
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.
- data/CHANGELOG.md +34 -176
- data/LICENSE +1 -1
- data/lib/config/locales/bg.yml +6 -0
- data/lib/config/locales/de.yml +6 -0
- data/lib/config/locales/en-GB.yml +8 -0
- data/lib/config/locales/en.yml +8 -0
- data/lib/config/locales/es.yml +9 -3
- data/lib/config/locales/fr.yml +6 -0
- data/lib/config/locales/hi.yml +6 -0
- data/lib/config/locales/hu.yml +6 -0
- data/lib/config/locales/id.yml +6 -0
- data/lib/config/locales/it.yml +6 -0
- data/lib/config/locales/ja.yml +6 -0
- data/lib/config/locales/kr.yml +6 -0
- data/lib/config/locales/nl.yml +8 -0
- data/lib/config/locales/pl.yml +6 -0
- data/lib/config/locales/pt-BR.yml +6 -0
- data/lib/config/locales/pt.yml +8 -2
- data/lib/config/locales/ro.yml +6 -0
- data/lib/config/locales/ru.yml +6 -0
- data/lib/config/locales/sv.yml +6 -0
- data/lib/config/locales/vi.yml +14 -8
- data/lib/config/locales/zh-CN.yml +6 -0
- data/lib/mongoid/atomic.rb +62 -13
- data/lib/mongoid/atomic/modifiers.rb +33 -1
- data/lib/mongoid/attributes.rb +5 -19
- data/lib/mongoid/callbacks.rb +2 -1
- data/lib/mongoid/collection.rb +2 -2
- data/lib/mongoid/collections/retry.rb +18 -6
- data/lib/mongoid/components.rb +2 -0
- data/lib/mongoid/config.rb +8 -63
- data/lib/mongoid/config/environment.rb +41 -0
- data/lib/mongoid/config/options.rb +74 -0
- data/lib/mongoid/contexts/enumerable.rb +0 -24
- data/lib/mongoid/contexts/mongo.rb +33 -3
- data/lib/mongoid/copyable.rb +1 -1
- data/lib/mongoid/criteria.rb +4 -2
- data/lib/mongoid/criterion/inclusion.rb +1 -16
- data/lib/mongoid/criterion/optional.rb +37 -10
- data/lib/mongoid/criterion/scoping.rb +83 -0
- data/lib/mongoid/criterion/selector.rb +9 -6
- data/lib/mongoid/default_scope.rb +1 -1
- data/lib/mongoid/dirty.rb +163 -29
- data/lib/mongoid/document.rb +58 -7
- data/lib/mongoid/errors.rb +2 -0
- data/lib/mongoid/errors/no_environment.rb +19 -0
- data/lib/mongoid/errors/scope_overwrite.rb +21 -0
- data/lib/mongoid/extensions.rb +6 -0
- data/lib/mongoid/extensions/array/deep_copy.rb +25 -0
- data/lib/mongoid/extensions/hash/deep_copy.rb +25 -0
- data/lib/mongoid/extensions/hash/scoping.rb +1 -1
- data/lib/mongoid/extensions/object/deep_copy.rb +21 -0
- data/lib/mongoid/extensions/proc/scoping.rb +2 -2
- data/lib/mongoid/extensions/symbol/inflections.rb +1 -0
- data/lib/mongoid/fields.rb +171 -104
- data/lib/mongoid/fields/{serializable → internal}/array.rb +33 -1
- data/lib/mongoid/fields/{serializable → internal}/big_decimal.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/bignum.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/binary.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/boolean.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/date.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/date_time.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/fixnum.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/float.rb +16 -1
- data/lib/mongoid/fields/internal/foreign_keys/array.rb +74 -0
- data/lib/mongoid/fields/{serializable → internal}/foreign_keys/object.rb +11 -2
- data/lib/mongoid/fields/{serializable → internal}/hash.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/integer.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/localized.rb +23 -2
- data/lib/mongoid/fields/{serializable → internal}/nil_class.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/object.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/object_id.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/range.rb +21 -2
- data/lib/mongoid/fields/{serializable → internal}/set.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/string.rb +16 -1
- data/lib/mongoid/fields/{serializable → internal}/symbol.rb +17 -1
- data/lib/mongoid/fields/{serializable → internal}/time.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/time_with_zone.rb +1 -1
- data/lib/mongoid/fields/{serializable → internal}/timekeeping.rb +16 -1
- data/lib/mongoid/fields/mappings.rb +8 -3
- data/lib/mongoid/fields/serializable.rb +34 -3
- data/lib/mongoid/hierarchy.rb +14 -14
- data/lib/mongoid/identity_map.rb +3 -2
- data/lib/mongoid/logger.rb +1 -7
- data/lib/mongoid/named_scope.rb +16 -12
- data/lib/mongoid/observer.rb +5 -1
- data/lib/mongoid/paranoia.rb +1 -0
- data/lib/mongoid/persistence.rb +11 -4
- data/lib/mongoid/persistence/atomic.rb +4 -1
- data/lib/mongoid/persistence/atomic/add_to_set.rb +17 -1
- data/lib/mongoid/persistence/atomic/sets.rb +1 -1
- data/lib/mongoid/railties/database.rake +1 -1
- data/lib/mongoid/relations.rb +1 -3
- data/lib/mongoid/relations/auto_save.rb +1 -1
- data/lib/mongoid/relations/builders.rb +1 -1
- data/lib/mongoid/relations/builders/embedded/many.rb +2 -6
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -1
- data/lib/mongoid/relations/cascading/delete.rb +1 -1
- data/lib/mongoid/relations/cyclic.rb +10 -6
- data/lib/mongoid/relations/embedded/atomic.rb +3 -3
- data/lib/mongoid/relations/embedded/many.rb +98 -20
- data/lib/mongoid/relations/macros.rb +2 -0
- data/lib/mongoid/relations/many.rb +13 -0
- data/lib/mongoid/relations/metadata.rb +3 -3
- data/lib/mongoid/relations/nested_builder.rb +4 -3
- data/lib/mongoid/relations/proxy.rb +0 -1
- data/lib/mongoid/relations/referenced/batch.rb +3 -2
- data/lib/mongoid/relations/referenced/in.rb +3 -3
- data/lib/mongoid/relations/referenced/many.rb +89 -10
- data/lib/mongoid/relations/referenced/many_to_many.rb +34 -43
- data/lib/mongoid/relations/referenced/one.rb +8 -4
- data/lib/mongoid/relations/synchronization.rb +22 -5
- data/lib/mongoid/threaded.rb +38 -276
- data/lib/mongoid/threaded/lifecycle.rb +18 -18
- data/lib/mongoid/timestamps/updated.rb +13 -3
- data/lib/mongoid/validations.rb +22 -1
- data/lib/mongoid/validations/presence.rb +40 -0
- data/lib/mongoid/validations/uniqueness.rb +14 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +6 -2
- data/lib/rails/mongoid.rb +7 -1
- metadata +64 -45
- data/lib/mongoid/fields/serializable/foreign_keys/array.rb +0 -42
- data/lib/mongoid/relations/embedded/sort.rb +0 -31
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
module Config
|
|
4
|
+
|
|
5
|
+
# Encapsulates logic for getting environment information.
|
|
6
|
+
module Environment
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
# Get the name of the environment that we are running under. This first
|
|
10
|
+
# looks for Rails, then Sinatra, then a RACK_ENV environment variable,
|
|
11
|
+
# and if none of those are found returns "development".
|
|
12
|
+
#
|
|
13
|
+
# @example Get the env name.
|
|
14
|
+
# Environment.env_name
|
|
15
|
+
#
|
|
16
|
+
# @return [ String ] The name of the current environment.
|
|
17
|
+
#
|
|
18
|
+
# @since 2.3.0
|
|
19
|
+
def env_name
|
|
20
|
+
return Rails.env if defined?(Rails)
|
|
21
|
+
return Sinatra::Base.environment.to_s if defined?(Sinatra)
|
|
22
|
+
ENV["RACK_ENV"] || raise(Errors::NoEnvironment.new)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Load the yaml from the provided path and return the settings for the
|
|
26
|
+
# current environment.
|
|
27
|
+
#
|
|
28
|
+
# @example Load the yaml.
|
|
29
|
+
# Environment.load_yaml("/work/mongoid.yml")
|
|
30
|
+
#
|
|
31
|
+
# @param [ String ] path The location of the file.
|
|
32
|
+
#
|
|
33
|
+
# @return [ Hash ] The settings.
|
|
34
|
+
#
|
|
35
|
+
# @since 2.3.0
|
|
36
|
+
def load_yaml(path)
|
|
37
|
+
YAML.load(ERB.new(File.new(path).read).result)[env_name]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
module Config
|
|
4
|
+
|
|
5
|
+
# Encapsulates logic for setting options.
|
|
6
|
+
module Options
|
|
7
|
+
|
|
8
|
+
# Get the defaults or initialize a new empty hash.
|
|
9
|
+
#
|
|
10
|
+
# @example Get the defaults.
|
|
11
|
+
# options.defaults
|
|
12
|
+
#
|
|
13
|
+
# @return [ Hash ] The default options.
|
|
14
|
+
#
|
|
15
|
+
# @since 2.3.0
|
|
16
|
+
def defaults
|
|
17
|
+
@defaults ||= {}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Define a configuration option with a default.
|
|
21
|
+
#
|
|
22
|
+
# @example Define the option.
|
|
23
|
+
# Options.option(:persist_in_safe_mode, :default => false)
|
|
24
|
+
#
|
|
25
|
+
# @param [ Symbol ] name The name of the configuration option.
|
|
26
|
+
# @param [ Hash ] options Extras for the option.
|
|
27
|
+
#
|
|
28
|
+
# @option options [ Object ] :default The default value.
|
|
29
|
+
#
|
|
30
|
+
# @since 2.0.0.rc.1
|
|
31
|
+
def option(name, options = {})
|
|
32
|
+
defaults[name] = settings[name] = options[:default]
|
|
33
|
+
|
|
34
|
+
class_eval <<-RUBY
|
|
35
|
+
def #{name}
|
|
36
|
+
settings[#{name.inspect}]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def #{name}=(value)
|
|
40
|
+
settings[#{name.inspect}] = value
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def #{name}?
|
|
44
|
+
#{name}
|
|
45
|
+
end
|
|
46
|
+
RUBY
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Reset the configuration options to the defaults.
|
|
50
|
+
#
|
|
51
|
+
# @example Reset the configuration options.
|
|
52
|
+
# config.reset
|
|
53
|
+
#
|
|
54
|
+
# @return [ Hash ] The defaults.
|
|
55
|
+
#
|
|
56
|
+
# @since 2.3.0
|
|
57
|
+
def reset
|
|
58
|
+
settings.replace(defaults)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get the settings or initialize a new empty hash.
|
|
62
|
+
#
|
|
63
|
+
# @example Get the settings.
|
|
64
|
+
# options.settings
|
|
65
|
+
#
|
|
66
|
+
# @return [ Hash ] The setting options.
|
|
67
|
+
#
|
|
68
|
+
# @since 2.3.0
|
|
69
|
+
def settings
|
|
70
|
+
@settings ||= {}
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -210,18 +210,6 @@ module Mongoid #:nodoc:
|
|
|
210
210
|
|
|
211
211
|
protected
|
|
212
212
|
|
|
213
|
-
# Get the root class collection name.
|
|
214
|
-
#
|
|
215
|
-
# @example Get the root class collection name.
|
|
216
|
-
# context.collection_name
|
|
217
|
-
#
|
|
218
|
-
# @return [ String ] The name of the collection.
|
|
219
|
-
#
|
|
220
|
-
# @since 2.4.3
|
|
221
|
-
def collection_name
|
|
222
|
-
root ? root.collection_name : nil
|
|
223
|
-
end
|
|
224
|
-
|
|
225
213
|
# Filters the documents against the criteria's selector
|
|
226
214
|
#
|
|
227
215
|
# @example Filter the documents.
|
|
@@ -263,22 +251,10 @@ module Mongoid #:nodoc:
|
|
|
263
251
|
documents
|
|
264
252
|
end
|
|
265
253
|
|
|
266
|
-
# Get the root document for the enumerable.
|
|
267
|
-
#
|
|
268
|
-
# @example Get the root document.
|
|
269
|
-
# context.root
|
|
270
|
-
#
|
|
271
|
-
# @return [ Document ] The root.
|
|
272
254
|
def root
|
|
273
255
|
@root ||= documents.first.try(:_root)
|
|
274
256
|
end
|
|
275
257
|
|
|
276
|
-
# Get the root class for the enumerable.
|
|
277
|
-
#
|
|
278
|
-
# @example Get the root class.
|
|
279
|
-
# context.root_class
|
|
280
|
-
#
|
|
281
|
-
# @return [ Class ] The root class.
|
|
282
258
|
def root_class
|
|
283
259
|
@root_class ||= root ? root.class : nil
|
|
284
260
|
end
|
|
@@ -145,10 +145,40 @@ module Mongoid #:nodoc:
|
|
|
145
145
|
#
|
|
146
146
|
# @return [ Cursor ] An enumerable +Cursor+ of results.
|
|
147
147
|
def execute
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
collection, options = klass.collection, process_options
|
|
149
|
+
if criteria.inclusions.any?
|
|
150
|
+
collection.find(selector, options).entries.tap do |docs|
|
|
151
|
+
parent_ids = docs.map(&:id)
|
|
152
|
+
criteria.inclusions.reject! do |metadata|
|
|
153
|
+
if metadata.macro == :referenced_in
|
|
154
|
+
child_ids = load_ids(metadata.foreign_key)
|
|
155
|
+
metadata.eager_load(child_ids)
|
|
156
|
+
else
|
|
157
|
+
metadata.eager_load(parent_ids)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
else
|
|
162
|
+
collection.find(selector, options)
|
|
150
163
|
end
|
|
151
|
-
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Loads an array of ids only for the current criteria. Used by eager
|
|
167
|
+
# loading to determine the documents to load.
|
|
168
|
+
#
|
|
169
|
+
# @example Load the related ids.
|
|
170
|
+
# criteria.load_ids("person_id")
|
|
171
|
+
#
|
|
172
|
+
# @param [ String ] key The id or foriegn key string.
|
|
173
|
+
#
|
|
174
|
+
# @return [ Array<String, BSON::ObjectId> ] The ids to load.
|
|
175
|
+
#
|
|
176
|
+
# @since 2.2.0
|
|
177
|
+
def load_ids(key)
|
|
178
|
+
klass.collection.driver.find(
|
|
179
|
+
selector,
|
|
180
|
+
process_options.merge({ :fields => { key => 1 }})
|
|
181
|
+
).map { |doc| doc[key] }
|
|
152
182
|
end
|
|
153
183
|
|
|
154
184
|
# Return the first result for the +Context+.
|
data/lib/mongoid/copyable.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Mongoid #:nodoc:
|
|
|
31
31
|
#
|
|
32
32
|
# @return [ Document ] The new document.
|
|
33
33
|
def initialize_copy(other)
|
|
34
|
-
|
|
34
|
+
other.as_document
|
|
35
35
|
instance_variables.each { |name| remove_instance_variable(name) }
|
|
36
36
|
COPYABLES.each do |name|
|
|
37
37
|
value = other.instance_variable_get(name)
|
data/lib/mongoid/criteria.rb
CHANGED
|
@@ -6,6 +6,7 @@ require "mongoid/criterion/exclusion"
|
|
|
6
6
|
require "mongoid/criterion/inclusion"
|
|
7
7
|
require "mongoid/criterion/inspection"
|
|
8
8
|
require "mongoid/criterion/optional"
|
|
9
|
+
require "mongoid/criterion/scoping"
|
|
9
10
|
require "mongoid/criterion/selector"
|
|
10
11
|
|
|
11
12
|
module Mongoid #:nodoc:
|
|
@@ -29,6 +30,7 @@ module Mongoid #:nodoc:
|
|
|
29
30
|
include Criterion::Inclusion
|
|
30
31
|
include Criterion::Inspection
|
|
31
32
|
include Criterion::Optional
|
|
33
|
+
include Criterion::Scoping
|
|
32
34
|
|
|
33
35
|
attr_accessor \
|
|
34
36
|
:documents,
|
|
@@ -253,10 +255,10 @@ module Mongoid #:nodoc:
|
|
|
253
255
|
# scope for use with named scopes.
|
|
254
256
|
#
|
|
255
257
|
# @example Get the criteria as a scoped hash.
|
|
256
|
-
# criteria.
|
|
258
|
+
# criteria.as_conditions
|
|
257
259
|
#
|
|
258
260
|
# @return [ Hash ] The criteria as a scoped hash.
|
|
259
|
-
def
|
|
261
|
+
def as_conditions
|
|
260
262
|
scope_options = @options.dup
|
|
261
263
|
sorting = scope_options.delete(:sort)
|
|
262
264
|
scope_options[:order_by] = sorting if sorting
|
|
@@ -165,7 +165,7 @@ module Mongoid #:nodoc:
|
|
|
165
165
|
#
|
|
166
166
|
# @since 2.2.1
|
|
167
167
|
def from_map_or_db
|
|
168
|
-
doc = IdentityMap.get(klass, extract_id)
|
|
168
|
+
doc = IdentityMap.get(klass, extract_id || selector)
|
|
169
169
|
doc && doc.matches?(selector) ? doc : first
|
|
170
170
|
end
|
|
171
171
|
|
|
@@ -228,21 +228,6 @@ module Mongoid #:nodoc:
|
|
|
228
228
|
@inclusions ||= []
|
|
229
229
|
end
|
|
230
230
|
|
|
231
|
-
# Loads an array of ids only for the current criteria. Used by eager
|
|
232
|
-
# loading to determine the documents to load.
|
|
233
|
-
#
|
|
234
|
-
# @example Load the related ids.
|
|
235
|
-
# criteria.load_ids("person_id")
|
|
236
|
-
#
|
|
237
|
-
# @param [ String ] key The id or foriegn key string.
|
|
238
|
-
#
|
|
239
|
-
# @return [ Array<String, BSON::ObjectId> ] The ids to load.
|
|
240
|
-
#
|
|
241
|
-
# @since 2.2.0
|
|
242
|
-
def load_ids(key)
|
|
243
|
-
driver.find(selector, { :fields => { key => 1 }}).map { |doc| doc[key] }
|
|
244
|
-
end
|
|
245
|
-
|
|
246
231
|
# Adds a criterion to the +Criteria+ that specifies values to do
|
|
247
232
|
# geospacial searches by. The field must be indexed with the "2d" option.
|
|
248
233
|
#
|
|
@@ -15,8 +15,8 @@ module Mongoid #:nodoc:
|
|
|
15
15
|
# @return [ Criteria ] The cloned criteria.
|
|
16
16
|
def ascending(*fields)
|
|
17
17
|
clone.tap do |crit|
|
|
18
|
-
crit.options
|
|
19
|
-
fields.flatten.each { |field| merge_options(crit.options[:sort], [ field, :asc ]) }
|
|
18
|
+
setup_sort_options(crit.options) unless fields.first.nil?
|
|
19
|
+
fields.flatten.each { |field| merge_options(crit.options[:sort], [ localize(field), :asc ]) }
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
alias :asc :ascending
|
|
@@ -56,8 +56,8 @@ module Mongoid #:nodoc:
|
|
|
56
56
|
# @return [ Criteria ] The cloned criteria.
|
|
57
57
|
def descending(*fields)
|
|
58
58
|
clone.tap do |crit|
|
|
59
|
-
crit.options
|
|
60
|
-
fields.flatten.each { |field| merge_options(crit.options[:sort], [ field, :desc ]) }
|
|
59
|
+
setup_sort_options(crit.options) unless fields.first.nil?
|
|
60
|
+
fields.flatten.each { |field| merge_options(crit.options[:sort], [ localize(field), :desc ]) }
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
alias :desc :descending
|
|
@@ -89,11 +89,12 @@ module Mongoid #:nodoc:
|
|
|
89
89
|
#
|
|
90
90
|
# @return [ Criteria ] The cloned criteria.
|
|
91
91
|
def for_ids(*ids)
|
|
92
|
+
field = klass.fields["_id"]
|
|
92
93
|
ids.flatten!
|
|
93
94
|
if ids.size > 1
|
|
94
|
-
|
|
95
|
+
any_in(:_id => ids.map{ |id| field.serialize(id) })
|
|
95
96
|
else
|
|
96
|
-
where(:_id => ids.first)
|
|
97
|
+
where(:_id => field.serialize(ids.first))
|
|
97
98
|
end
|
|
98
99
|
end
|
|
99
100
|
|
|
@@ -135,7 +136,7 @@ module Mongoid #:nodoc:
|
|
|
135
136
|
def order_by(*args)
|
|
136
137
|
clone.tap do |crit|
|
|
137
138
|
arguments = args.size == 1 ? args.first : args
|
|
138
|
-
crit.options
|
|
139
|
+
setup_sort_options(crit.options) unless args.first.nil?
|
|
139
140
|
if arguments.is_a?(Array)
|
|
140
141
|
#[:name, :asc]
|
|
141
142
|
if arguments.size == 2 && (arguments.first.is_a?(Symbol) || arguments.first.is_a?(String))
|
|
@@ -198,12 +199,12 @@ module Mongoid #:nodoc:
|
|
|
198
199
|
"due to the fact that hash doesn't have order this may cause unpredictable results"
|
|
199
200
|
end
|
|
200
201
|
arguments.each_pair do |field, direction|
|
|
201
|
-
merge_options(crit.options[:sort], [ field, direction ])
|
|
202
|
+
merge_options(crit.options[:sort], [ localize(field), direction ])
|
|
202
203
|
end
|
|
203
204
|
when Array
|
|
204
|
-
merge_options(crit.options[:sort],arguments)
|
|
205
|
+
merge_options(crit.options[:sort], arguments.map{ |field| localize(field) })
|
|
205
206
|
when Complex
|
|
206
|
-
merge_options(crit.options[:sort], [ arguments.key, arguments.operator.to_sym ])
|
|
207
|
+
merge_options(crit.options[:sort], [ localize(arguments.key), arguments.operator.to_sym ])
|
|
207
208
|
end
|
|
208
209
|
end
|
|
209
210
|
|
|
@@ -227,6 +228,32 @@ module Mongoid #:nodoc:
|
|
|
227
228
|
options << new_option.flatten
|
|
228
229
|
end
|
|
229
230
|
end
|
|
231
|
+
|
|
232
|
+
# Initialize the sort options
|
|
233
|
+
# Set options[:sort] to an empty array if it does not exist, or dup it if
|
|
234
|
+
# it already has been defined
|
|
235
|
+
#
|
|
236
|
+
# @example criteria.setup_sort_options(crit.options)
|
|
237
|
+
#
|
|
238
|
+
# @param [ Array<Array> ] Existing options
|
|
239
|
+
#
|
|
240
|
+
# @since 2.4.0
|
|
241
|
+
def setup_sort_options(options)
|
|
242
|
+
options[:sort] = options[:sort] ? options[:sort].dup : []
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Check if field is localized and return localized version if it is.
|
|
246
|
+
#
|
|
247
|
+
# @example localize
|
|
248
|
+
# criteria.localize(:description)
|
|
249
|
+
#
|
|
250
|
+
# @param [ <Symbol> ] field to localize
|
|
251
|
+
def localize(field)
|
|
252
|
+
if klass.fields[field.to_s].try(:localized?)
|
|
253
|
+
field = "#{field}.#{::I18n.locale}".to_sym
|
|
254
|
+
end
|
|
255
|
+
field
|
|
256
|
+
end
|
|
230
257
|
end
|
|
231
258
|
end
|
|
232
259
|
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
module Scoping
|
|
5
|
+
|
|
6
|
+
attr_accessor :default_scopable
|
|
7
|
+
|
|
8
|
+
# Apply the model's default scope to this criteria.
|
|
9
|
+
#
|
|
10
|
+
# @example Apply the default scope.
|
|
11
|
+
# criteria.apply_default_scope
|
|
12
|
+
#
|
|
13
|
+
# @return [ Criteria ] The criteria.
|
|
14
|
+
#
|
|
15
|
+
# @since 2.4.0
|
|
16
|
+
def apply_default_scope
|
|
17
|
+
if klass.default_scoping && default_scopable?
|
|
18
|
+
self.default_scopable = false
|
|
19
|
+
fuse(klass.default_scoping)
|
|
20
|
+
else
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Is the default scope of the class allowed to be applied?
|
|
26
|
+
#
|
|
27
|
+
# @example Can the default scope be applied?
|
|
28
|
+
# criteria.default_scopable?
|
|
29
|
+
#
|
|
30
|
+
# @return [ true, false ] The the default can be applied.
|
|
31
|
+
#
|
|
32
|
+
# @since 2.4.0
|
|
33
|
+
def default_scopable?
|
|
34
|
+
default_scopable != false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Force the default scope to be applied to the criteria.
|
|
38
|
+
#
|
|
39
|
+
# @example Force default scoping.
|
|
40
|
+
# criteria.scoped
|
|
41
|
+
#
|
|
42
|
+
# @return [ Criteria ] The criteria.
|
|
43
|
+
#
|
|
44
|
+
# @since 2.4.0
|
|
45
|
+
def scoped
|
|
46
|
+
self.default_scopable = true
|
|
47
|
+
apply_default_scope
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Get the criteria with the default scoping removed.
|
|
51
|
+
#
|
|
52
|
+
# @note This has slightly different behaviour than AR - will remove the
|
|
53
|
+
# default scoping if no other criteria have been chained and tampered
|
|
54
|
+
# with the criterion instead of clearing everything.
|
|
55
|
+
#
|
|
56
|
+
# @example Get the criteria unscoped.
|
|
57
|
+
# criteria.unscoped
|
|
58
|
+
#
|
|
59
|
+
# @return [ Criteria ] The unscoped criteria.
|
|
60
|
+
#
|
|
61
|
+
# @since 2.4.0
|
|
62
|
+
def unscoped
|
|
63
|
+
clone.tap do |criteria|
|
|
64
|
+
criteria.clear_scoping
|
|
65
|
+
criteria.default_scopable = false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Remove all scoping from the criteria.
|
|
70
|
+
#
|
|
71
|
+
# @example Remove the default scope.
|
|
72
|
+
# criteria.clear_scoping
|
|
73
|
+
#
|
|
74
|
+
# @return [ nil ] No guaranteed return value.
|
|
75
|
+
#
|
|
76
|
+
# @since 2.4.0
|
|
77
|
+
def clear_scoping
|
|
78
|
+
selector.clear
|
|
79
|
+
options.clear
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|