mongoid-pre 2.0.0.beta1
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/.gitignore +6 -0
- data/.watchr +24 -0
- data/MIT_LICENSE +20 -0
- data/README.rdoc +49 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/caliper.yml +4 -0
- data/lib/mongoid.rb +135 -0
- data/lib/mongoid/associations.rb +263 -0
- data/lib/mongoid/associations/belongs_to_related.rb +59 -0
- data/lib/mongoid/associations/embedded_in.rb +64 -0
- data/lib/mongoid/associations/embeds_many.rb +193 -0
- data/lib/mongoid/associations/embeds_one.rb +95 -0
- data/lib/mongoid/associations/has_many_related.rb +133 -0
- data/lib/mongoid/associations/has_one_related.rb +81 -0
- data/lib/mongoid/associations/meta_data.rb +28 -0
- data/lib/mongoid/associations/options.rb +52 -0
- data/lib/mongoid/associations/proxy.rb +31 -0
- data/lib/mongoid/attributes.rb +185 -0
- data/lib/mongoid/callbacks.rb +18 -0
- data/lib/mongoid/collection.rb +119 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +28 -0
- data/lib/mongoid/collections/mimic.rb +46 -0
- data/lib/mongoid/collections/operations.rb +41 -0
- data/lib/mongoid/collections/slaves.rb +44 -0
- data/lib/mongoid/commands.rb +161 -0
- data/lib/mongoid/commands/create.rb +19 -0
- data/lib/mongoid/commands/delete.rb +16 -0
- data/lib/mongoid/commands/delete_all.rb +25 -0
- data/lib/mongoid/commands/deletion.rb +18 -0
- data/lib/mongoid/commands/destroy.rb +17 -0
- data/lib/mongoid/commands/destroy_all.rb +25 -0
- data/lib/mongoid/commands/save.rb +30 -0
- data/lib/mongoid/components.rb +31 -0
- data/lib/mongoid/config.rb +86 -0
- data/lib/mongoid/contexts.rb +25 -0
- data/lib/mongoid/contexts/enumerable.rb +151 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +285 -0
- data/lib/mongoid/contexts/paging.rb +42 -0
- data/lib/mongoid/criteria.rb +239 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +93 -0
- data/lib/mongoid/criterion/optional.rb +136 -0
- data/lib/mongoid/cursor.rb +82 -0
- data/lib/mongoid/deprecation.rb +22 -0
- data/lib/mongoid/dirty.rb +203 -0
- data/lib/mongoid/document.rb +306 -0
- data/lib/mongoid/errors.rb +77 -0
- data/lib/mongoid/extensions.rb +99 -0
- data/lib/mongoid/extensions/array/accessors.rb +17 -0
- data/lib/mongoid/extensions/array/aliasing.rb +4 -0
- data/lib/mongoid/extensions/array/assimilation.rb +26 -0
- data/lib/mongoid/extensions/array/conversions.rb +27 -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 +16 -0
- data/lib/mongoid/extensions/date/conversions.rb +15 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +17 -0
- data/lib/mongoid/extensions/float/conversions.rb +16 -0
- data/lib/mongoid/extensions/hash/accessors.rb +38 -0
- data/lib/mongoid/extensions/hash/assimilation.rb +30 -0
- data/lib/mongoid/extensions/hash/conversions.rb +15 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +16 -0
- data/lib/mongoid/extensions/nil/assimilation.rb +13 -0
- data/lib/mongoid/extensions/object/conversions.rb +27 -0
- data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/string/conversions.rb +15 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
- data/lib/mongoid/extensions/time/conversions.rb +18 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +19 -0
- data/lib/mongoid/field.rb +52 -0
- data/lib/mongoid/fields.rb +62 -0
- data/lib/mongoid/finders.rb +136 -0
- data/lib/mongoid/identity.rb +39 -0
- data/lib/mongoid/indexes.rb +27 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/matchers.rb +36 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +26 -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/memoization.rb +27 -0
- data/lib/mongoid/named_scope.rb +42 -0
- data/lib/mongoid/observable.rb +30 -0
- data/lib/mongoid/paths.rb +54 -0
- data/lib/mongoid/persistence.rb +27 -0
- data/lib/mongoid/persistence/command.rb +20 -0
- data/lib/mongoid/persistence/insert.rb +71 -0
- data/lib/mongoid/persistence/update.rb +78 -0
- data/lib/mongoid/scope.rb +75 -0
- data/lib/mongoid/state.rb +32 -0
- data/lib/mongoid/timestamps.rb +27 -0
- data/lib/mongoid/validations.rb +51 -0
- data/lib/mongoid/validations/associated.rb +32 -0
- data/lib/mongoid/validations/locale/en.yml +4 -0
- data/lib/mongoid/validations/uniqueness.rb +22 -0
- data/lib/mongoid/versioning.rb +26 -0
- data/mongoid.gemspec +413 -0
- data/perf/benchmark.rb +77 -0
- data/spec/integration/mongoid/associations_spec.rb +340 -0
- data/spec/integration/mongoid/attributes_spec.rb +22 -0
- data/spec/integration/mongoid/commands_spec.rb +230 -0
- data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
- data/spec/integration/mongoid/criteria_spec.rb +272 -0
- data/spec/integration/mongoid/dirty_spec.rb +70 -0
- data/spec/integration/mongoid/document_spec.rb +650 -0
- data/spec/integration/mongoid/extensions_spec.rb +22 -0
- data/spec/integration/mongoid/finders_spec.rb +119 -0
- data/spec/integration/mongoid/inheritance_spec.rb +137 -0
- data/spec/integration/mongoid/named_scope_spec.rb +46 -0
- data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
- data/spec/models/address.rb +39 -0
- data/spec/models/animal.rb +6 -0
- data/spec/models/callbacks.rb +18 -0
- data/spec/models/comment.rb +8 -0
- data/spec/models/country_code.rb +6 -0
- data/spec/models/employer.rb +5 -0
- data/spec/models/game.rb +7 -0
- data/spec/models/inheritance.rb +56 -0
- data/spec/models/location.rb +5 -0
- data/spec/models/mixed_drink.rb +4 -0
- data/spec/models/name.rb +13 -0
- data/spec/models/namespacing.rb +11 -0
- data/spec/models/patient.rb +6 -0
- data/spec/models/person.rb +99 -0
- data/spec/models/pet.rb +7 -0
- data/spec/models/pet_owner.rb +6 -0
- data/spec/models/phone.rb +7 -0
- data/spec/models/post.rb +15 -0
- data/spec/models/translation.rb +5 -0
- data/spec/models/vet_visit.rb +5 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +145 -0
- data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
- data/spec/unit/mongoid/associations/embeds_many_spec.rb +516 -0
- data/spec/unit/mongoid/associations/embeds_one_spec.rb +282 -0
- data/spec/unit/mongoid/associations/has_many_related_spec.rb +418 -0
- data/spec/unit/mongoid/associations/has_one_related_spec.rb +179 -0
- data/spec/unit/mongoid/associations/meta_data_spec.rb +88 -0
- data/spec/unit/mongoid/associations/options_spec.rb +192 -0
- data/spec/unit/mongoid/associations_spec.rb +595 -0
- data/spec/unit/mongoid/attributes_spec.rb +507 -0
- data/spec/unit/mongoid/callbacks_spec.rb +55 -0
- data/spec/unit/mongoid/collection_spec.rb +187 -0
- data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
- data/spec/unit/mongoid/collections/master_spec.rb +41 -0
- data/spec/unit/mongoid/collections/mimic_spec.rb +43 -0
- data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
- data/spec/unit/mongoid/commands/create_spec.rb +31 -0
- data/spec/unit/mongoid/commands/delete_all_spec.rb +59 -0
- data/spec/unit/mongoid/commands/delete_spec.rb +38 -0
- data/spec/unit/mongoid/commands/destroy_all_spec.rb +21 -0
- data/spec/unit/mongoid/commands/destroy_spec.rb +51 -0
- data/spec/unit/mongoid/commands/save_spec.rb +107 -0
- data/spec/unit/mongoid/commands_spec.rb +270 -0
- data/spec/unit/mongoid/config_spec.rb +176 -0
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +421 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +682 -0
- data/spec/unit/mongoid/contexts_spec.rb +25 -0
- data/spec/unit/mongoid/criteria_spec.rb +824 -0
- data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
- data/spec/unit/mongoid/criterion/exclusion_spec.rb +91 -0
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +219 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +319 -0
- data/spec/unit/mongoid/cursor_spec.rb +74 -0
- data/spec/unit/mongoid/deprecation_spec.rb +24 -0
- data/spec/unit/mongoid/dirty_spec.rb +286 -0
- data/spec/unit/mongoid/document_spec.rb +818 -0
- data/spec/unit/mongoid/errors_spec.rb +103 -0
- data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
- data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
- data/spec/unit/mongoid/extensions/array/conversions_spec.rb +35 -0
- data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
- data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
- data/spec/unit/mongoid/extensions/date/conversions_spec.rb +102 -0
- data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +67 -0
- data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
- data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
- data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +46 -0
- data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +21 -0
- data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
- data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
- data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
- data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +24 -0
- data/spec/unit/mongoid/extensions/object/conversions_spec.rb +57 -0
- data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
- data/spec/unit/mongoid/extensions/string/conversions_spec.rb +17 -0
- data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
- data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +91 -0
- data/spec/unit/mongoid/extensions/time/conversions_spec.rb +70 -0
- data/spec/unit/mongoid/extras_spec.rb +102 -0
- data/spec/unit/mongoid/factory_spec.rb +31 -0
- data/spec/unit/mongoid/field_spec.rb +143 -0
- data/spec/unit/mongoid/fields_spec.rb +181 -0
- data/spec/unit/mongoid/finders_spec.rb +404 -0
- data/spec/unit/mongoid/identity_spec.rb +109 -0
- data/spec/unit/mongoid/indexes_spec.rb +93 -0
- data/spec/unit/mongoid/javascript_spec.rb +48 -0
- data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
- data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
- data/spec/unit/mongoid/matchers_spec.rb +329 -0
- data/spec/unit/mongoid/memoization_spec.rb +75 -0
- data/spec/unit/mongoid/named_scope_spec.rb +123 -0
- data/spec/unit/mongoid/observable_spec.rb +46 -0
- data/spec/unit/mongoid/paths_spec.rb +124 -0
- data/spec/unit/mongoid/persistence/insert_spec.rb +175 -0
- data/spec/unit/mongoid/persistence/update_spec.rb +148 -0
- data/spec/unit/mongoid/persistence_spec.rb +40 -0
- data/spec/unit/mongoid/scope_spec.rb +240 -0
- data/spec/unit/mongoid/state_spec.rb +83 -0
- data/spec/unit/mongoid/timestamps_spec.rb +25 -0
- data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
- data/spec/unit/mongoid/validations/uniqueness_spec.rb +47 -0
- data/spec/unit/mongoid/validations_spec.rb +190 -0
- data/spec/unit/mongoid/versioning_spec.rb +41 -0
- data/spec/unit/mongoid_spec.rb +46 -0
- metadata +476 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
module Fields #:nodoc
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
# Set up the class attributes that must be available to all subclasses.
|
|
7
|
+
# These include defaults, fields
|
|
8
|
+
class_inheritable_accessor :fields
|
|
9
|
+
|
|
10
|
+
self.fields = {}
|
|
11
|
+
delegate :defaults, :fields, :to => "self.class"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module ClassMethods #:nodoc
|
|
15
|
+
# Defines all the fields that are accessable on the Document
|
|
16
|
+
# For each field that is defined, a getter and setter will be
|
|
17
|
+
# added as an instance method to the Document.
|
|
18
|
+
#
|
|
19
|
+
# Options:
|
|
20
|
+
#
|
|
21
|
+
# name: The name of the field, as a +Symbol+.
|
|
22
|
+
# options: A +Hash+ of options to supply to the +Field+.
|
|
23
|
+
#
|
|
24
|
+
# Example:
|
|
25
|
+
#
|
|
26
|
+
# <tt>field :score, :default => 0</tt>
|
|
27
|
+
def field(name, options = {})
|
|
28
|
+
access = name.to_s
|
|
29
|
+
set_field(access, options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns the default values for the fields on the document
|
|
33
|
+
def defaults
|
|
34
|
+
fields.inject({}) do |defs,(field_name,field)|
|
|
35
|
+
next(defs) if field.default.nil?
|
|
36
|
+
defs[field_name.to_s] = field.default
|
|
37
|
+
defs
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
protected
|
|
42
|
+
# Define a field attribute for the +Document+.
|
|
43
|
+
def set_field(name, options = {})
|
|
44
|
+
meth = options.delete(:as) || name
|
|
45
|
+
fields[name] = Field.new(name, options)
|
|
46
|
+
create_accessors(name, meth, options)
|
|
47
|
+
add_dirty_methods(name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Create the field accessors.
|
|
51
|
+
def create_accessors(name, meth, options = {})
|
|
52
|
+
define_method(meth) { read_attribute(name) }
|
|
53
|
+
define_method("#{meth}=") { |value| write_attribute(name, value) }
|
|
54
|
+
define_method("#{meth}?") do
|
|
55
|
+
attr = read_attribute(name)
|
|
56
|
+
(options[:type] == Boolean) ? attr == true : attr.present?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Finders #:nodoc:
|
|
4
|
+
|
|
5
|
+
# Delegate to the criteria methods that are natural for creating a new
|
|
6
|
+
# criteria.
|
|
7
|
+
[ :all_in, :any_in, :avg, :excludes, :limit, :max, :min,
|
|
8
|
+
:not_in, :only, :order_by, :skip, :sum, :where ].each do |name|
|
|
9
|
+
define_method(name) do |*args|
|
|
10
|
+
criteria.send(name, *args)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Find +Documents+ given the conditions.
|
|
15
|
+
#
|
|
16
|
+
# Options:
|
|
17
|
+
#
|
|
18
|
+
# args: A +Hash+ with a conditions key and other options
|
|
19
|
+
#
|
|
20
|
+
# <tt>Person.all(:conditions => { :attribute => "value" })</tt>
|
|
21
|
+
def all(*args)
|
|
22
|
+
find(:all, *args)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns a count of matching records in the database based on the
|
|
26
|
+
# provided arguments.
|
|
27
|
+
#
|
|
28
|
+
# <tt>Person.count(:first, :conditions => { :attribute => "value" })</tt>
|
|
29
|
+
def count(*args)
|
|
30
|
+
Criteria.translate(self, *args).count
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Helper to initialize a new +Criteria+ object for this class.
|
|
34
|
+
#
|
|
35
|
+
# Example:
|
|
36
|
+
#
|
|
37
|
+
# <tt>Person.criteria</tt>
|
|
38
|
+
def criteria
|
|
39
|
+
Criteria.new(self)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Find a +Document+ in several different ways.
|
|
43
|
+
#
|
|
44
|
+
# If a +String+ is provided, it will be assumed that it is a
|
|
45
|
+
# representation of a Mongo::ObjectID and will attempt to find a single
|
|
46
|
+
# +Document+ based on that id. If a +Symbol+ and +Hash+ is provided then
|
|
47
|
+
# it will attempt to find either a single +Document+ or multiples based
|
|
48
|
+
# on the conditions provided and the first parameter.
|
|
49
|
+
#
|
|
50
|
+
# <tt>Person.find(:first, :conditions => { :attribute => "value" })</tt>
|
|
51
|
+
#
|
|
52
|
+
# <tt>Person.find(:all, :conditions => { :attribute => "value" })</tt>
|
|
53
|
+
#
|
|
54
|
+
# <tt>Person.find(Mongo::ObjectID.new.to_s)</tt>
|
|
55
|
+
def find(*args)
|
|
56
|
+
raise Errors::InvalidOptions.new("Calling Document#find with nil is invalid") if args[0].nil?
|
|
57
|
+
type = args.delete_at(0) if args[0].is_a?(Symbol)
|
|
58
|
+
criteria = Criteria.translate(self, *args)
|
|
59
|
+
case type
|
|
60
|
+
when :first then return criteria.one
|
|
61
|
+
when :last then return criteria.last
|
|
62
|
+
else
|
|
63
|
+
return criteria
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Find the first +Document+ given the conditions, or creates a new document
|
|
68
|
+
# with the conditions that were supplied
|
|
69
|
+
#
|
|
70
|
+
# Options:
|
|
71
|
+
#
|
|
72
|
+
# args: A +Hash+ of attributes
|
|
73
|
+
#
|
|
74
|
+
# <tt>Person.find_or_create_by(:attribute => "value")</tt>
|
|
75
|
+
def find_or_create_by(attrs = {})
|
|
76
|
+
find_or(:create, attrs)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Find the first +Document+ given the conditions, or instantiates a new document
|
|
80
|
+
# with the conditions that were supplied
|
|
81
|
+
#
|
|
82
|
+
# Options:
|
|
83
|
+
#
|
|
84
|
+
# args: A +Hash+ of attributes
|
|
85
|
+
#
|
|
86
|
+
# <tt>Person.find_or_initialize_by(:attribute => "value")</tt>
|
|
87
|
+
def find_or_initialize_by(attrs = {})
|
|
88
|
+
find_or(:new, attrs)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Find the first +Document+ given the conditions.
|
|
92
|
+
#
|
|
93
|
+
# Options:
|
|
94
|
+
#
|
|
95
|
+
# args: A +Hash+ with a conditions key and other options
|
|
96
|
+
#
|
|
97
|
+
# <tt>Person.first(:conditions => { :attribute => "value" })</tt>
|
|
98
|
+
def first(*args)
|
|
99
|
+
find(:first, *args)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Find the last +Document+ given the conditions.
|
|
103
|
+
#
|
|
104
|
+
# Options:
|
|
105
|
+
#
|
|
106
|
+
# args: A +Hash+ with a conditions key and other options
|
|
107
|
+
#
|
|
108
|
+
# <tt>Person.last(:conditions => { :attribute => "value" })</tt>
|
|
109
|
+
def last(*args)
|
|
110
|
+
find(:last, *args)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Find all documents in paginated fashion given the supplied arguments.
|
|
114
|
+
# If no parameters are passed just default to offset 0 and limit 20.
|
|
115
|
+
#
|
|
116
|
+
# Options:
|
|
117
|
+
#
|
|
118
|
+
# params: A +Hash+ of params to pass to the Criteria API.
|
|
119
|
+
#
|
|
120
|
+
# Example:
|
|
121
|
+
#
|
|
122
|
+
# <tt>Person.paginate(:conditions => { :field => "Test" }, :page => 1,
|
|
123
|
+
# :per_page => 20)</tt>
|
|
124
|
+
#
|
|
125
|
+
# Returns paginated array of docs.
|
|
126
|
+
def paginate(params = {})
|
|
127
|
+
Criteria.translate(self, params).paginate
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
protected
|
|
131
|
+
# Find the first object or create/initialize it.
|
|
132
|
+
def find_or(method, attrs = {})
|
|
133
|
+
first(:conditions => attrs) || send(method, attrs)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
class Identity #:nodoc:
|
|
4
|
+
class << self
|
|
5
|
+
# Create the identity for the +Document+.
|
|
6
|
+
#
|
|
7
|
+
# The id will be set in either in the form of a Mongo
|
|
8
|
+
# +ObjectID+ or a composite key set up by defining a key on the document.
|
|
9
|
+
#
|
|
10
|
+
# The _type will be set to the document's class name.
|
|
11
|
+
def create(doc)
|
|
12
|
+
identify(doc); type(doc); doc
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
protected
|
|
16
|
+
# Return the proper id for the document.
|
|
17
|
+
def generate_id
|
|
18
|
+
id = Mongo::ObjectID.new
|
|
19
|
+
Mongoid.use_object_ids ? id : id.to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Set the id for the document.
|
|
23
|
+
def identify(doc)
|
|
24
|
+
doc.id = compose(doc).join(" ").identify if doc.primary_key
|
|
25
|
+
doc.id = generate_id unless doc.id
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Set the _type field on the document.
|
|
29
|
+
def type(doc)
|
|
30
|
+
doc._type = doc.class.name if Mongoid.persist_types
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Generates the composite key for a document.
|
|
34
|
+
def compose(doc)
|
|
35
|
+
doc.primary_key.collect { |key| doc.attributes[key] }.reject { |val| val.nil? }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
module Indexes #:nodoc
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
cattr_accessor :indexed
|
|
7
|
+
self.indexed = false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassMethods #:nodoc
|
|
11
|
+
# Add the default indexes to the root document if they do not already
|
|
12
|
+
# exist. Currently this is only _type.
|
|
13
|
+
def add_indexes
|
|
14
|
+
unless indexed
|
|
15
|
+
self._collection.create_index(:_type, false)
|
|
16
|
+
self.indexed = true
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Adds an index on the field specified. Options can be :unique => true or
|
|
21
|
+
# :unique => false. It will default to the latter.
|
|
22
|
+
def index(name, options = { :unique => false })
|
|
23
|
+
collection.create_index(name, options[:unique])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -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
|
|
@@ -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,36 @@
|
|
|
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
|
+
module Matchers
|
|
16
|
+
# Determines if this document has the attributes to match the supplied
|
|
17
|
+
# MongoDB selector. Used for matching on embedded associations.
|
|
18
|
+
def matches?(selector)
|
|
19
|
+
selector.each_pair do |key, value|
|
|
20
|
+
return false unless matcher(key, value).matches?(value)
|
|
21
|
+
end
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
# Get the matcher for the supplied key and value. Will determine the class
|
|
27
|
+
# name from the key.
|
|
28
|
+
def matcher(key, value)
|
|
29
|
+
if value.is_a?(Hash)
|
|
30
|
+
name = "Mongoid::Matchers::#{value.keys.first.gsub("$", "").camelize}"
|
|
31
|
+
return name.constantize.new(attributes[key])
|
|
32
|
+
end
|
|
33
|
+
Default.new(attributes[key])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
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 == value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
# Return the first value in the hash.
|
|
16
|
+
def first(value)
|
|
17
|
+
value.values.first
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# If object exists then compare, else return false
|
|
21
|
+
def determine(value, operator)
|
|
22
|
+
@attribute ? @attribute.send(operator, first(value)) : false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
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
|