stonegao-mongoid 2.0.0.rc.6
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 +44 -0
- data/lib/config/locales/de.yml +44 -0
- data/lib/config/locales/en.yml +45 -0
- data/lib/config/locales/es.yml +44 -0
- data/lib/config/locales/fr.yml +45 -0
- data/lib/config/locales/hu.yml +47 -0
- data/lib/config/locales/it.yml +42 -0
- data/lib/config/locales/kr.yml +68 -0
- data/lib/config/locales/nl.yml +42 -0
- data/lib/config/locales/pl.yml +42 -0
- data/lib/config/locales/pt-br.yml +43 -0
- data/lib/config/locales/pt.yml +43 -0
- data/lib/config/locales/ro.yml +49 -0
- data/lib/config/locales/sv.yml +43 -0
- data/lib/config/locales/zh-CN.yml +34 -0
- data/lib/mongoid/atomicity.rb +111 -0
- data/lib/mongoid/attributes.rb +251 -0
- data/lib/mongoid/callbacks.rb +13 -0
- data/lib/mongoid/collection.rb +137 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +29 -0
- data/lib/mongoid/collections/operations.rb +42 -0
- data/lib/mongoid/collections/slaves.rb +45 -0
- data/lib/mongoid/collections.rb +70 -0
- data/lib/mongoid/components.rb +45 -0
- data/lib/mongoid/config/database.rb +167 -0
- data/lib/mongoid/config/replset_database.rb +48 -0
- data/lib/mongoid/config.rb +343 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/enumerable.rb +226 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +345 -0
- data/lib/mongoid/contexts/paging.rb +50 -0
- data/lib/mongoid/contexts.rb +21 -0
- data/lib/mongoid/copyable.rb +44 -0
- data/lib/mongoid/criteria.rb +325 -0
- data/lib/mongoid/criterion/complex.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +67 -0
- data/lib/mongoid/criterion/inclusion.rb +134 -0
- data/lib/mongoid/criterion/inspection.rb +20 -0
- data/lib/mongoid/criterion/optional.rb +213 -0
- data/lib/mongoid/criterion/selector.rb +74 -0
- data/lib/mongoid/cursor.rb +81 -0
- data/lib/mongoid/default_scope.rb +28 -0
- data/lib/mongoid/dirty.rb +251 -0
- data/lib/mongoid/document.rb +256 -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/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/errors.rb +12 -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/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 +57 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -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/extensions.rb +116 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +20 -0
- data/lib/mongoid/field.rb +95 -0
- data/lib/mongoid/fields.rb +138 -0
- data/lib/mongoid/finders.rb +173 -0
- data/lib/mongoid/hierarchy.rb +85 -0
- data/lib/mongoid/identity.rb +89 -0
- data/lib/mongoid/indexes.rb +38 -0
- data/lib/mongoid/inspection.rb +58 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +77 -0
- data/lib/mongoid/logger.rb +18 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +27 -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/size.rb +11 -0
- data/lib/mongoid/matchers.rb +55 -0
- data/lib/mongoid/modifiers/command.rb +18 -0
- data/lib/mongoid/modifiers/inc.rb +24 -0
- data/lib/mongoid/modifiers.rb +24 -0
- data/lib/mongoid/multi_database.rb +11 -0
- data/lib/mongoid/multi_parameter_attributes.rb +80 -0
- data/lib/mongoid/named_scope.rb +36 -0
- data/lib/mongoid/nested_attributes.rb +43 -0
- data/lib/mongoid/paranoia.rb +103 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence/command.rb +59 -0
- data/lib/mongoid/persistence/insert.rb +53 -0
- data/lib/mongoid/persistence/insert_embedded.rb +42 -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 +76 -0
- data/lib/mongoid/persistence.rb +237 -0
- data/lib/mongoid/railtie.rb +129 -0
- data/lib/mongoid/railties/database.rake +171 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations/accessors.rb +157 -0
- data/lib/mongoid/relations/auto_save.rb +34 -0
- data/lib/mongoid/relations/binding.rb +26 -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 +99 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/builder.rb +42 -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 +116 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
- data/lib/mongoid/relations/builders.rb +79 -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/cascading.rb +55 -0
- data/lib/mongoid/relations/constraint.rb +45 -0
- data/lib/mongoid/relations/cyclic.rb +97 -0
- data/lib/mongoid/relations/embedded/in.rb +173 -0
- data/lib/mongoid/relations/embedded/many.rb +483 -0
- data/lib/mongoid/relations/embedded/one.rb +170 -0
- data/lib/mongoid/relations/macros.rb +306 -0
- data/lib/mongoid/relations/many.rb +171 -0
- data/lib/mongoid/relations/metadata.rb +533 -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 +128 -0
- data/lib/mongoid/relations/referenced/in.rb +216 -0
- data/lib/mongoid/relations/referenced/many.rb +443 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +344 -0
- data/lib/mongoid/relations/referenced/one.rb +206 -0
- data/lib/mongoid/relations/reflections.rb +45 -0
- data/lib/mongoid/relations.rb +105 -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/state.rb +66 -0
- data/lib/mongoid/timestamps.rb +38 -0
- data/lib/mongoid/validations/associated.rb +42 -0
- data/lib/mongoid/validations/uniqueness.rb +85 -0
- data/lib/mongoid/validations.rb +117 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +51 -0
- data/lib/mongoid.rb +139 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +23 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +17 -0
- data/lib/rails/generators/mongoid_generator.rb +61 -0
- data/lib/rails/mongoid.rb +57 -0
- metadata +380 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
module Inspection #:nodoc
|
|
4
|
+
|
|
5
|
+
# Returns the class name plus its attributes. If using dynamic fields will
|
|
6
|
+
# include those as well.
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
#
|
|
10
|
+
# <tt>person.inspect</tt>
|
|
11
|
+
#
|
|
12
|
+
# Returns:
|
|
13
|
+
#
|
|
14
|
+
# A nice pretty string to look at.
|
|
15
|
+
def inspect
|
|
16
|
+
inspection = []
|
|
17
|
+
inspection.concat(inspect_fields).concat(inspect_dynamic_fields)
|
|
18
|
+
"#<#{self.class.name} _id: #{id}, #{inspection * ', '}>"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# Get an array of inspected fields for the document.
|
|
24
|
+
#
|
|
25
|
+
# Example:
|
|
26
|
+
#
|
|
27
|
+
# <tt>inspect_fields</tt>
|
|
28
|
+
#
|
|
29
|
+
# Returns:
|
|
30
|
+
#
|
|
31
|
+
# An array of pretty printed field values.
|
|
32
|
+
def inspect_fields
|
|
33
|
+
fields.map do |name, field|
|
|
34
|
+
"#{name}: #{@attributes[name].inspect}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Get an array of inspected dynamic fields for the document.
|
|
39
|
+
#
|
|
40
|
+
# Example:
|
|
41
|
+
#
|
|
42
|
+
# <tt>inspect_dynamic_fields</tt>
|
|
43
|
+
#
|
|
44
|
+
# Returns:
|
|
45
|
+
#
|
|
46
|
+
# An array of pretty printed dynamic field values.
|
|
47
|
+
def inspect_dynamic_fields
|
|
48
|
+
if Mongoid.allow_dynamic_fields
|
|
49
|
+
keys = @attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
|
|
50
|
+
return keys.map do |name|
|
|
51
|
+
"#{name}: #{@attributes[name].inspect}"
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
[]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
aggregate:
|
|
2
|
+
"function(obj, prev) {
|
|
3
|
+
prev.count++;
|
|
4
|
+
}"
|
|
5
|
+
|
|
6
|
+
group:
|
|
7
|
+
"function(obj, prev) {
|
|
8
|
+
prev.group.push(obj);
|
|
9
|
+
}"
|
|
10
|
+
|
|
11
|
+
max:
|
|
12
|
+
"function(obj, prev) {
|
|
13
|
+
if (prev.max == 'start') {
|
|
14
|
+
prev.max = obj.[field];
|
|
15
|
+
}
|
|
16
|
+
if (prev.max < obj.[field]) {
|
|
17
|
+
prev.max = obj.[field];
|
|
18
|
+
}
|
|
19
|
+
}"
|
|
20
|
+
|
|
21
|
+
min:
|
|
22
|
+
"function(obj, prev) {
|
|
23
|
+
if (prev.min == 'start') {
|
|
24
|
+
prev.min = obj.[field];
|
|
25
|
+
}
|
|
26
|
+
if (prev.min > obj.[field]) {
|
|
27
|
+
prev.min = obj.[field];
|
|
28
|
+
}
|
|
29
|
+
}"
|
|
30
|
+
|
|
31
|
+
sum:
|
|
32
|
+
"function(obj, prev) {
|
|
33
|
+
if (prev.sum == 'start') {
|
|
34
|
+
prev.sum = 0;
|
|
35
|
+
}
|
|
36
|
+
prev.sum += obj.[field];
|
|
37
|
+
}"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
class Javascript
|
|
4
|
+
# Constant for the file that defines all the js functions.
|
|
5
|
+
FUNCTIONS = File.join(File.dirname(__FILE__), "javascript", "functions.yml")
|
|
6
|
+
|
|
7
|
+
# Load the javascript functions and define a class method for each one,
|
|
8
|
+
# that memoizes the value.
|
|
9
|
+
#
|
|
10
|
+
# Example:
|
|
11
|
+
#
|
|
12
|
+
# <tt>Mongoid::Javascript.aggregate</tt>
|
|
13
|
+
YAML.load(File.read(FUNCTIONS)).each_pair do |key, function|
|
|
14
|
+
(class << self; self; end).class_eval <<-EOT
|
|
15
|
+
def #{key}
|
|
16
|
+
@#{key} ||= "#{function}"
|
|
17
|
+
end
|
|
18
|
+
EOT
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/mongoid/json.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
# This module is for hooking in to +ActiveModel+s serialization to let
|
|
4
|
+
# configuring the ability to include the root in JSON happen from the Mongoid
|
|
5
|
+
# config.
|
|
6
|
+
module JSON
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# We need to redefine where the JSON configuration is getting defined,
|
|
10
|
+
# similar to +ActiveRecord+.
|
|
11
|
+
included do
|
|
12
|
+
undef_method :include_root_in_json
|
|
13
|
+
delegate :include_root_in_json, :to => ::Mongoid
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/mongoid/keys.rb
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Keys
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
cattr_accessor :primary_key, :_identity
|
|
7
|
+
self._identity = { :type => BSON::ObjectId }
|
|
8
|
+
|
|
9
|
+
delegate \
|
|
10
|
+
:_id_type,
|
|
11
|
+
:primary_key,
|
|
12
|
+
:using_object_ids?, :to => "self.class"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module ClassMethods #:nodoc:
|
|
16
|
+
|
|
17
|
+
# Convenience method for returning the type of the id for this class.
|
|
18
|
+
#
|
|
19
|
+
# Example:
|
|
20
|
+
#
|
|
21
|
+
# <tt>Person._id_type</tt>
|
|
22
|
+
#
|
|
23
|
+
# Returns:
|
|
24
|
+
#
|
|
25
|
+
# The type of the id.
|
|
26
|
+
def _id_type
|
|
27
|
+
_identity[:type]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Used for telling Mongoid on a per model basis whether to override the
|
|
31
|
+
# default +BSON::ObjectId+ and use a different type. This will be
|
|
32
|
+
# expanded in the future for requiring a PkFactory if the type is not a
|
|
33
|
+
# +BSON::ObjectId+ or +String+.
|
|
34
|
+
#
|
|
35
|
+
# Example:
|
|
36
|
+
#
|
|
37
|
+
# class Person
|
|
38
|
+
# include Mongoid::Document
|
|
39
|
+
# identity :type => String
|
|
40
|
+
# end
|
|
41
|
+
def identity(options = {})
|
|
42
|
+
self._identity = options
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Defines the field that will be used for the id of this +Document+. This
|
|
46
|
+
# set the id of this +Document+ before save to a parameterized version of
|
|
47
|
+
# the field that was supplied. This is good for use for readable URLS in
|
|
48
|
+
# web applications.
|
|
49
|
+
#
|
|
50
|
+
# Example:
|
|
51
|
+
#
|
|
52
|
+
# class Person
|
|
53
|
+
# include Mongoid::Document
|
|
54
|
+
# key :first_name, :last_name
|
|
55
|
+
# end
|
|
56
|
+
def key(*fields)
|
|
57
|
+
self.primary_key = fields
|
|
58
|
+
identity(:type => String)
|
|
59
|
+
set_callback :save, :before, :identify
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Convenience method for determining if we are using +BSON::ObjectIds+ as
|
|
63
|
+
# our id.
|
|
64
|
+
#
|
|
65
|
+
# Example:
|
|
66
|
+
#
|
|
67
|
+
# <tt>person.using_object_ids?</tt>
|
|
68
|
+
#
|
|
69
|
+
# Returns:
|
|
70
|
+
#
|
|
71
|
+
# true if we are using BSON::ObjectIds
|
|
72
|
+
def using_object_ids?
|
|
73
|
+
_id_type == BSON::ObjectId
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Mongoid
|
|
2
|
+
class Logger
|
|
3
|
+
|
|
4
|
+
delegate :info, :debug, :error, :fatal, :unknown, :to => :logger, :allow_nil => true
|
|
5
|
+
|
|
6
|
+
def warn(message)
|
|
7
|
+
logger.warn(message) if logger && logger.respond_to?(:warn)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def logger
|
|
11
|
+
Mongoid.logger
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def inspect
|
|
15
|
+
"#<Mongoid::Logger:0x#{object_id.to_s(16)} @logger=#{logger.inspect}>"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Matchers #:nodoc:
|
|
4
|
+
class Default
|
|
5
|
+
# Creating a new matcher only requires the value.
|
|
6
|
+
def initialize(attribute)
|
|
7
|
+
@attribute = attribute
|
|
8
|
+
end
|
|
9
|
+
# Return true if the attribute and value are equal.
|
|
10
|
+
def matches?(value)
|
|
11
|
+
@attribute.is_a?(Array) && value.is_a?(String) ?
|
|
12
|
+
@attribute.include?(value) : value === @attribute
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
protected
|
|
16
|
+
# Return the first value in the hash.
|
|
17
|
+
def first(value)
|
|
18
|
+
value.values.first
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# If object exists then compare, else return false
|
|
22
|
+
def determine(value, operator)
|
|
23
|
+
@attribute ? @attribute.send(operator, first(value)) : false
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Matchers #:nodoc:
|
|
4
|
+
class Exists < Default
|
|
5
|
+
# Return true if the attribute exists and checking for existence or
|
|
6
|
+
# return true if the attribute does not exist and checking for
|
|
7
|
+
# non-existence.
|
|
8
|
+
def matches?(value)
|
|
9
|
+
@attribute.nil? != value.values.first
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/matchers/default"
|
|
3
|
+
require "mongoid/matchers/all"
|
|
4
|
+
require "mongoid/matchers/exists"
|
|
5
|
+
require "mongoid/matchers/gt"
|
|
6
|
+
require "mongoid/matchers/gte"
|
|
7
|
+
require "mongoid/matchers/in"
|
|
8
|
+
require "mongoid/matchers/lt"
|
|
9
|
+
require "mongoid/matchers/lte"
|
|
10
|
+
require "mongoid/matchers/ne"
|
|
11
|
+
require "mongoid/matchers/nin"
|
|
12
|
+
require "mongoid/matchers/size"
|
|
13
|
+
|
|
14
|
+
module Mongoid #:nodoc:
|
|
15
|
+
|
|
16
|
+
# This module contains all the behavior for ruby implementations of MongoDB
|
|
17
|
+
# selectors.
|
|
18
|
+
module Matchers
|
|
19
|
+
|
|
20
|
+
# Determines if this document has the attributes to match the supplied
|
|
21
|
+
# MongoDB selector. Used for matching on embedded associations.
|
|
22
|
+
#
|
|
23
|
+
# @example Does the document match?
|
|
24
|
+
# document.matches?(:title => { "$in" => [ "test" ] })
|
|
25
|
+
#
|
|
26
|
+
# @param [ Hash ] selector The MongoDB selector.
|
|
27
|
+
#
|
|
28
|
+
# @return [ true, false ] True if matches, false if not.
|
|
29
|
+
def matches?(selector)
|
|
30
|
+
selector.each_pair do |key, value|
|
|
31
|
+
return false unless matcher(key, value).matches?(value)
|
|
32
|
+
end; true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
# Get the matcher for the supplied key and value. Will determine the class
|
|
38
|
+
# name from the key.
|
|
39
|
+
#
|
|
40
|
+
# @example Get the matcher.
|
|
41
|
+
# document.matcher(:title, { "$in" => [ "test" ] })
|
|
42
|
+
#
|
|
43
|
+
# @param [ Symbol, String ] key The field name.
|
|
44
|
+
# @param [ Object, Hash ] The value or selector.
|
|
45
|
+
#
|
|
46
|
+
# @return [ Matcher ] The matcher.
|
|
47
|
+
def matcher(key, value)
|
|
48
|
+
if value.is_a?(Hash)
|
|
49
|
+
name = "Mongoid::Matchers::#{value.keys.first.gsub("$", "").camelize}"
|
|
50
|
+
return name.constantize.new(attributes[key])
|
|
51
|
+
end
|
|
52
|
+
Default.new(attributes[key])
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Modifiers #:nodoc:
|
|
4
|
+
class Command #:nodoc:
|
|
5
|
+
include Mongoid::Safe
|
|
6
|
+
|
|
7
|
+
# Instantiate the new $inc modifier.
|
|
8
|
+
#
|
|
9
|
+
# Options:
|
|
10
|
+
#
|
|
11
|
+
# klass: The class to get the collection from.
|
|
12
|
+
# options: The options to get passed through to the driver.
|
|
13
|
+
def initialize(document, options = {})
|
|
14
|
+
@document, @options = document, options
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Modifiers #:nodoc:
|
|
4
|
+
class Inc < Command #:nodoc:
|
|
5
|
+
|
|
6
|
+
# Execute the persistence operation. This will increment the provided
|
|
7
|
+
# field by the supplied value. If no field exists, it will be created and
|
|
8
|
+
# set to the value provided.
|
|
9
|
+
#
|
|
10
|
+
# Options:
|
|
11
|
+
#
|
|
12
|
+
# field: The field to increment.
|
|
13
|
+
# value: The number to increment by.
|
|
14
|
+
def persist(field, value)
|
|
15
|
+
@document.collection.update(
|
|
16
|
+
@document._selector,
|
|
17
|
+
{ "$inc" => { field => value } },
|
|
18
|
+
:safe => safe_mode?(@options),
|
|
19
|
+
:multi => false
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/modifiers/command"
|
|
3
|
+
require "mongoid/modifiers/inc"
|
|
4
|
+
|
|
5
|
+
module Mongoid #:nodoc:
|
|
6
|
+
module Modifiers #:nodoc:
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# Increment the field by the provided value, else if it doesn't exists set
|
|
10
|
+
# it to that value.
|
|
11
|
+
#
|
|
12
|
+
# Options:
|
|
13
|
+
#
|
|
14
|
+
# field: The field to increment.
|
|
15
|
+
# value: The value to increment by.
|
|
16
|
+
# options: Options to pass through to the driver.
|
|
17
|
+
def inc(field, value, options = {})
|
|
18
|
+
current = send(field)
|
|
19
|
+
write_attribute(field, (current ? (current + value) : value))
|
|
20
|
+
Inc.new(self, options).persist(field, value)
|
|
21
|
+
current + value
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module MultiParameterAttributes
|
|
4
|
+
module Errors
|
|
5
|
+
# Raised when an error occurred while doing a mass assignment to an attribute through the
|
|
6
|
+
# <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
|
|
7
|
+
# offending attribute.
|
|
8
|
+
class AttributeAssignmentError < Mongoid::Errors::MongoidError
|
|
9
|
+
attr_reader :exception, :attribute
|
|
10
|
+
def initialize(message, exception, attribute)
|
|
11
|
+
@exception = exception
|
|
12
|
+
@attribute = attribute
|
|
13
|
+
@message = message
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Raised when there are multiple errors while doing a mass assignment through the +attributes+
|
|
18
|
+
# method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
|
|
19
|
+
# objects, each corresponding to the error while assigning to an attribute.
|
|
20
|
+
class MultiparameterAssignmentErrors < Mongoid::Errors::MongoidError
|
|
21
|
+
attr_reader :errors
|
|
22
|
+
def initialize(errors)
|
|
23
|
+
@errors = errors
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def process(attrs = nil)
|
|
29
|
+
if attrs
|
|
30
|
+
errors = []
|
|
31
|
+
attributes = {}
|
|
32
|
+
multi_parameter_attributes = {}
|
|
33
|
+
|
|
34
|
+
attrs.each_pair do |key, value|
|
|
35
|
+
if key =~ /^([^\(]+)\((\d+)([if])\)$/
|
|
36
|
+
key, index = $1, $2.to_i
|
|
37
|
+
(multi_parameter_attributes[key] ||= {})[index] = value.empty? ? nil : value.send("to_#{$3}")
|
|
38
|
+
else
|
|
39
|
+
attributes[key] = value
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
multi_parameter_attributes.each_pair do |key, values|
|
|
44
|
+
begin
|
|
45
|
+
values = (values.keys.min..values.keys.max).map { |i| values[i] }
|
|
46
|
+
klass = self.class.fields[key].try(:type)
|
|
47
|
+
attributes[key] = instantiate_object(klass, values)
|
|
48
|
+
rescue => e
|
|
49
|
+
errors << Errors::AttributeAssignmentError.new("error on assignment #{values.inspect} to #{key}", e, key)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
unless errors.empty?
|
|
54
|
+
raise Errors::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
super attributes
|
|
58
|
+
else
|
|
59
|
+
super
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
protected
|
|
64
|
+
|
|
65
|
+
def instantiate_object(klass, values_with_empty_parameters)
|
|
66
|
+
return nil if values_with_empty_parameters.all? { |v| v.nil? }
|
|
67
|
+
|
|
68
|
+
values = values_with_empty_parameters.collect { |v| v.nil? ? 1 : v }
|
|
69
|
+
|
|
70
|
+
if klass == DateTime || klass == Date || klass == Time
|
|
71
|
+
klass.send(:convert_to_time, values)
|
|
72
|
+
elsif klass
|
|
73
|
+
klass.new *values
|
|
74
|
+
else
|
|
75
|
+
values
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module NamedScope
|
|
4
|
+
# Creates a named_scope for the +Document+, similar to ActiveRecord's
|
|
5
|
+
# named_scopes. +NamedScopes+ are proxied +Criteria+ objects that can be
|
|
6
|
+
# chained.
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
#
|
|
10
|
+
# class Person
|
|
11
|
+
# include Mongoid::Document
|
|
12
|
+
# field :active, :type => Boolean
|
|
13
|
+
# field :count, :type => Integer
|
|
14
|
+
#
|
|
15
|
+
# named_scope :active, :where => { :active => true }
|
|
16
|
+
# named_scope :count_gt_one, :where => { :count.gt => 1 }
|
|
17
|
+
# named_scope :at_least_count, lambda { |count| { :where => { :count.gt => count } } }
|
|
18
|
+
# end
|
|
19
|
+
def named_scope(name, conditions = {}, &block)
|
|
20
|
+
name = name.to_sym
|
|
21
|
+
scopes[name] = Scope.new(conditions, &block)
|
|
22
|
+
(class << self; self; end).class_eval <<-EOT
|
|
23
|
+
def #{name}(*args)
|
|
24
|
+
scope = scopes[:#{name}]
|
|
25
|
+
scope.extend(criteria.fuse(scope.conditions.scoped(*args)))
|
|
26
|
+
end
|
|
27
|
+
EOT
|
|
28
|
+
end
|
|
29
|
+
alias :scope :named_scope
|
|
30
|
+
|
|
31
|
+
# Return the scopes or default to an empty +Hash+.
|
|
32
|
+
def scopes
|
|
33
|
+
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module NestedAttributes
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
module ClassMethods
|
|
7
|
+
REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |_, value| value.blank? } }
|
|
8
|
+
|
|
9
|
+
# Used when needing to update related models from a parent relation. Can
|
|
10
|
+
# be used on embedded or referenced relations.
|
|
11
|
+
#
|
|
12
|
+
# @example Defining nested attributes.
|
|
13
|
+
#
|
|
14
|
+
# class Person
|
|
15
|
+
# include Mongoid::Document
|
|
16
|
+
#
|
|
17
|
+
# embeds_many :addresses
|
|
18
|
+
# embeds_one :game
|
|
19
|
+
# references_many :posts
|
|
20
|
+
#
|
|
21
|
+
# accepts_nested_attributes_for :addresses, :game, :posts
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# @param [ Array<Symbol>, Hash ] *args A list of relation names, followed
|
|
25
|
+
# by a hash of options.
|
|
26
|
+
#
|
|
27
|
+
# @option *args [ true, false ] :allow_destroy Can deletion occur?
|
|
28
|
+
# @option *args [ Proc ] :reject_if Block to reject documents with.
|
|
29
|
+
# @option *args [ Integer ] :limit The max number to create.
|
|
30
|
+
# @option *args [ true, false ] :update_only Only update existing docs.
|
|
31
|
+
def accepts_nested_attributes_for(*args)
|
|
32
|
+
options = args.extract_options!
|
|
33
|
+
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
|
|
34
|
+
args.each do |name|
|
|
35
|
+
define_method("#{name}_attributes=") do |attrs|
|
|
36
|
+
relation = relations[name.to_s]
|
|
37
|
+
relation.nested_builder(attrs, options).build(self)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|