stonegao-mongoid 2.0.0.rc.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|