mongoid-braxton 2.0.2
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/LICENSE +20 -0
- data/README.rdoc +50 -0
- data/Rakefile +51 -0
- data/lib/config/locales/bg.yml +41 -0
- data/lib/config/locales/de.yml +41 -0
- data/lib/config/locales/en.yml +45 -0
- data/lib/config/locales/es.yml +41 -0
- data/lib/config/locales/fr.yml +42 -0
- data/lib/config/locales/hu.yml +44 -0
- data/lib/config/locales/id.yml +46 -0
- data/lib/config/locales/it.yml +39 -0
- data/lib/config/locales/ja.yml +40 -0
- data/lib/config/locales/kr.yml +65 -0
- data/lib/config/locales/nl.yml +39 -0
- data/lib/config/locales/pl.yml +39 -0
- data/lib/config/locales/pt-BR.yml +40 -0
- data/lib/config/locales/pt.yml +40 -0
- data/lib/config/locales/ro.yml +46 -0
- data/lib/config/locales/ru.yml +41 -0
- data/lib/config/locales/sv.yml +40 -0
- data/lib/config/locales/vi.yml +45 -0
- data/lib/config/locales/zh-CN.yml +33 -0
- data/lib/mongoid.rb +140 -0
- data/lib/mongoid/atomicity.rb +111 -0
- data/lib/mongoid/attributes.rb +185 -0
- data/lib/mongoid/attributes/processing.rb +145 -0
- data/lib/mongoid/callbacks.rb +23 -0
- data/lib/mongoid/collection.rb +137 -0
- data/lib/mongoid/collections.rb +71 -0
- data/lib/mongoid/collections/master.rb +37 -0
- data/lib/mongoid/collections/operations.rb +42 -0
- data/lib/mongoid/collections/retry.rb +39 -0
- data/lib/mongoid/components.rb +45 -0
- data/lib/mongoid/config.rb +349 -0
- data/lib/mongoid/config/database.rb +167 -0
- data/lib/mongoid/config/replset_database.rb +78 -0
- data/lib/mongoid/contexts.rb +19 -0
- data/lib/mongoid/contexts/enumerable.rb +275 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/mongo.rb +345 -0
- data/lib/mongoid/copyable.rb +46 -0
- data/lib/mongoid/criteria.rb +357 -0
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/complex.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +108 -0
- data/lib/mongoid/criterion/inclusion.rb +198 -0
- data/lib/mongoid/criterion/inspection.rb +22 -0
- data/lib/mongoid/criterion/optional.rb +193 -0
- data/lib/mongoid/criterion/selector.rb +143 -0
- data/lib/mongoid/criterion/unconvertable.rb +20 -0
- data/lib/mongoid/cursor.rb +86 -0
- data/lib/mongoid/default_scope.rb +36 -0
- data/lib/mongoid/dirty.rb +253 -0
- data/lib/mongoid/document.rb +284 -0
- data/lib/mongoid/errors.rb +13 -0
- data/lib/mongoid/errors/document_not_found.rb +29 -0
- data/lib/mongoid/errors/invalid_collection.rb +19 -0
- data/lib/mongoid/errors/invalid_database.rb +20 -0
- data/lib/mongoid/errors/invalid_field.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +16 -0
- data/lib/mongoid/errors/invalid_type.rb +26 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/errors/mongoid_error.rb +27 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +21 -0
- data/lib/mongoid/errors/validations.rb +24 -0
- data/lib/mongoid/extensions.rb +123 -0
- data/lib/mongoid/extensions/array/conversions.rb +23 -0
- data/lib/mongoid/extensions/array/parentization.rb +13 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
- data/lib/mongoid/extensions/date/conversions.rb +25 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
- data/lib/mongoid/extensions/false_class/equality.rb +13 -0
- data/lib/mongoid/extensions/float/conversions.rb +20 -0
- data/lib/mongoid/extensions/hash/conversions.rb +19 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +20 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
- data/lib/mongoid/extensions/object/checks.rb +32 -0
- data/lib/mongoid/extensions/object/conversions.rb +25 -0
- data/lib/mongoid/extensions/object/reflections.rb +17 -0
- data/lib/mongoid/extensions/object/yoda.rb +27 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +96 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/range/conversions.rb +25 -0
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/extensions/string/conversions.rb +34 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +38 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extras.rb +42 -0
- data/lib/mongoid/factory.rb +37 -0
- data/lib/mongoid/field.rb +162 -0
- data/lib/mongoid/fields.rb +183 -0
- data/lib/mongoid/finders.rb +127 -0
- data/lib/mongoid/hierarchy.rb +85 -0
- data/lib/mongoid/identity.rb +92 -0
- data/lib/mongoid/indexes.rb +38 -0
- data/lib/mongoid/inspection.rb +54 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +131 -0
- data/lib/mongoid/logger.rb +18 -0
- data/lib/mongoid/matchers.rb +32 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +70 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/or.rb +30 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/matchers/strategies.rb +63 -0
- data/lib/mongoid/multi_database.rb +11 -0
- data/lib/mongoid/multi_parameter_attributes.rb +82 -0
- data/lib/mongoid/named_scope.rb +137 -0
- data/lib/mongoid/nested_attributes.rb +51 -0
- data/lib/mongoid/observer.rb +67 -0
- data/lib/mongoid/paranoia.rb +103 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence.rb +240 -0
- data/lib/mongoid/persistence/atomic.rb +88 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +32 -0
- data/lib/mongoid/persistence/atomic/inc.rb +28 -0
- data/lib/mongoid/persistence/atomic/operation.rb +44 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
- data/lib/mongoid/persistence/atomic/push.rb +28 -0
- data/lib/mongoid/persistence/command.rb +71 -0
- data/lib/mongoid/persistence/insert.rb +53 -0
- data/lib/mongoid/persistence/insert_embedded.rb +43 -0
- data/lib/mongoid/persistence/remove.rb +44 -0
- data/lib/mongoid/persistence/remove_all.rb +40 -0
- data/lib/mongoid/persistence/remove_embedded.rb +48 -0
- data/lib/mongoid/persistence/update.rb +77 -0
- data/lib/mongoid/railtie.rb +139 -0
- data/lib/mongoid/railties/database.rake +171 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +107 -0
- data/lib/mongoid/relations/accessors.rb +175 -0
- data/lib/mongoid/relations/auto_save.rb +34 -0
- data/lib/mongoid/relations/binding.rb +26 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +103 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
- data/lib/mongoid/relations/builder.rb +42 -0
- data/lib/mongoid/relations/builders.rb +79 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +126 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +47 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +27 -0
- data/lib/mongoid/relations/cascading.rb +55 -0
- data/lib/mongoid/relations/cascading/delete.rb +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +19 -0
- data/lib/mongoid/relations/cascading/nullify.rb +18 -0
- data/lib/mongoid/relations/cascading/strategy.rb +26 -0
- data/lib/mongoid/relations/constraint.rb +42 -0
- data/lib/mongoid/relations/cyclic.rb +103 -0
- data/lib/mongoid/relations/embedded/atomic.rb +86 -0
- data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
- data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
- data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
- data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
- data/lib/mongoid/relations/embedded/in.rb +173 -0
- data/lib/mongoid/relations/embedded/many.rb +499 -0
- data/lib/mongoid/relations/embedded/one.rb +170 -0
- data/lib/mongoid/relations/macros.rb +310 -0
- data/lib/mongoid/relations/many.rb +215 -0
- data/lib/mongoid/relations/metadata.rb +539 -0
- data/lib/mongoid/relations/nested_builder.rb +68 -0
- data/lib/mongoid/relations/one.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +54 -0
- data/lib/mongoid/relations/proxy.rb +143 -0
- data/lib/mongoid/relations/referenced/batch.rb +71 -0
- data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
- data/lib/mongoid/relations/referenced/in.rb +216 -0
- data/lib/mongoid/relations/referenced/many.rb +516 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
- data/lib/mongoid/relations/referenced/one.rb +222 -0
- data/lib/mongoid/relations/reflections.rb +45 -0
- data/lib/mongoid/safe.rb +23 -0
- data/lib/mongoid/safety.rb +207 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +99 -0
- data/lib/mongoid/sharding.rb +51 -0
- data/lib/mongoid/state.rb +67 -0
- data/lib/mongoid/timestamps.rb +14 -0
- data/lib/mongoid/timestamps/created.rb +31 -0
- data/lib/mongoid/timestamps/updated.rb +33 -0
- data/lib/mongoid/validations.rb +124 -0
- data/lib/mongoid/validations/associated.rb +44 -0
- data/lib/mongoid/validations/referenced.rb +58 -0
- data/lib/mongoid/validations/uniqueness.rb +85 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +113 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/mongoid_generator.rb +70 -0
- data/lib/rails/mongoid.rb +58 -0
- metadata +406 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
|
|
5
|
+
# The selector is a hash-like object that has special behaviour for merging
|
|
6
|
+
# mongoid criteria selectors.
|
|
7
|
+
class Selector < Hash
|
|
8
|
+
|
|
9
|
+
attr_reader :fields, :klass
|
|
10
|
+
|
|
11
|
+
# Create the new selector.
|
|
12
|
+
#
|
|
13
|
+
# @example Create the selector.
|
|
14
|
+
# Selector.new(Person)
|
|
15
|
+
#
|
|
16
|
+
# @param [ Class ] klass The class the selector is for.
|
|
17
|
+
#
|
|
18
|
+
# @since 1.0.0
|
|
19
|
+
def initialize(klass)
|
|
20
|
+
@fields, @klass = klass.fields.except("_id", "_type"), klass
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Set the value for the supplied key, attempting to typecast the value.
|
|
24
|
+
#
|
|
25
|
+
# @example Set the value for the key.
|
|
26
|
+
# selector["$ne"] = { :name => "Zorg" }
|
|
27
|
+
#
|
|
28
|
+
# @param [ String, Symbol ] key The hash key.
|
|
29
|
+
# @param [ Object ] value The value to set.
|
|
30
|
+
#
|
|
31
|
+
# @since 2.0.0
|
|
32
|
+
def []=(key, value)
|
|
33
|
+
super(key, try_to_typecast(key, value))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Merge the selector with another hash.
|
|
37
|
+
#
|
|
38
|
+
# @example Merge the objects.
|
|
39
|
+
# selector.merge!({ :key => "value" })
|
|
40
|
+
#
|
|
41
|
+
# @param [ Hash, Selector ] other The object to merge with.
|
|
42
|
+
#
|
|
43
|
+
# @return [ Selector ] The merged selector.
|
|
44
|
+
#
|
|
45
|
+
# @since 1.0.0
|
|
46
|
+
def merge!(other)
|
|
47
|
+
tap do |selector|
|
|
48
|
+
other.each_pair do |key, value|
|
|
49
|
+
selector[key] = value
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
alias :update :merge!
|
|
54
|
+
|
|
55
|
+
if RUBY_VERSION < '1.9'
|
|
56
|
+
|
|
57
|
+
# Generate pretty inspection for old ruby versions.
|
|
58
|
+
#
|
|
59
|
+
# @example Inspect the selector.
|
|
60
|
+
# selector.inspect
|
|
61
|
+
#
|
|
62
|
+
# @return [ String ] The inspected selector.
|
|
63
|
+
def inspect
|
|
64
|
+
ret = self.keys.inject([]) do |ret, key|
|
|
65
|
+
ret << "#{key.inspect}=>#{self[key].inspect}"
|
|
66
|
+
end
|
|
67
|
+
"{#{ret.sort.join(', ')}}"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
# If the key is defined as a field, then attempt to typecast it.
|
|
74
|
+
#
|
|
75
|
+
# @example Try to cast.
|
|
76
|
+
# selector.try_to_typecast(:id, 1)
|
|
77
|
+
#
|
|
78
|
+
# @param [ String, Symbol ] key The field name.
|
|
79
|
+
# @param [ Object ] value The value.
|
|
80
|
+
#
|
|
81
|
+
# @return [ Object ] The typecasted value.
|
|
82
|
+
#
|
|
83
|
+
# @since 1.0.0
|
|
84
|
+
def try_to_typecast(key, value)
|
|
85
|
+
access = key.to_s
|
|
86
|
+
return value unless fields.has_key?(access)
|
|
87
|
+
field = fields[access]
|
|
88
|
+
typecast_value_for(field, value)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Get the typecast value for the defined field.
|
|
92
|
+
#
|
|
93
|
+
# @example Get the typecast value.
|
|
94
|
+
# selector.typecast_value_for(:name, "Corbin")
|
|
95
|
+
#
|
|
96
|
+
# @param [ Field ] field The defined field.
|
|
97
|
+
# @param [ Object ] value The value to cast.
|
|
98
|
+
#
|
|
99
|
+
# @return [ Object ] The cast value.
|
|
100
|
+
#
|
|
101
|
+
# @since 1.0.0
|
|
102
|
+
def typecast_value_for(field, value)
|
|
103
|
+
return field.set(value) if field.type === value
|
|
104
|
+
case value
|
|
105
|
+
when Hash
|
|
106
|
+
value = value.dup
|
|
107
|
+
value.each_pair do |k, v|
|
|
108
|
+
value[k] = typecast_hash_value(field, k, v)
|
|
109
|
+
end
|
|
110
|
+
when Array
|
|
111
|
+
value.map { |v| typecast_value_for(field, v) }
|
|
112
|
+
when Regexp
|
|
113
|
+
value
|
|
114
|
+
else
|
|
115
|
+
field.type == Array ? value.class.set(value) : field.set(value)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Typecast the value for booleans and integers in hashes.
|
|
120
|
+
#
|
|
121
|
+
# @example Typecast the hash values.
|
|
122
|
+
# selector.typecast_hash_value(field, "$exists", "true")
|
|
123
|
+
#
|
|
124
|
+
# @param [ Field ] field The defined field.
|
|
125
|
+
# @param [ String ] key The modifier key.
|
|
126
|
+
# @param [ Object ] value The value to cast.
|
|
127
|
+
#
|
|
128
|
+
# @return [ Object ] The cast value.
|
|
129
|
+
#
|
|
130
|
+
# @since 1.0.0
|
|
131
|
+
def typecast_hash_value(field, key, value)
|
|
132
|
+
case key
|
|
133
|
+
when "$exists"
|
|
134
|
+
Boolean.set(value)
|
|
135
|
+
when "$size"
|
|
136
|
+
Integer.set(value)
|
|
137
|
+
else
|
|
138
|
+
typecast_value_for(field, value)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
|
|
5
|
+
# Wrapper class for strings that should not be converted into
|
|
6
|
+
# BSON::ObjectIds.
|
|
7
|
+
class Unconvertable < String
|
|
8
|
+
|
|
9
|
+
# Initialize just like a normal string, and quack like it to.
|
|
10
|
+
#
|
|
11
|
+
# @example Create the new Unconvertable.
|
|
12
|
+
# Unconvertable.new("testing")
|
|
13
|
+
#
|
|
14
|
+
# @param [ String ] value The string.
|
|
15
|
+
#
|
|
16
|
+
# @since 2.0.2
|
|
17
|
+
def initialize(value); super; end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
class Cursor
|
|
4
|
+
include Mongoid::Collections::Retry
|
|
5
|
+
include Enumerable
|
|
6
|
+
# Operations on the Mongo::Cursor object that will not get overriden by the
|
|
7
|
+
# Mongoid::Cursor are defined here.
|
|
8
|
+
OPERATIONS = [
|
|
9
|
+
:close,
|
|
10
|
+
:closed?,
|
|
11
|
+
:count,
|
|
12
|
+
:explain,
|
|
13
|
+
:fields,
|
|
14
|
+
:full_collection_name,
|
|
15
|
+
:hint,
|
|
16
|
+
:limit,
|
|
17
|
+
:order,
|
|
18
|
+
:query_options_hash,
|
|
19
|
+
:query_opts,
|
|
20
|
+
:selector,
|
|
21
|
+
:skip,
|
|
22
|
+
:snapshot,
|
|
23
|
+
:sort,
|
|
24
|
+
:timeout
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
attr_reader :collection
|
|
28
|
+
|
|
29
|
+
# The operations above will all delegate to the proxied Mongo::Cursor.
|
|
30
|
+
#
|
|
31
|
+
# Example:
|
|
32
|
+
#
|
|
33
|
+
# <tt>cursor.close</tt>
|
|
34
|
+
OPERATIONS.each do |name|
|
|
35
|
+
define_method(name) do |*args|
|
|
36
|
+
retry_on_connection_failure do
|
|
37
|
+
@cursor.send(name, *args)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Iterate over each document in the cursor and yield to it.
|
|
43
|
+
#
|
|
44
|
+
# Example:
|
|
45
|
+
#
|
|
46
|
+
# <tt>cursor.each { |doc| p doc.title }</tt>
|
|
47
|
+
def each
|
|
48
|
+
@cursor.each do |document|
|
|
49
|
+
yield Mongoid::Factory.from_db(@klass, document)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Create the new +Mongoid::Cursor+.
|
|
54
|
+
#
|
|
55
|
+
# Options:
|
|
56
|
+
#
|
|
57
|
+
# collection: The Mongoid::Collection instance.
|
|
58
|
+
# cursor: The Mongo::Cursor to be proxied.
|
|
59
|
+
#
|
|
60
|
+
# Example:
|
|
61
|
+
#
|
|
62
|
+
# <tt>Mongoid::Cursor.new(Person, cursor)</tt>
|
|
63
|
+
def initialize(klass, collection, cursor)
|
|
64
|
+
@klass, @collection, @cursor = klass, collection, cursor
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Return the next document in the cursor. Will instantiate a new Mongoid
|
|
68
|
+
# document with the attributes.
|
|
69
|
+
#
|
|
70
|
+
# Example:
|
|
71
|
+
#
|
|
72
|
+
# <tt>cursor.next_document</tt>
|
|
73
|
+
def next_document
|
|
74
|
+
Mongoid::Factory.from_db(@klass, @cursor.next_document)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Returns an array of all the documents in the cursor.
|
|
78
|
+
#
|
|
79
|
+
# Example:
|
|
80
|
+
#
|
|
81
|
+
# <tt>cursor.to_a</tt>
|
|
82
|
+
def to_a
|
|
83
|
+
@cursor.to_a.collect { |attrs| Mongoid::Factory.from_db(@klass, attrs) }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
|
|
4
|
+
# This module handles functionality for creating default scopes.
|
|
5
|
+
module DefaultScope
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :default_scoping
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods #:nodoc:
|
|
13
|
+
|
|
14
|
+
# Creates a default_scope for the +Document+, similar to ActiveRecord's
|
|
15
|
+
# default_scope. +DefaultScopes+ are proxied +Criteria+ objects that are
|
|
16
|
+
# applied by default to all queries for the class.
|
|
17
|
+
#
|
|
18
|
+
# @example Create a default scope.
|
|
19
|
+
#
|
|
20
|
+
# class Person
|
|
21
|
+
# include Mongoid::Document
|
|
22
|
+
# field :active, :type => Boolean
|
|
23
|
+
# field :count, :type => Integer
|
|
24
|
+
#
|
|
25
|
+
# default_scope :where => { :active => true }
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# @param [ Hash ] conditions The conditions to create with.
|
|
29
|
+
#
|
|
30
|
+
# @since 2.0.0.rc.1
|
|
31
|
+
def default_scope(conditions = {})
|
|
32
|
+
self.default_scoping = Scope.new(conditions).conditions.scoped
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Dirty #:nodoc:
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
# Gets the changes for a specific field.
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
#
|
|
10
|
+
# person = Person.new(:title => "Sir")
|
|
11
|
+
# person.title = "Madam"
|
|
12
|
+
# person.attribute_change("title") # [ "Sir", "Madam" ]
|
|
13
|
+
#
|
|
14
|
+
# Returns:
|
|
15
|
+
#
|
|
16
|
+
# An +Array+ containing the old and new values.
|
|
17
|
+
def attribute_change(name)
|
|
18
|
+
modifications[name]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Determines if a specific field has chaged.
|
|
22
|
+
#
|
|
23
|
+
# Example:
|
|
24
|
+
#
|
|
25
|
+
# person = Person.new(:title => "Sir")
|
|
26
|
+
# person.title = "Madam"
|
|
27
|
+
# person.attribute_changed?("title") # true
|
|
28
|
+
#
|
|
29
|
+
# Returns:
|
|
30
|
+
#
|
|
31
|
+
# +true+ if changed, +false+ if not.
|
|
32
|
+
def attribute_changed?(name)
|
|
33
|
+
modifications.include?(name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Gets the old value for a specific field.
|
|
37
|
+
#
|
|
38
|
+
# Example:
|
|
39
|
+
#
|
|
40
|
+
# person = Person.new(:title => "Sir")
|
|
41
|
+
# person.title = "Madam"
|
|
42
|
+
# person.attribute_was("title") # "Sir"
|
|
43
|
+
#
|
|
44
|
+
# Returns:
|
|
45
|
+
#
|
|
46
|
+
# The old field value.
|
|
47
|
+
def attribute_was(name)
|
|
48
|
+
change = modifications[name]
|
|
49
|
+
change ? change[0] : attributes[name]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Gets the names of all the fields that have changed in the document.
|
|
53
|
+
#
|
|
54
|
+
# Example:
|
|
55
|
+
#
|
|
56
|
+
# person = Person.new(:title => "Sir")
|
|
57
|
+
# person.title = "Madam"
|
|
58
|
+
# person.changed # returns [ "title" ]
|
|
59
|
+
#
|
|
60
|
+
# Returns:
|
|
61
|
+
#
|
|
62
|
+
# An +Array+ of changed field names.
|
|
63
|
+
def changed
|
|
64
|
+
modifications.keys
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Alerts to whether the document has been modified or not.
|
|
68
|
+
#
|
|
69
|
+
# Example:
|
|
70
|
+
#
|
|
71
|
+
# person = Person.new(:title => "Sir")
|
|
72
|
+
# person.title = "Madam"
|
|
73
|
+
# person.changed? # returns true
|
|
74
|
+
#
|
|
75
|
+
# Returns:
|
|
76
|
+
#
|
|
77
|
+
# +true+ if changed, +false+ if not.
|
|
78
|
+
def changed?
|
|
79
|
+
!modifications.empty?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Gets all the modifications that have happened to the object as a +Hash+
|
|
83
|
+
# with the keys being the names of the fields, and the values being an
|
|
84
|
+
# +Array+ with the old value and new value.
|
|
85
|
+
#
|
|
86
|
+
# Example:
|
|
87
|
+
#
|
|
88
|
+
# person = Person.new(:title => "Sir")
|
|
89
|
+
# person.title = "Madam"
|
|
90
|
+
# person.changes # returns { "title" => [ "Sir", "Madam" ] }
|
|
91
|
+
#
|
|
92
|
+
# Returns:
|
|
93
|
+
#
|
|
94
|
+
# A +Hash+ of changes.
|
|
95
|
+
def changes
|
|
96
|
+
modifications
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Call this method after save, so the changes can be properly switched.
|
|
100
|
+
#
|
|
101
|
+
# Example:
|
|
102
|
+
#
|
|
103
|
+
# <tt>person.move_changes</tt>
|
|
104
|
+
def move_changes
|
|
105
|
+
@validated = false
|
|
106
|
+
@previous_modifications = modifications.dup
|
|
107
|
+
@modifications = {}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Gets all the new values for each of the changed fields, to be passed to
|
|
111
|
+
# a MongoDB $set modifier.
|
|
112
|
+
#
|
|
113
|
+
# Example:
|
|
114
|
+
#
|
|
115
|
+
# person = Person.new(:title => "Sir")
|
|
116
|
+
# person.title = "Madam"
|
|
117
|
+
# person.setters # returns { "title" => "Madam" }
|
|
118
|
+
#
|
|
119
|
+
# Returns:
|
|
120
|
+
#
|
|
121
|
+
# A +Hash+ of new values.
|
|
122
|
+
def setters
|
|
123
|
+
modifications.inject({}) do |sets, (field, changes)|
|
|
124
|
+
key = embedded? ? "#{_position}.#{field}" : field
|
|
125
|
+
sets[key] = changes[1]; sets
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Gets all the modifications that have happened to the object before the
|
|
130
|
+
# object was saved.
|
|
131
|
+
#
|
|
132
|
+
# Example:
|
|
133
|
+
#
|
|
134
|
+
# person = Person.new(:title => "Sir")
|
|
135
|
+
# person.title = "Madam"
|
|
136
|
+
# person.save!
|
|
137
|
+
# person.previous_changes # returns { "title" => [ "Sir", "Madam" ] }
|
|
138
|
+
#
|
|
139
|
+
# Returns:
|
|
140
|
+
#
|
|
141
|
+
# A +Hash+ of changes before save.
|
|
142
|
+
def previous_changes
|
|
143
|
+
@previous_modifications
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Resets a changed field back to its old value.
|
|
147
|
+
#
|
|
148
|
+
# Example:
|
|
149
|
+
#
|
|
150
|
+
# person = Person.new(:title => "Sir")
|
|
151
|
+
# person.title = "Madam"
|
|
152
|
+
# person.reset_attribute!("title")
|
|
153
|
+
# person.title # "Sir"
|
|
154
|
+
#
|
|
155
|
+
# Returns:
|
|
156
|
+
#
|
|
157
|
+
# The old field value.
|
|
158
|
+
def reset_attribute!(name)
|
|
159
|
+
value = attribute_was(name)
|
|
160
|
+
value ? attributes[name] = value : attributes.delete(name)
|
|
161
|
+
modifications.delete(name)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Sets up the modifications hash. This occurs just after the document is
|
|
165
|
+
# instantiated.
|
|
166
|
+
#
|
|
167
|
+
# Example:
|
|
168
|
+
#
|
|
169
|
+
# <tt>document.setup_notifications</tt>
|
|
170
|
+
def setup_modifications
|
|
171
|
+
@accessed ||= {}
|
|
172
|
+
@modifications ||= {}
|
|
173
|
+
@previous_modifications ||= {}
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Reset all modifications for the document. This will wipe all the marked
|
|
177
|
+
# changes, but not reset the values.
|
|
178
|
+
#
|
|
179
|
+
# Example:
|
|
180
|
+
#
|
|
181
|
+
# <tt>document.reset_modifications</tt>
|
|
182
|
+
def reset_modifications
|
|
183
|
+
@accessed = {}
|
|
184
|
+
@modifications = {}
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
protected
|
|
188
|
+
|
|
189
|
+
# Audit the original value for a field that can be modified in place.
|
|
190
|
+
#
|
|
191
|
+
# Example:
|
|
192
|
+
#
|
|
193
|
+
# <tt>person.accessed("aliases", [ "007" ])</tt>
|
|
194
|
+
def accessed(name, value)
|
|
195
|
+
return value unless value.is_a?(Enumerable)
|
|
196
|
+
@accessed ||= {}
|
|
197
|
+
@accessed[name] = value.dup unless @accessed.has_key?(name)
|
|
198
|
+
value
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Get all normal modifications plus in place potential changes.
|
|
202
|
+
#
|
|
203
|
+
# Example:
|
|
204
|
+
#
|
|
205
|
+
# <tt>person.modifications</tt>
|
|
206
|
+
#
|
|
207
|
+
# Returns:
|
|
208
|
+
#
|
|
209
|
+
# All changes to the document.
|
|
210
|
+
def modifications
|
|
211
|
+
reset_modifications unless @modifications && @accessed
|
|
212
|
+
@accessed.each_pair do |field, value|
|
|
213
|
+
current = attributes[field]
|
|
214
|
+
@modifications[field] = [ value, current ] if current != value
|
|
215
|
+
end
|
|
216
|
+
@accessed.clear
|
|
217
|
+
@modifications
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Audit the change of a field's value.
|
|
221
|
+
#
|
|
222
|
+
# Example:
|
|
223
|
+
#
|
|
224
|
+
# <tt>person.modify("name", "Jack", "John")</tt>
|
|
225
|
+
def modify(name, old_value, new_value)
|
|
226
|
+
attributes[name] = new_value
|
|
227
|
+
if @modifications && (old_value != new_value)
|
|
228
|
+
original = @modifications[name].first if @modifications[name]
|
|
229
|
+
@modifications[name] = [ (original || old_value), new_value ]
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
module ClassMethods #:nodoc:
|
|
234
|
+
# Add the dynamic dirty methods. These are custom methods defined on a
|
|
235
|
+
# field by field basis that wrap the dirty attribute methods.
|
|
236
|
+
#
|
|
237
|
+
# Example:
|
|
238
|
+
#
|
|
239
|
+
# person = Person.new(:title => "Sir")
|
|
240
|
+
# person.title = "Madam"
|
|
241
|
+
# person.title_change # [ "Sir", "Madam" ]
|
|
242
|
+
# person.title_changed? # true
|
|
243
|
+
# person.title_was # "Sir"
|
|
244
|
+
# person.reset_title!
|
|
245
|
+
def add_dirty_methods(name)
|
|
246
|
+
define_method("#{name}_change") { attribute_change(name) } unless instance_methods.include?("#{name}_change") || instance_methods.include?(:"#{name}_change")
|
|
247
|
+
define_method("#{name}_changed?") { attribute_changed?(name) } unless instance_methods.include?("#{name}_changed?") || instance_methods.include?(:"#{name}_changed?")
|
|
248
|
+
define_method("#{name}_was") { attribute_was(name) } unless instance_methods.include?("#{name}_was") || instance_methods.include?(:"#{name}_was")
|
|
249
|
+
define_method("reset_#{name}!") { reset_attribute!(name) } unless instance_methods.include?("reset_#{name}!") || instance_methods.include?(:"reset_#{name}!")
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|