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,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,33 @@
|
|
|
1
|
+
module Mongoid #:nodoc
|
|
2
|
+
module Memoization
|
|
3
|
+
|
|
4
|
+
# Handles cases when accessing an association that should be memoized in
|
|
5
|
+
# the Mongoid specific manner. Does not memoize nil values though
|
|
6
|
+
def memoized(name, &block)
|
|
7
|
+
var = "@#{name}"
|
|
8
|
+
if instance_variable_defined?(var)
|
|
9
|
+
return instance_variable_get(var)
|
|
10
|
+
end
|
|
11
|
+
value = yield
|
|
12
|
+
instance_variable_set(var, value) if value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Removes an memozied association if it exists
|
|
16
|
+
def unmemoize(name)
|
|
17
|
+
var = "@#{name}"
|
|
18
|
+
remove_instance_variable(var) if instance_variable_defined?(var)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Mongoid specific behavior is to remove the memoized object when setting
|
|
22
|
+
# the association, or if it wasn't previously memoized it will get set.
|
|
23
|
+
def reset(name, &block)
|
|
24
|
+
var = "@#{name}"
|
|
25
|
+
value = yield
|
|
26
|
+
if instance_variable_defined?(var)
|
|
27
|
+
remove_instance_variable(var)
|
|
28
|
+
else
|
|
29
|
+
instance_variable_set(var, value)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
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, options = {}, &block)
|
|
20
|
+
name = name.to_sym
|
|
21
|
+
scopes[name] = lambda do |parent, *args|
|
|
22
|
+
Scope.new(parent, options.scoped(*args), &block)
|
|
23
|
+
end
|
|
24
|
+
(class << self; self; end).class_eval <<-EOT
|
|
25
|
+
def #{name}(*args)
|
|
26
|
+
scopes[:#{name}].call(self, *args)
|
|
27
|
+
end
|
|
28
|
+
EOT
|
|
29
|
+
end
|
|
30
|
+
alias :scope :named_scope
|
|
31
|
+
|
|
32
|
+
# Return the scopes or default to an empty +Hash+.
|
|
33
|
+
def scopes
|
|
34
|
+
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Paranoid #:nodoc:
|
|
4
|
+
# Find deleted documents
|
|
5
|
+
#
|
|
6
|
+
# Examples:
|
|
7
|
+
#
|
|
8
|
+
# <tt>Person.deleted</tt> # all deleted employees
|
|
9
|
+
# <tt>Company.first.employees.deleted</tt> # works with a join
|
|
10
|
+
# <tt>Person.deleted.find("4c188dea7b17235a2a000001").first</tt> # retrieve by id a deleted person
|
|
11
|
+
def deleted
|
|
12
|
+
where(:deleted_at.exists => false)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Include this module to get soft deletion of root level documents.
|
|
17
|
+
# This will add a deleted_at field to the +Document+, managed automatically.
|
|
18
|
+
# Potentially incompatible with unique indices. (if collisions with deleted items)
|
|
19
|
+
#
|
|
20
|
+
# To use:
|
|
21
|
+
#
|
|
22
|
+
# class Person
|
|
23
|
+
# include Mongoid::Document
|
|
24
|
+
# include Mongoid::Paranoia
|
|
25
|
+
# end
|
|
26
|
+
module Paranoia
|
|
27
|
+
extend ActiveSupport::Concern
|
|
28
|
+
|
|
29
|
+
included do
|
|
30
|
+
Mongoid::Criteria.send(:include, Mongoid::Paranoid)
|
|
31
|
+
field :deleted_at, :type => Time
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Delete the paranoid +Document+ from the database completely. This will
|
|
35
|
+
# run the destroy callbacks.
|
|
36
|
+
#
|
|
37
|
+
# Example:
|
|
38
|
+
#
|
|
39
|
+
# <tt>document.destroy!</tt>
|
|
40
|
+
def destroy!
|
|
41
|
+
run_callbacks(:destroy) { delete! }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Delete the paranoid +Document+ from the database completely.
|
|
45
|
+
#
|
|
46
|
+
# Example:
|
|
47
|
+
#
|
|
48
|
+
# <tt>document.delete!</tt>
|
|
49
|
+
def delete!
|
|
50
|
+
@destroyed = true
|
|
51
|
+
Mongoid::Persistence::Remove.new(self).persist
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Delete the +Document+, will set the deleted_at timestamp and not actually
|
|
55
|
+
# delete it.
|
|
56
|
+
#
|
|
57
|
+
# Example:
|
|
58
|
+
#
|
|
59
|
+
# <tt>document._remove</tt>
|
|
60
|
+
#
|
|
61
|
+
# Returns:
|
|
62
|
+
#
|
|
63
|
+
# true
|
|
64
|
+
def _remove
|
|
65
|
+
now = Time.now
|
|
66
|
+
collection.update({ :_id => self.id }, { '$set' => { :deleted_at => Time.now } })
|
|
67
|
+
@attributes["deleted_at"] = now
|
|
68
|
+
true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
alias :delete :_remove
|
|
72
|
+
|
|
73
|
+
# Determines if this document is destroyed.
|
|
74
|
+
#
|
|
75
|
+
# Returns:
|
|
76
|
+
#
|
|
77
|
+
# true if the +Document+ was destroyed.
|
|
78
|
+
def destroyed?
|
|
79
|
+
@destroyed || !!deleted_at
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Restores a previously soft-deleted document. Handles this by removing the
|
|
83
|
+
# deleted_at flag.
|
|
84
|
+
#
|
|
85
|
+
# Example:
|
|
86
|
+
#
|
|
87
|
+
# <tt>document.restore</tt>
|
|
88
|
+
def restore
|
|
89
|
+
collection.update({ :_id => self.id }, { '$unset' => { :deleted_at => true } })
|
|
90
|
+
@attributes.delete("deleted_at")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
module ClassMethods #:nodoc:
|
|
94
|
+
|
|
95
|
+
# Override the default +Criteria+ accessor to only get existing
|
|
96
|
+
# documents.
|
|
97
|
+
#
|
|
98
|
+
# Returns:
|
|
99
|
+
#
|
|
100
|
+
# A +Criteria+ for deleted_at not existing.
|
|
101
|
+
def criteria
|
|
102
|
+
super.where(:deleted_at.exists => false)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Paths #:nodoc:
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
cattr_accessor :__path
|
|
7
|
+
attr_accessor :_index
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Get the insertion modifier for the document. Will be nil on root
|
|
11
|
+
# documents, $set on embeds_one, $push on embeds_many.
|
|
12
|
+
#
|
|
13
|
+
# Example:
|
|
14
|
+
#
|
|
15
|
+
# <tt>name.inserter</tt>
|
|
16
|
+
def _inserter
|
|
17
|
+
embedded? ? (embedded_many? ? "$push" : "$set") : nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Return the path to this +Document+ in JSON notation, used for atomic
|
|
21
|
+
# updates via $set in MongoDB.
|
|
22
|
+
#
|
|
23
|
+
# Example:
|
|
24
|
+
#
|
|
25
|
+
# <tt>address.path # returns "addresses"</tt>
|
|
26
|
+
def _path
|
|
27
|
+
_position.sub!(/\.\d+$/, '') || _position
|
|
28
|
+
end
|
|
29
|
+
alias :_pull :_path
|
|
30
|
+
|
|
31
|
+
# Returns the positional operator of this document for modification.
|
|
32
|
+
#
|
|
33
|
+
# Example:
|
|
34
|
+
#
|
|
35
|
+
# <tt>address.position</tt>
|
|
36
|
+
def _position
|
|
37
|
+
locator = _index ? (new_record? ? "" : ".#{_index}") : ""
|
|
38
|
+
embedded? ? "#{_parent._position}#{"." unless _parent._position.blank?}#{@association_name}#{locator}" : ""
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Get the removal modifier for the document. Will be nil on root
|
|
42
|
+
# documents, $unset on embeds_one, $set on embeds_many.
|
|
43
|
+
#
|
|
44
|
+
# Example:
|
|
45
|
+
#
|
|
46
|
+
# <tt>name.remover</tt>
|
|
47
|
+
def _remover
|
|
48
|
+
embedded? ? (_index ? "$pull" : "$unset") : nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Return the selector for this document to be matched exactly for use
|
|
52
|
+
# with MongoDB's $ operator.
|
|
53
|
+
#
|
|
54
|
+
# Example:
|
|
55
|
+
#
|
|
56
|
+
# <tt>address.selector</tt>
|
|
57
|
+
def _selector
|
|
58
|
+
embedded? ? _parent._selector.merge("#{_path}._id" => id) : { "_id" => id }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/persistence/command"
|
|
3
|
+
require "mongoid/persistence/insert"
|
|
4
|
+
require "mongoid/persistence/insert_embedded"
|
|
5
|
+
require "mongoid/persistence/remove"
|
|
6
|
+
require "mongoid/persistence/remove_all"
|
|
7
|
+
require "mongoid/persistence/remove_embedded"
|
|
8
|
+
require "mongoid/persistence/update"
|
|
9
|
+
|
|
10
|
+
module Mongoid #:nodoc:
|
|
11
|
+
# The persistence module is a mixin to provide database accessor methods for
|
|
12
|
+
# the document. These correspond to the appropriate accessors on a
|
|
13
|
+
# +Mongo::Collection+ and retain the same DSL.
|
|
14
|
+
#
|
|
15
|
+
# Examples:
|
|
16
|
+
#
|
|
17
|
+
# <tt>document.insert</tt>
|
|
18
|
+
# <tt>document.update</tt>
|
|
19
|
+
# <tt>document.upsert</tt>
|
|
20
|
+
module Persistence
|
|
21
|
+
extend ActiveSupport::Concern
|
|
22
|
+
# Remove the +Document+ from the datbase with callbacks.
|
|
23
|
+
#
|
|
24
|
+
# Example:
|
|
25
|
+
#
|
|
26
|
+
# <tt>document.destroy</tt>
|
|
27
|
+
#
|
|
28
|
+
# TODO: Will get rid of other #destroy once new persistence complete.
|
|
29
|
+
def destroy
|
|
30
|
+
run_callbacks(:destroy) { self.destroyed = true if _remove }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Insert a new +Document+ into the database. Will return the document
|
|
34
|
+
# itself whether or not the save was successful.
|
|
35
|
+
#
|
|
36
|
+
# Example:
|
|
37
|
+
#
|
|
38
|
+
# <tt>document.insert</tt>
|
|
39
|
+
def insert(validate = true)
|
|
40
|
+
Insert.new(self, validate).persist
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Remove the +Document+ from the datbase.
|
|
44
|
+
#
|
|
45
|
+
# Example:
|
|
46
|
+
#
|
|
47
|
+
# <tt>document._remove</tt>
|
|
48
|
+
#
|
|
49
|
+
# TODO: Will get rid of other #remove once observable pattern killed.
|
|
50
|
+
def _remove
|
|
51
|
+
Remove.new(self).persist
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
alias :delete :_remove
|
|
55
|
+
|
|
56
|
+
# Save the document - will perform an insert if the document is new, and
|
|
57
|
+
# update if not. If a validation error occurs a
|
|
58
|
+
# Mongoid::Errors::Validations error will get raised.
|
|
59
|
+
#
|
|
60
|
+
# Example:
|
|
61
|
+
#
|
|
62
|
+
# <tt>document.save!</tt>
|
|
63
|
+
#
|
|
64
|
+
# Returns:
|
|
65
|
+
#
|
|
66
|
+
# +true+ if validation passed, will raise error otherwise.
|
|
67
|
+
def save!
|
|
68
|
+
self.class.fail_validate!(self) unless upsert; true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Update the +Document+ in the datbase.
|
|
72
|
+
#
|
|
73
|
+
# Example:
|
|
74
|
+
#
|
|
75
|
+
# <tt>document.update</tt>
|
|
76
|
+
def update(validate = true)
|
|
77
|
+
Update.new(self, validate).persist
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Update the +Document+ attributes in the datbase.
|
|
81
|
+
#
|
|
82
|
+
# Example:
|
|
83
|
+
#
|
|
84
|
+
# <tt>document.update_attributes(:title => "Sir")</tt>
|
|
85
|
+
#
|
|
86
|
+
# Returns:
|
|
87
|
+
#
|
|
88
|
+
# +true+ if validation passed, +false+ if not.
|
|
89
|
+
def update_attributes(attributes = {})
|
|
90
|
+
write_attributes(attributes); update
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Update the +Document+ attributes in the datbase.
|
|
94
|
+
#
|
|
95
|
+
# Example:
|
|
96
|
+
#
|
|
97
|
+
# <tt>document.update_attributes(:title => "Sir")</tt>
|
|
98
|
+
#
|
|
99
|
+
# Returns:
|
|
100
|
+
#
|
|
101
|
+
# +true+ if validation passed, raises an error if not
|
|
102
|
+
def update_attributes!(attributes = {})
|
|
103
|
+
write_attributes(attributes)
|
|
104
|
+
result = update
|
|
105
|
+
self.class.fail_validate!(self) unless result
|
|
106
|
+
result
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Upsert the document - will perform an insert if the document is new, and
|
|
110
|
+
# update if not.
|
|
111
|
+
#
|
|
112
|
+
# Example:
|
|
113
|
+
#
|
|
114
|
+
# <tt>document.upsert</tt>
|
|
115
|
+
#
|
|
116
|
+
# Returns:
|
|
117
|
+
#
|
|
118
|
+
# A +Boolean+ for updates.
|
|
119
|
+
def upsert(validate = true)
|
|
120
|
+
validate = parse_validate(validate)
|
|
121
|
+
if new_record?
|
|
122
|
+
insert(validate).persisted?
|
|
123
|
+
else
|
|
124
|
+
update(validate)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Save is aliased so that users familiar with active record can have some
|
|
129
|
+
# semblance of a familiar API.
|
|
130
|
+
#
|
|
131
|
+
# Example:
|
|
132
|
+
#
|
|
133
|
+
# <tt>document.save</tt>
|
|
134
|
+
alias :save :upsert
|
|
135
|
+
|
|
136
|
+
protected
|
|
137
|
+
# Alternative validation params.
|
|
138
|
+
def parse_validate(validate)
|
|
139
|
+
if validate.is_a?(Hash) && validate.has_key?(:validate)
|
|
140
|
+
validate = validate[:validate]
|
|
141
|
+
end
|
|
142
|
+
validate
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
module ClassMethods #:nodoc:
|
|
146
|
+
|
|
147
|
+
# Create a new +Document+. This will instantiate a new document and
|
|
148
|
+
# insert it in a single call. Will always return the document
|
|
149
|
+
# whether save passed or not.
|
|
150
|
+
#
|
|
151
|
+
# Example:
|
|
152
|
+
#
|
|
153
|
+
# <tt>Person.create(:title => "Mr")</tt>
|
|
154
|
+
#
|
|
155
|
+
# Returns: the +Document+.
|
|
156
|
+
def create(attributes = {})
|
|
157
|
+
new(attributes).tap(&:insert)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Create a new +Document+. This will instantiate a new document and
|
|
161
|
+
# insert it in a single call. Will always return the document
|
|
162
|
+
# whether save passed or not, and if validation fails an error will be
|
|
163
|
+
# raise.
|
|
164
|
+
#
|
|
165
|
+
# Example:
|
|
166
|
+
#
|
|
167
|
+
# <tt>Person.create!(:title => "Mr")</tt>
|
|
168
|
+
#
|
|
169
|
+
# Returns: the +Document+.
|
|
170
|
+
def create!(attributes = {})
|
|
171
|
+
document = new(attributes)
|
|
172
|
+
fail_validate!(document) if document.insert.errors.any?
|
|
173
|
+
document
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Delete all documents given the supplied conditions. If no conditions
|
|
177
|
+
# are passed, the entire collection will be dropped for performance
|
|
178
|
+
# benefits. Does not fire any callbacks.
|
|
179
|
+
#
|
|
180
|
+
# Example:
|
|
181
|
+
#
|
|
182
|
+
# <tt>Person.delete_all(:conditions => { :title => "Sir" })</tt>
|
|
183
|
+
# <tt>Person.delete_all</tt>
|
|
184
|
+
#
|
|
185
|
+
# Returns: true or raises an error.
|
|
186
|
+
def delete_all(conditions = {})
|
|
187
|
+
RemoveAll.new(
|
|
188
|
+
self,
|
|
189
|
+
false,
|
|
190
|
+
conditions[:conditions] || {}
|
|
191
|
+
).persist
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Delete all documents given the supplied conditions. If no conditions
|
|
195
|
+
# are passed, the entire collection will be dropped for performance
|
|
196
|
+
# benefits. Fires the destroy callbacks if conditions were passed.
|
|
197
|
+
#
|
|
198
|
+
# Example:
|
|
199
|
+
#
|
|
200
|
+
# <tt>Person.destroy_all(:conditions => { :title => "Sir" })</tt>
|
|
201
|
+
# <tt>Person.destroy_all</tt>
|
|
202
|
+
#
|
|
203
|
+
# Returns: true or raises an error.
|
|
204
|
+
def destroy_all(conditions = {})
|
|
205
|
+
documents = all(conditions)
|
|
206
|
+
count = documents.count
|
|
207
|
+
documents.each { |doc| doc.destroy }; count
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Raise an error if validation failed.
|
|
211
|
+
def fail_validate!(document)
|
|
212
|
+
raise Errors::Validations.new(document)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|