mongoid-locomotive 2.0.0.beta9
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/MIT_LICENSE +20 -0
- data/README.rdoc +47 -0
- data/lib/mongoid.rb +141 -0
- data/lib/mongoid/associations.rb +306 -0
- data/lib/mongoid/associations/embedded_in.rb +74 -0
- data/lib/mongoid/associations/embeds_many.rb +280 -0
- data/lib/mongoid/associations/embeds_one.rb +97 -0
- data/lib/mongoid/associations/foreign_key.rb +35 -0
- data/lib/mongoid/associations/meta_data.rb +38 -0
- data/lib/mongoid/associations/options.rb +62 -0
- data/lib/mongoid/associations/proxy.rb +33 -0
- data/lib/mongoid/associations/referenced_in.rb +59 -0
- data/lib/mongoid/associations/references_many.rb +245 -0
- data/lib/mongoid/associations/references_many_as_array.rb +78 -0
- data/lib/mongoid/associations/references_one.rb +99 -0
- data/lib/mongoid/atomicity.rb +55 -0
- data/lib/mongoid/attributes.rb +242 -0
- data/lib/mongoid/callbacks.rb +21 -0
- data/lib/mongoid/collection.rb +120 -0
- data/lib/mongoid/collections.rb +71 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +29 -0
- data/lib/mongoid/collections/operations.rb +41 -0
- data/lib/mongoid/collections/slaves.rb +45 -0
- data/lib/mongoid/components.rb +34 -0
- data/lib/mongoid/config.rb +263 -0
- data/lib/mongoid/contexts.rb +24 -0
- data/lib/mongoid/contexts/enumerable.rb +156 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +285 -0
- data/lib/mongoid/contexts/paging.rb +50 -0
- data/lib/mongoid/criteria.rb +248 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +110 -0
- data/lib/mongoid/criterion/optional.rb +189 -0
- data/lib/mongoid/cursor.rb +81 -0
- data/lib/mongoid/deprecation.rb +21 -0
- data/lib/mongoid/dirty.rb +252 -0
- data/lib/mongoid/document.rb +210 -0
- data/lib/mongoid/errors.rb +131 -0
- data/lib/mongoid/extensions.rb +115 -0
- data/lib/mongoid/extensions/array/accessors.rb +17 -0
- data/lib/mongoid/extensions/array/assimilation.rb +26 -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 +24 -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/accessors.rb +42 -0
- data/lib/mongoid/extensions/hash/assimilation.rb +40 -0
- data/lib/mongoid/extensions/hash/conversions.rb +42 -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 +20 -0
- data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
- data/lib/mongoid/extensions/object/conversions.rb +21 -0
- data/lib/mongoid/extensions/objectid/conversions.rb +15 -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 +15 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +35 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +20 -0
- data/lib/mongoid/field.rb +83 -0
- data/lib/mongoid/fields.rb +62 -0
- data/lib/mongoid/finders.rb +145 -0
- data/lib/mongoid/hierarchy.rb +74 -0
- data/lib/mongoid/identity.rb +47 -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/logger.rb +19 -0
- data/lib/mongoid/matchers.rb +35 -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 +33 -0
- data/lib/mongoid/named_scope.rb +37 -0
- data/lib/mongoid/paranoia.rb +106 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence.rb +216 -0
- data/lib/mongoid/persistence/command.rb +39 -0
- data/lib/mongoid/persistence/insert.rb +48 -0
- data/lib/mongoid/persistence/insert_embedded.rb +44 -0
- data/lib/mongoid/persistence/remove.rb +39 -0
- data/lib/mongoid/persistence/remove_all.rb +38 -0
- data/lib/mongoid/persistence/remove_embedded.rb +50 -0
- data/lib/mongoid/persistence/update.rb +71 -0
- data/lib/mongoid/railtie.rb +67 -0
- data/lib/mongoid/railties/database.rake +60 -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 +5 -0
- data/lib/mongoid/validations/uniqueness.rb +56 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +26 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
- data/lib/rails/generators/mongoid_generator.rb +61 -0
- data/spec/integration/mongoid/association_attributes_spec.rb +71 -0
- data/spec/integration/mongoid/associations_spec.rb +768 -0
- data/spec/integration/mongoid/attributes_spec.rb +59 -0
- data/spec/integration/mongoid/callback_spec.rb +33 -0
- data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
- data/spec/integration/mongoid/criteria_spec.rb +281 -0
- data/spec/integration/mongoid/dirty_spec.rb +85 -0
- data/spec/integration/mongoid/document_spec.rb +741 -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 +171 -0
- data/spec/integration/mongoid/named_scope_spec.rb +58 -0
- data/spec/integration/mongoid/paranoia_spec.rb +44 -0
- data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
- data/spec/integration/mongoid/persistence_spec.rb +311 -0
- data/spec/integration/mongoid/validations/uniqueness_spec.rb +206 -0
- data/spec/models/account.rb +5 -0
- data/spec/models/address.rb +40 -0
- data/spec/models/agent.rb +7 -0
- data/spec/models/animal.rb +15 -0
- data/spec/models/answer.rb +4 -0
- data/spec/models/callbacks.rb +47 -0
- data/spec/models/category.rb +13 -0
- data/spec/models/comment.rb +10 -0
- data/spec/models/country_code.rb +6 -0
- data/spec/models/employer.rb +5 -0
- data/spec/models/favorite.rb +8 -0
- data/spec/models/game.rb +9 -0
- data/spec/models/inheritance.rb +72 -0
- data/spec/models/location.rb +5 -0
- data/spec/models/login.rb +6 -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/paranoid_post.rb +18 -0
- data/spec/models/parents.rb +32 -0
- data/spec/models/patient.rb +15 -0
- data/spec/models/person.rb +106 -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 +25 -0
- data/spec/models/preference.rb +7 -0
- data/spec/models/question.rb +8 -0
- data/spec/models/survey.rb +6 -0
- data/spec/models/translation.rb +5 -0
- data/spec/models/user.rb +6 -0
- data/spec/models/user_accout.rb +5 -0
- data/spec/models/vet_visit.rb +5 -0
- data/spec/models/video.rb +5 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
- data/spec/unit/mongoid/associations/embeds_many_spec.rb +626 -0
- data/spec/unit/mongoid/associations/embeds_one_spec.rb +287 -0
- data/spec/unit/mongoid/associations/foreign_key_spec.rb +90 -0
- data/spec/unit/mongoid/associations/meta_data_spec.rb +110 -0
- data/spec/unit/mongoid/associations/options_spec.rb +215 -0
- data/spec/unit/mongoid/associations/referenced_in_spec.rb +145 -0
- data/spec/unit/mongoid/associations/references_many_as_array_spec.rb +424 -0
- data/spec/unit/mongoid/associations/references_many_spec.rb +502 -0
- data/spec/unit/mongoid/associations/references_one_spec.rb +204 -0
- data/spec/unit/mongoid/associations_spec.rb +688 -0
- data/spec/unit/mongoid/atomicity_spec.rb +164 -0
- data/spec/unit/mongoid/attributes_spec.rb +646 -0
- data/spec/unit/mongoid/callbacks_spec.rb +85 -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/slaves_spec.rb +81 -0
- data/spec/unit/mongoid/collections_spec.rb +98 -0
- data/spec/unit/mongoid/config_spec.rb +298 -0
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +447 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +703 -0
- data/spec/unit/mongoid/contexts_spec.rb +25 -0
- data/spec/unit/mongoid/criteria_spec.rb +873 -0
- data/spec/unit/mongoid/criterion/complex_spec.rb +17 -0
- data/spec/unit/mongoid/criterion/exclusion_spec.rb +121 -0
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +274 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +483 -0
- data/spec/unit/mongoid/cursor_spec.rb +80 -0
- data/spec/unit/mongoid/deprecation_spec.rb +24 -0
- data/spec/unit/mongoid/dirty_spec.rb +430 -0
- data/spec/unit/mongoid/document_spec.rb +623 -0
- data/spec/unit/mongoid/errors_spec.rb +154 -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 +52 -0
- data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
- data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +36 -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 +145 -0
- data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +14 -0
- data/spec/unit/mongoid/extensions/false_class/equality_spec.rb +35 -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 +59 -0
- data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +35 -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 +29 -0
- data/spec/unit/mongoid/extensions/object/conversions_spec.rb +44 -0
- data/spec/unit/mongoid/extensions/objectid/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
- data/spec/unit/mongoid/extensions/set/conversions_spec.rb +21 -0
- data/spec/unit/mongoid/extensions/string/conversions_spec.rb +28 -0
- data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
- data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +107 -0
- data/spec/unit/mongoid/extensions/time_conversions_spec.rb +186 -0
- data/spec/unit/mongoid/extensions/true_class/equality_spec.rb +35 -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 +169 -0
- data/spec/unit/mongoid/fields_spec.rb +181 -0
- data/spec/unit/mongoid/finders_spec.rb +439 -0
- data/spec/unit/mongoid/hierarchy_spec.rb +68 -0
- data/spec/unit/mongoid/identity_spec.rb +109 -0
- data/spec/unit/mongoid/indexes_spec.rb +99 -0
- data/spec/unit/mongoid/javascript_spec.rb +48 -0
- data/spec/unit/mongoid/logger_spec.rb +38 -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/paranoia_spec.rb +108 -0
- data/spec/unit/mongoid/paths_spec.rb +272 -0
- data/spec/unit/mongoid/persistence/insert_embedded_spec.rb +154 -0
- data/spec/unit/mongoid/persistence/insert_spec.rb +144 -0
- data/spec/unit/mongoid/persistence/remove_all_spec.rb +82 -0
- data/spec/unit/mongoid/persistence/remove_embedded_spec.rb +152 -0
- data/spec/unit/mongoid/persistence/remove_spec.rb +89 -0
- data/spec/unit/mongoid/persistence/update_spec.rb +177 -0
- data/spec/unit/mongoid/persistence_spec.rb +452 -0
- data/spec/unit/mongoid/scope_spec.rb +240 -0
- data/spec/unit/mongoid/serialization_spec.rb +43 -0
- data/spec/unit/mongoid/state_spec.rb +94 -0
- data/spec/unit/mongoid/timestamps_spec.rb +30 -0
- data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
- data/spec/unit/mongoid/validations/uniqueness_spec.rb +201 -0
- data/spec/unit/mongoid/validations_spec.rb +43 -0
- data/spec/unit/mongoid/versioning_spec.rb +41 -0
- data/spec/unit/mongoid_spec.rb +46 -0
- metadata +433 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Criterion #:nodoc:
|
|
4
|
+
module Optional
|
|
5
|
+
|
|
6
|
+
# Adds fields to be sorted in ascending order. Will add them in the order
|
|
7
|
+
# they were passed into the method.
|
|
8
|
+
#
|
|
9
|
+
# Example:
|
|
10
|
+
#
|
|
11
|
+
# <tt>criteria.ascending(:title, :dob)</tt>
|
|
12
|
+
def ascending(*fields)
|
|
13
|
+
@options[:sort] = [] unless @options[:sort] || fields.first.nil?
|
|
14
|
+
fields.flatten.each { |field| @options[:sort] << [ field, :asc ] }
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias :asc :ascending
|
|
19
|
+
|
|
20
|
+
# Tells the criteria that the cursor that gets returned needs to be
|
|
21
|
+
# cached. This is so multiple iterations don't hit the database multiple
|
|
22
|
+
# times, however this is not advisable when working with large data sets
|
|
23
|
+
# as the entire results will get stored in memory.
|
|
24
|
+
#
|
|
25
|
+
# Example:
|
|
26
|
+
#
|
|
27
|
+
# <tt>criteria.cache</tt>
|
|
28
|
+
def cache
|
|
29
|
+
@options.merge!(:cache => true); self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Will return true if the cache option has been set.
|
|
33
|
+
#
|
|
34
|
+
# Example:
|
|
35
|
+
#
|
|
36
|
+
# <tt>criteria.cached?</tt>
|
|
37
|
+
def cached?
|
|
38
|
+
@options[:cache] == true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Adds fields to be sorted in descending order. Will add them in the order
|
|
42
|
+
# they were passed into the method.
|
|
43
|
+
#
|
|
44
|
+
# Example:
|
|
45
|
+
#
|
|
46
|
+
# <tt>criteria.descending(:title, :dob)</tt>
|
|
47
|
+
def descending(*fields)
|
|
48
|
+
@options[:sort] = [] unless @options[:sort] || fields.first.nil?
|
|
49
|
+
fields.flatten.each { |field| @options[:sort] << [ field, :desc ] }
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
alias :desc :descending
|
|
54
|
+
|
|
55
|
+
# Flags the criteria to execute against a read-only slave in the pool
|
|
56
|
+
# instead of master.
|
|
57
|
+
#
|
|
58
|
+
# Example:
|
|
59
|
+
#
|
|
60
|
+
# <tt>criteria.enslave</tt>
|
|
61
|
+
def enslave
|
|
62
|
+
@options.merge!(:enslave => true); self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Will return true if the criteria is enslaved.
|
|
66
|
+
#
|
|
67
|
+
# Example:
|
|
68
|
+
#
|
|
69
|
+
# <tt>criteria.enslaved?</tt>
|
|
70
|
+
def enslaved?
|
|
71
|
+
@options[:enslave] == true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Adds a criterion to the +Criteria+ that specifies additional options
|
|
75
|
+
# to be passed to the Ruby driver, in the exact format for the driver.
|
|
76
|
+
#
|
|
77
|
+
# Options:
|
|
78
|
+
#
|
|
79
|
+
# extras: A +Hash+ that gets set to the driver options.
|
|
80
|
+
#
|
|
81
|
+
# Example:
|
|
82
|
+
#
|
|
83
|
+
# <tt>criteria.extras(:limit => 20, :skip => 40)</tt>
|
|
84
|
+
#
|
|
85
|
+
# Returns: <tt>self</tt>
|
|
86
|
+
def extras(extras)
|
|
87
|
+
@options.merge!(extras); filter_options; self
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Adds a criterion to the +Criteria+ that specifies an id that must be matched.
|
|
91
|
+
#
|
|
92
|
+
# Options:
|
|
93
|
+
#
|
|
94
|
+
# object_id: A +String+ representation of a <tt>BSON::ObjectID</tt>
|
|
95
|
+
#
|
|
96
|
+
# Example:
|
|
97
|
+
#
|
|
98
|
+
# <tt>criteria.id("4ab2bc4b8ad548971900005c")</tt>
|
|
99
|
+
#
|
|
100
|
+
# Returns: <tt>self</tt>
|
|
101
|
+
def id(*args)
|
|
102
|
+
(args.flatten.size > 1) ? self.in(:_id => args.flatten) : (@selector[:_id] = args.first)
|
|
103
|
+
self
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
|
107
|
+
# results to return. This is mostly used in conjunction with <tt>skip()</tt>
|
|
108
|
+
# to handle paginated results.
|
|
109
|
+
#
|
|
110
|
+
# Options:
|
|
111
|
+
#
|
|
112
|
+
# value: An +Integer+ specifying the max number of results. Defaults to 20.
|
|
113
|
+
#
|
|
114
|
+
# Example:
|
|
115
|
+
#
|
|
116
|
+
# <tt>criteria.limit(100)</tt>
|
|
117
|
+
#
|
|
118
|
+
# Returns: <tt>self</tt>
|
|
119
|
+
def limit(value = 20)
|
|
120
|
+
@options[:limit] = value; self
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Returns the offset option. If a per_page option is in the list then it
|
|
124
|
+
# will replace it with a skip parameter and return the same value. Defaults
|
|
125
|
+
# to 20 if nothing was provided.
|
|
126
|
+
def offset(*args)
|
|
127
|
+
args.size > 0 ? skip(args.first) : @options[:skip]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Adds a criterion to the +Criteria+ that specifies the sort order of
|
|
131
|
+
# the returned documents in the database. Similar to a SQL "ORDER BY".
|
|
132
|
+
#
|
|
133
|
+
# Options:
|
|
134
|
+
#
|
|
135
|
+
# params: An +Array+ of [field, direction] sorting pairs.
|
|
136
|
+
#
|
|
137
|
+
# Example:
|
|
138
|
+
#
|
|
139
|
+
# <tt>criteria.order_by([[:field1, :asc], [:field2, :desc]])</tt>
|
|
140
|
+
#
|
|
141
|
+
# Returns: <tt>self</tt>
|
|
142
|
+
def order_by(*args)
|
|
143
|
+
@options[:sort] = [] unless @options[:sort] || args.first.nil?
|
|
144
|
+
arguments = args.first
|
|
145
|
+
case arguments
|
|
146
|
+
when Hash then arguments.each { |field, direction| @options[:sort] << [ field, direction ] }
|
|
147
|
+
when Array then @options[:sort].concat(arguments)
|
|
148
|
+
when Complex
|
|
149
|
+
args.flatten.each { |complex| @options[:sort] << [ complex.key, complex.operator.to_sym ] }
|
|
150
|
+
end; self
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Adds a criterion to the +Criteria+ that specifies how many results to skip
|
|
154
|
+
# when returning Documents. This is mostly used in conjunction with
|
|
155
|
+
# <tt>limit()</tt> to handle paginated results, and is similar to the
|
|
156
|
+
# traditional "offset" parameter.
|
|
157
|
+
#
|
|
158
|
+
# Options:
|
|
159
|
+
#
|
|
160
|
+
# value: An +Integer+ specifying the number of results to skip. Defaults to 0.
|
|
161
|
+
#
|
|
162
|
+
# Example:
|
|
163
|
+
#
|
|
164
|
+
# <tt>criteria.skip(20)</tt>
|
|
165
|
+
#
|
|
166
|
+
# Returns: <tt>self</tt>
|
|
167
|
+
def skip(value = 0)
|
|
168
|
+
@options[:skip] = value; self
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Adds a criterion to the +Criteria+ that specifies a type or an Array of type that must be matched.
|
|
172
|
+
#
|
|
173
|
+
# Options:
|
|
174
|
+
#
|
|
175
|
+
# types : An +Array+ of types of a +String+ representing the Type of you search
|
|
176
|
+
#
|
|
177
|
+
# Example:
|
|
178
|
+
#
|
|
179
|
+
# <tt>criteria.type('Browser')</tt>
|
|
180
|
+
# <tt>criteria.type(['Firefox', 'Browser'])</tt>
|
|
181
|
+
#
|
|
182
|
+
# Returns: <tt>self</tt>
|
|
183
|
+
def type(types)
|
|
184
|
+
types = [types] unless types.is_a?(Array)
|
|
185
|
+
self.in(:_type => types)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc
|
|
3
|
+
class Cursor
|
|
4
|
+
include Enumerable
|
|
5
|
+
# Operations on the Mongo::Cursor object that will not get overriden by the
|
|
6
|
+
# Mongoid::Cursor are defined here.
|
|
7
|
+
OPERATIONS = [
|
|
8
|
+
:close,
|
|
9
|
+
:closed?,
|
|
10
|
+
:count,
|
|
11
|
+
:explain,
|
|
12
|
+
:fields,
|
|
13
|
+
:full_collection_name,
|
|
14
|
+
:hint,
|
|
15
|
+
:limit,
|
|
16
|
+
:order,
|
|
17
|
+
:query_options_hash,
|
|
18
|
+
:query_opts,
|
|
19
|
+
:selector,
|
|
20
|
+
:skip,
|
|
21
|
+
:snapshot,
|
|
22
|
+
:sort,
|
|
23
|
+
:timeout
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
attr_reader :collection
|
|
27
|
+
|
|
28
|
+
# The operations above will all delegate to the proxied Mongo::Cursor.
|
|
29
|
+
#
|
|
30
|
+
# Example:
|
|
31
|
+
#
|
|
32
|
+
# <tt>cursor.close</tt>
|
|
33
|
+
OPERATIONS.each do |name|
|
|
34
|
+
define_method(name) { |*args| @cursor.send(name, *args) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Iterate over each document in the cursor and yield to it.
|
|
38
|
+
#
|
|
39
|
+
# Example:
|
|
40
|
+
#
|
|
41
|
+
# <tt>cursor.each { |doc| p doc.title }</tt>
|
|
42
|
+
def each
|
|
43
|
+
@cursor.each do |document|
|
|
44
|
+
yield Mongoid::Factory.build(@klass, document)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Create the new +Mongoid::Cursor+.
|
|
49
|
+
#
|
|
50
|
+
# Options:
|
|
51
|
+
#
|
|
52
|
+
# collection: The Mongoid::Collection instance.
|
|
53
|
+
# cursor: The Mongo::Cursor to be proxied.
|
|
54
|
+
#
|
|
55
|
+
# Example:
|
|
56
|
+
#
|
|
57
|
+
# <tt>Mongoid::Cursor.new(Person, cursor)</tt>
|
|
58
|
+
def initialize(klass, collection, cursor)
|
|
59
|
+
@klass, @collection, @cursor = klass, collection, cursor
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Return the next document in the cursor. Will instantiate a new Mongoid
|
|
63
|
+
# document with the attributes.
|
|
64
|
+
#
|
|
65
|
+
# Example:
|
|
66
|
+
#
|
|
67
|
+
# <tt>cursor.next_document</tt>
|
|
68
|
+
def next_document
|
|
69
|
+
Mongoid::Factory.build(@klass, @cursor.next_document)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns an array of all the documents in the cursor.
|
|
73
|
+
#
|
|
74
|
+
# Example:
|
|
75
|
+
#
|
|
76
|
+
# <tt>cursor.to_a</tt>
|
|
77
|
+
def to_a
|
|
78
|
+
@cursor.to_a.collect { |attrs| Mongoid::Factory.build(@klass, attrs) }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
class Deprecation #:nodoc
|
|
4
|
+
include Singleton
|
|
5
|
+
|
|
6
|
+
# Alert of a deprecation. This will delegate to the logger and call warn on
|
|
7
|
+
# it.
|
|
8
|
+
#
|
|
9
|
+
# Example:
|
|
10
|
+
#
|
|
11
|
+
# <tt>deprecation.alert("Method no longer used")</tt>
|
|
12
|
+
def alert(message)
|
|
13
|
+
@logger.warn("Deprecation: #{message}")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
def initialize
|
|
18
|
+
@logger = Mongoid::Logger.new
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,252 @@
|
|
|
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] : nil
|
|
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
|
+
@previous_modifications = modifications.dup
|
|
106
|
+
@modifications = {}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Gets all the new values for each of the changed fields, to be passed to
|
|
110
|
+
# a MongoDB $set modifier.
|
|
111
|
+
#
|
|
112
|
+
# Example:
|
|
113
|
+
#
|
|
114
|
+
# person = Person.new(:title => "Sir")
|
|
115
|
+
# person.title = "Madam"
|
|
116
|
+
# person.setters # returns { "title" => "Madam" }
|
|
117
|
+
#
|
|
118
|
+
# Returns:
|
|
119
|
+
#
|
|
120
|
+
# A +Hash+ of new values.
|
|
121
|
+
def setters
|
|
122
|
+
modifications.inject({}) do |sets, (field, changes)|
|
|
123
|
+
key = embedded? ? "#{_position}.#{field}" : field
|
|
124
|
+
sets[key] = changes[1]; sets
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Gets all the modifications that have happened to the object before the
|
|
129
|
+
# object was saved.
|
|
130
|
+
#
|
|
131
|
+
# Example:
|
|
132
|
+
#
|
|
133
|
+
# person = Person.new(:title => "Sir")
|
|
134
|
+
# person.title = "Madam"
|
|
135
|
+
# person.save!
|
|
136
|
+
# person.previous_changes # returns { "title" => [ "Sir", "Madam" ] }
|
|
137
|
+
#
|
|
138
|
+
# Returns:
|
|
139
|
+
#
|
|
140
|
+
# A +Hash+ of changes before save.
|
|
141
|
+
def previous_changes
|
|
142
|
+
@previous_modifications
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Resets a changed field back to its old value.
|
|
146
|
+
#
|
|
147
|
+
# Example:
|
|
148
|
+
#
|
|
149
|
+
# person = Person.new(:title => "Sir")
|
|
150
|
+
# person.title = "Madam"
|
|
151
|
+
# person.reset_attribute!("title")
|
|
152
|
+
# person.title # "Sir"
|
|
153
|
+
#
|
|
154
|
+
# Returns:
|
|
155
|
+
#
|
|
156
|
+
# The old field value.
|
|
157
|
+
def reset_attribute!(name)
|
|
158
|
+
value = attribute_was(name)
|
|
159
|
+
if value
|
|
160
|
+
@attributes[name] = value
|
|
161
|
+
modifications.delete(name)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Sets up the modifications hash. This occurs just after the document is
|
|
166
|
+
# instantiated.
|
|
167
|
+
#
|
|
168
|
+
# Example:
|
|
169
|
+
#
|
|
170
|
+
# <tt>document.setup_notifications</tt>
|
|
171
|
+
def setup_modifications
|
|
172
|
+
@accessed ||= {}
|
|
173
|
+
@modifications ||= {}
|
|
174
|
+
@previous_modifications ||= {}
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Reset all modifications for the document. This will wipe all the marked
|
|
178
|
+
# changes, but not reset the values.
|
|
179
|
+
#
|
|
180
|
+
# Example:
|
|
181
|
+
#
|
|
182
|
+
# <tt>document.reset_modifications</tt>
|
|
183
|
+
def reset_modifications
|
|
184
|
+
@accessed = {}
|
|
185
|
+
@modifications = {}
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
protected
|
|
189
|
+
|
|
190
|
+
# Audit the original value for a field that can be modified in place.
|
|
191
|
+
#
|
|
192
|
+
# Example:
|
|
193
|
+
#
|
|
194
|
+
# <tt>person.accessed("aliases", [ "007" ])</tt>
|
|
195
|
+
def accessed(name, value)
|
|
196
|
+
@accessed ||= {}
|
|
197
|
+
@accessed[name] = value.dup if (value.is_a?(Array) || value.is_a?(Hash)) && !@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
|
+
@accessed.each_pair do |field, value|
|
|
212
|
+
current = @attributes[field]
|
|
213
|
+
@modifications[field] = [ value, current ] if current != value
|
|
214
|
+
end
|
|
215
|
+
@accessed.clear
|
|
216
|
+
@modifications
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Audit the change of a field's value.
|
|
220
|
+
#
|
|
221
|
+
# Example:
|
|
222
|
+
#
|
|
223
|
+
# <tt>person.modify("name", "Jack", "John")</tt>
|
|
224
|
+
def modify(name, old_value, new_value)
|
|
225
|
+
@attributes[name] = new_value
|
|
226
|
+
if @modifications && (old_value != new_value)
|
|
227
|
+
original = @modifications[name].first if @modifications[name]
|
|
228
|
+
@modifications[name] = [ (original || old_value), new_value ]
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
module ClassMethods #:nodoc:
|
|
233
|
+
# Add the dynamic dirty methods. These are custom methods defined on a
|
|
234
|
+
# field by field basis that wrap the dirty attribute methods.
|
|
235
|
+
#
|
|
236
|
+
# Example:
|
|
237
|
+
#
|
|
238
|
+
# person = Person.new(:title => "Sir")
|
|
239
|
+
# person.title = "Madam"
|
|
240
|
+
# person.title_change # [ "Sir", "Madam" ]
|
|
241
|
+
# person.title_changed? # true
|
|
242
|
+
# person.title_was # "Sir"
|
|
243
|
+
# person.reset_title!
|
|
244
|
+
def add_dirty_methods(name)
|
|
245
|
+
define_method("#{name}_change") { attribute_change(name) } unless instance_methods.include?("#{name}_change")
|
|
246
|
+
define_method("#{name}_changed?") { attribute_changed?(name) } unless instance_methods.include?("#{name}_changed?")
|
|
247
|
+
define_method("#{name}_was") { attribute_was(name) } unless instance_methods.include?("#{name}_was")
|
|
248
|
+
define_method("reset_#{name}!") { reset_attribute!(name) } unless instance_methods.include?("reset_#{name}!")
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|