lookout-mongo_mapper 0.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +33 -0
- data/UPGRADES +26 -0
- data/bin/mmconsole +59 -0
- data/examples/attr_accessible.rb +22 -0
- data/examples/attr_protected.rb +22 -0
- data/examples/cache_key.rb +24 -0
- data/examples/custom_types.rb +24 -0
- data/examples/identity_map.rb +33 -0
- data/examples/identity_map/automatic.rb +2 -0
- data/examples/keys.rb +40 -0
- data/examples/modifiers/set.rb +25 -0
- data/examples/plugins.rb +38 -0
- data/examples/querying.rb +35 -0
- data/examples/safe.rb +43 -0
- data/examples/scopes.rb +52 -0
- data/examples/validating/embedded_docs.rb +29 -0
- data/lib/mongo_mapper.rb +94 -0
- data/lib/mongo_mapper/connection.rb +96 -0
- data/lib/mongo_mapper/document.rb +42 -0
- data/lib/mongo_mapper/embedded_document.rb +32 -0
- data/lib/mongo_mapper/exceptions.rb +30 -0
- data/lib/mongo_mapper/extensions/array.rb +19 -0
- data/lib/mongo_mapper/extensions/binary.rb +22 -0
- data/lib/mongo_mapper/extensions/boolean.rb +44 -0
- data/lib/mongo_mapper/extensions/date.rb +25 -0
- data/lib/mongo_mapper/extensions/float.rb +14 -0
- data/lib/mongo_mapper/extensions/hash.rb +14 -0
- data/lib/mongo_mapper/extensions/integer.rb +19 -0
- data/lib/mongo_mapper/extensions/kernel.rb +9 -0
- data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
- data/lib/mongo_mapper/extensions/object.rb +26 -0
- data/lib/mongo_mapper/extensions/object_id.rb +32 -0
- data/lib/mongo_mapper/extensions/set.rb +20 -0
- data/lib/mongo_mapper/extensions/string.rb +18 -0
- data/lib/mongo_mapper/extensions/time.rb +28 -0
- data/lib/mongo_mapper/locale/en.yml +5 -0
- data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
- data/lib/mongo_mapper/plugins.rb +22 -0
- data/lib/mongo_mapper/plugins/accessible.rb +52 -0
- data/lib/mongo_mapper/plugins/active_model.rb +18 -0
- data/lib/mongo_mapper/plugins/associations.rb +90 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +92 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +54 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +34 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +44 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +133 -0
- data/lib/mongo_mapper/plugins/associations/many_association.rb +63 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
- data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +22 -0
- data/lib/mongo_mapper/plugins/associations/one_association.rb +48 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +95 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +134 -0
- data/lib/mongo_mapper/plugins/associations/single_association.rb +46 -0
- data/lib/mongo_mapper/plugins/caching.rb +21 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +29 -0
- data/lib/mongo_mapper/plugins/clone.rb +22 -0
- data/lib/mongo_mapper/plugins/dirty.rb +60 -0
- data/lib/mongo_mapper/plugins/document.rb +41 -0
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +45 -0
- data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
- data/lib/mongo_mapper/plugins/embedded_callbacks.rb +56 -0
- data/lib/mongo_mapper/plugins/embedded_document.rb +53 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
- data/lib/mongo_mapper/plugins/indexes.rb +13 -0
- data/lib/mongo_mapper/plugins/inspect.rb +16 -0
- data/lib/mongo_mapper/plugins/keys.rb +313 -0
- data/lib/mongo_mapper/plugins/keys/key.rb +61 -0
- data/lib/mongo_mapper/plugins/logger.rb +18 -0
- data/lib/mongo_mapper/plugins/modifiers.rb +134 -0
- data/lib/mongo_mapper/plugins/pagination.rb +16 -0
- data/lib/mongo_mapper/plugins/persistence.rb +69 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/querying.rb +165 -0
- data/lib/mongo_mapper/plugins/querying/decorator.rb +36 -0
- data/lib/mongo_mapper/plugins/rails.rb +58 -0
- data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
- data/lib/mongo_mapper/plugins/safe.rb +28 -0
- data/lib/mongo_mapper/plugins/sci.rb +36 -0
- data/lib/mongo_mapper/plugins/scopes.rb +27 -0
- data/lib/mongo_mapper/plugins/serialization.rb +109 -0
- data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
- data/lib/mongo_mapper/plugins/touch.rb +18 -0
- data/lib/mongo_mapper/plugins/userstamps.rb +18 -0
- data/lib/mongo_mapper/plugins/validations.rb +86 -0
- data/lib/mongo_mapper/railtie.rb +48 -0
- data/lib/mongo_mapper/railtie/database.rake +65 -0
- data/lib/mongo_mapper/translation.rb +10 -0
- data/lib/mongo_mapper/version.rb +4 -0
- data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
- data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
- data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
- data/lib/rails/generators/mongo_mapper/model/templates/model.rb +13 -0
- data/test/_NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +238 -0
- data/test/functional/associations/test_in_array_proxy.rb +349 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +231 -0
- data/test/functional/associations/test_many_documents_proxy.rb +866 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +239 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +289 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
- data/test/functional/associations/test_one_as_proxy.rb +491 -0
- data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
- data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
- data/test/functional/associations/test_one_proxy.rb +383 -0
- data/test/functional/test_accessible.rb +198 -0
- data/test/functional/test_associations.rb +46 -0
- data/test/functional/test_binary.rb +27 -0
- data/test/functional/test_caching.rb +77 -0
- data/test/functional/test_callbacks.rb +232 -0
- data/test/functional/test_dirty.rb +301 -0
- data/test/functional/test_document.rb +282 -0
- data/test/functional/test_dynamic_querying.rb +75 -0
- data/test/functional/test_embedded_document.rb +288 -0
- data/test/functional/test_equality.rb +20 -0
- data/test/functional/test_identity_map.rb +513 -0
- data/test/functional/test_indexes.rb +50 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +537 -0
- data/test/functional/test_pagination.rb +91 -0
- data/test/functional/test_protected.rb +201 -0
- data/test/functional/test_querying.rb +935 -0
- data/test/functional/test_safe.rb +76 -0
- data/test/functional/test_sci.rb +240 -0
- data/test/functional/test_scopes.rb +171 -0
- data/test/functional/test_timestamps.rb +62 -0
- data/test/functional/test_touch.rb +125 -0
- data/test/functional/test_userstamps.rb +44 -0
- data/test/functional/test_validations.rb +414 -0
- data/test/models.rb +261 -0
- data/test/support/railtie.rb +4 -0
- data/test/support/railtie/autoloaded.rb +2 -0
- data/test/support/railtie/not_autoloaded.rb +3 -0
- data/test/support/railtie/parent.rb +3 -0
- data/test/test_active_model_lint.rb +18 -0
- data/test/test_helper.rb +93 -0
- data/test/unit/associations/test_base.rb +146 -0
- data/test/unit/associations/test_belongs_to_association.rb +29 -0
- data/test/unit/associations/test_many_association.rb +63 -0
- data/test/unit/associations/test_one_association.rb +47 -0
- data/test/unit/associations/test_proxy.rb +100 -0
- data/test/unit/serializers/test_json_serializer.rb +216 -0
- data/test/unit/serializers/test_xml_serializer.rb +196 -0
- data/test/unit/test_clone.rb +69 -0
- data/test/unit/test_document.rb +249 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +682 -0
- data/test/unit/test_equality.rb +38 -0
- data/test/unit/test_exceptions.rb +12 -0
- data/test/unit/test_extensions.rb +380 -0
- data/test/unit/test_identity_map_middleware.rb +34 -0
- data/test/unit/test_inspect.rb +47 -0
- data/test/unit/test_key.rb +205 -0
- data/test/unit/test_keys.rb +65 -0
- data/test/unit/test_mongo_mapper.rb +143 -0
- data/test/unit/test_pagination.rb +11 -0
- data/test/unit/test_plugins.rb +89 -0
- data/test/unit/test_rails.rb +183 -0
- data/test/unit/test_rails_compatibility.rb +38 -0
- data/test/unit/test_rails_reflect_on_association.rb +118 -0
- data/test/unit/test_railtie.rb +66 -0
- data/test/unit/test_serialization.rb +166 -0
- data/test/unit/test_time_zones.rb +44 -0
- data/test/unit/test_translation.rb +27 -0
- data/test/unit/test_validations.rb +562 -0
- metadata +285 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class Base
|
|
6
|
+
attr_reader :name, :options, :query_options
|
|
7
|
+
|
|
8
|
+
# Options that should not be considered MongoDB query options/criteria
|
|
9
|
+
AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic, :autosave, :touch]
|
|
10
|
+
|
|
11
|
+
def initialize(name, options={}, &extension)
|
|
12
|
+
@name, @options, @query_options, @original_options = name.to_sym, {}, {}, options
|
|
13
|
+
options.symbolize_keys!
|
|
14
|
+
options[:extend] = modularized_extensions(extension, options[:extend])
|
|
15
|
+
separate_options_and_conditions
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def class_name
|
|
19
|
+
@class_name ||= options[:class_name] || name.to_s.camelize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def klass
|
|
23
|
+
@klass ||= options[:class] || class_name.constantize
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def polymorphic?
|
|
27
|
+
!!@options[:polymorphic]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def as?
|
|
31
|
+
!!@options[:as]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def in_array?
|
|
35
|
+
!!@options[:in]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def embeddable?
|
|
39
|
+
klass.embeddable?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def touch?
|
|
43
|
+
!!@options[:touch]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def type_key_name
|
|
47
|
+
"_type"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def as
|
|
51
|
+
@options[:as] || self.name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def foreign_key
|
|
55
|
+
@options[:foreign_key] || "#{name}_id"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def ivar
|
|
59
|
+
@ivar ||= "@_#{name}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def proxy_class
|
|
63
|
+
raise NotImplementedError
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def setup(model)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def autosave?
|
|
70
|
+
raise NotImplementedError
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
def separate_options_and_conditions
|
|
75
|
+
@original_options.each_pair do |key, value|
|
|
76
|
+
if AssociationOptions.include?(key)
|
|
77
|
+
@options[key] = value
|
|
78
|
+
else
|
|
79
|
+
@query_options[key] = value
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def modularized_extensions(*extensions)
|
|
85
|
+
extensions.flatten.compact.map do |extension|
|
|
86
|
+
Proc === extension ? Module.new(&extension) : extension
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class BelongsToAssociation < SingleAssociation
|
|
6
|
+
def type_key_name
|
|
7
|
+
"#{as}_type"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def embeddable?
|
|
11
|
+
false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def proxy_class
|
|
15
|
+
@proxy_class ||= polymorphic? ? BelongsToPolymorphicProxy : BelongsToProxy
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def setup(model)
|
|
19
|
+
model.key foreign_key, ObjectId unless model.key?(foreign_key)
|
|
20
|
+
model.key type_key_name, String unless model.key?(type_key_name) if polymorphic?
|
|
21
|
+
super
|
|
22
|
+
add_touch_callbacks if touch?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def autosave?
|
|
26
|
+
options.fetch(:autosave, false)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def add_touch_callbacks
|
|
30
|
+
name = self.name
|
|
31
|
+
method_name = "belongs_to_touch_after_save_or_destroy_for_#{name}"
|
|
32
|
+
touch = options.fetch(:touch)
|
|
33
|
+
|
|
34
|
+
@model.send(:define_method, method_name) do
|
|
35
|
+
record = send(name)
|
|
36
|
+
|
|
37
|
+
unless record.nil?
|
|
38
|
+
if touch == true
|
|
39
|
+
record.touch
|
|
40
|
+
else
|
|
41
|
+
record.touch(touch)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
@model.after_save(method_name)
|
|
47
|
+
@model.after_touch(method_name)
|
|
48
|
+
@model.after_destroy(method_name)
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class BelongsToPolymorphicProxy < Proxy
|
|
6
|
+
def replace(doc)
|
|
7
|
+
if doc
|
|
8
|
+
doc.save unless doc.persisted?
|
|
9
|
+
id, type = doc.id, doc.class.name
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
proxy_owner[association.foreign_key] = id
|
|
13
|
+
proxy_owner[association.type_key_name] = type
|
|
14
|
+
reset
|
|
15
|
+
unless doc.nil?
|
|
16
|
+
loaded
|
|
17
|
+
@target = doc
|
|
18
|
+
end
|
|
19
|
+
@target
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
def find_target
|
|
24
|
+
return nil if association_class.nil? || proxy_owner[association.foreign_key].nil?
|
|
25
|
+
association_class.find_by_id(proxy_owner[association.foreign_key])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def association_class
|
|
29
|
+
proxy_owner[association.type_key_name] ? proxy_owner[association.type_key_name].constantize : nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class BelongsToProxy < Proxy
|
|
6
|
+
def replace(doc)
|
|
7
|
+
if doc
|
|
8
|
+
doc.save if !doc.persisted?
|
|
9
|
+
id = doc.id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
reset
|
|
13
|
+
proxy_owner[association.foreign_key] = id
|
|
14
|
+
unless doc.nil?
|
|
15
|
+
loaded
|
|
16
|
+
@target = doc
|
|
17
|
+
end
|
|
18
|
+
@target
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def build(attrs={})
|
|
22
|
+
instantiate_target(:new, attrs)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create(attrs={})
|
|
26
|
+
instantiate_target(:create, attrs)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create!(attrs={})
|
|
30
|
+
instantiate_target(:create!, attrs)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def save_to_collection(options={})
|
|
34
|
+
@target.save(options) if @target
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
def find_target
|
|
39
|
+
return nil if proxy_owner[association.foreign_key].nil?
|
|
40
|
+
klass.find_by_id(proxy_owner[association.foreign_key])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def instantiate_target(instantiator, attrs={})
|
|
44
|
+
@target = klass.send(instantiator, attrs)
|
|
45
|
+
proxy_owner[association.foreign_key] = @target.id
|
|
46
|
+
loaded
|
|
47
|
+
@target
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class Collection < Proxy
|
|
6
|
+
def to_ary
|
|
7
|
+
load_target
|
|
8
|
+
if target.is_a?(Array)
|
|
9
|
+
target.to_ary
|
|
10
|
+
else
|
|
11
|
+
Array(target)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def include?(*args)
|
|
16
|
+
load_target
|
|
17
|
+
target.include?(*args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset
|
|
21
|
+
super
|
|
22
|
+
target = []
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class EmbeddedCollection < Collection
|
|
6
|
+
def build(attributes={})
|
|
7
|
+
doc = klass.new(attributes)
|
|
8
|
+
assign_references(doc)
|
|
9
|
+
self << doc
|
|
10
|
+
doc
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def find(id)
|
|
14
|
+
load_target
|
|
15
|
+
target.detect { |item| item.id.to_s == id || item.id == id }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def count
|
|
19
|
+
load_target
|
|
20
|
+
target.size
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def <<(*docs)
|
|
24
|
+
load_target
|
|
25
|
+
docs.each do |doc|
|
|
26
|
+
assign_references(doc)
|
|
27
|
+
target << doc
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
alias_method :push, :<<
|
|
31
|
+
alias_method :concat, :<<
|
|
32
|
+
|
|
33
|
+
def save_to_collection(options={})
|
|
34
|
+
@target.each { |doc| doc.persist(options) } if @target
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
def assign_references(*docs)
|
|
39
|
+
docs.each { |doc| doc._parent_document = proxy_owner }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class InArrayProxy < Collection
|
|
6
|
+
include DynamicQuerying::ClassMethods
|
|
7
|
+
|
|
8
|
+
def find(*args)
|
|
9
|
+
query.find(*scoped_ids(args))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def find!(*args)
|
|
13
|
+
query.find!(*scoped_ids(args))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def paginate(options)
|
|
17
|
+
return [] if ids.blank?
|
|
18
|
+
query.paginate(options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def all(options={})
|
|
22
|
+
return [] if ids.blank?
|
|
23
|
+
query(options).all
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def first(options={})
|
|
27
|
+
return nil if ids.blank?
|
|
28
|
+
query(options).first
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def last(options={})
|
|
32
|
+
return nil if ids.blank?
|
|
33
|
+
query(options).last
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def count(options={})
|
|
37
|
+
return 0 if ids.blank?
|
|
38
|
+
options.blank? ? ids.size : query(options).count
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def destroy_all(options={})
|
|
42
|
+
all(options).each do |doc|
|
|
43
|
+
ids.delete(doc.id)
|
|
44
|
+
doc.destroy
|
|
45
|
+
end
|
|
46
|
+
reset
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def delete_all(options={})
|
|
50
|
+
docs = query(options).fields(:_id).all
|
|
51
|
+
docs.each { |doc| ids.delete(doc.id) }
|
|
52
|
+
klass.delete(docs.map { |d| d.id })
|
|
53
|
+
reset
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def nullify
|
|
57
|
+
replace([])
|
|
58
|
+
reset
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def create(attrs={})
|
|
62
|
+
doc = klass.create(attrs)
|
|
63
|
+
if doc.persisted?
|
|
64
|
+
ids << doc.id
|
|
65
|
+
proxy_owner.save
|
|
66
|
+
reset
|
|
67
|
+
end
|
|
68
|
+
doc
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def create!(attrs={})
|
|
72
|
+
doc = klass.create!(attrs)
|
|
73
|
+
if doc.persisted?
|
|
74
|
+
ids << doc.id
|
|
75
|
+
proxy_owner.save
|
|
76
|
+
reset
|
|
77
|
+
end
|
|
78
|
+
doc
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def <<(*docs)
|
|
82
|
+
flatten_deeper(docs).each do |doc|
|
|
83
|
+
doc.save unless doc.persisted?
|
|
84
|
+
unless ids.include?(doc.id)
|
|
85
|
+
ids << doc.id
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
reset
|
|
89
|
+
end
|
|
90
|
+
alias_method :push, :<<
|
|
91
|
+
alias_method :concat, :<<
|
|
92
|
+
|
|
93
|
+
def replace(docs)
|
|
94
|
+
doc_ids = docs.map do |doc|
|
|
95
|
+
doc.save unless doc.persisted?
|
|
96
|
+
doc.id
|
|
97
|
+
end
|
|
98
|
+
ids.replace(doc_ids.uniq)
|
|
99
|
+
reset
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private
|
|
103
|
+
def query(options={})
|
|
104
|
+
klass.
|
|
105
|
+
query(association.query_options).
|
|
106
|
+
amend(options).
|
|
107
|
+
amend(criteria)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def criteria
|
|
111
|
+
{:_id => ids}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def scoped_ids(args)
|
|
115
|
+
valid = args.flatten.select do |id|
|
|
116
|
+
id = ObjectId.to_mongo(id) if klass.using_object_id?
|
|
117
|
+
ids.include?(id)
|
|
118
|
+
end
|
|
119
|
+
valid.empty? ? nil : valid
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def find_target
|
|
123
|
+
return [] if ids.blank?
|
|
124
|
+
all
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def ids
|
|
128
|
+
proxy_owner[options[:in]]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
module MongoMapper
|
|
3
|
+
module Plugins
|
|
4
|
+
module Associations
|
|
5
|
+
class ManyAssociation < Base
|
|
6
|
+
|
|
7
|
+
def class_name
|
|
8
|
+
@class_name ||= options[:class_name] || name.to_s.singularize.camelize
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# hate this, need to revisit
|
|
12
|
+
def proxy_class
|
|
13
|
+
@proxy_class ||= if klass.embeddable?
|
|
14
|
+
polymorphic? ? ManyEmbeddedPolymorphicProxy : ManyEmbeddedProxy
|
|
15
|
+
else
|
|
16
|
+
if polymorphic?
|
|
17
|
+
ManyPolymorphicProxy
|
|
18
|
+
elsif as?
|
|
19
|
+
ManyDocumentsAsProxy
|
|
20
|
+
elsif in_array?
|
|
21
|
+
InArrayProxy
|
|
22
|
+
else
|
|
23
|
+
ManyDocumentsProxy
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def setup(model)
|
|
29
|
+
model.associations_module.module_eval <<-end_eval
|
|
30
|
+
def #{name}
|
|
31
|
+
get_proxy(associations[#{name.inspect}])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def #{name}=(value)
|
|
35
|
+
get_proxy(associations[#{name.inspect}]).replace(value)
|
|
36
|
+
value
|
|
37
|
+
end
|
|
38
|
+
end_eval
|
|
39
|
+
|
|
40
|
+
association = self
|
|
41
|
+
options = self.options
|
|
42
|
+
|
|
43
|
+
model.before_destroy do
|
|
44
|
+
if !association.embeddable?
|
|
45
|
+
case options[:dependent]
|
|
46
|
+
when :destroy
|
|
47
|
+
self.get_proxy(association).destroy_all
|
|
48
|
+
when :delete_all
|
|
49
|
+
self.get_proxy(association).delete_all
|
|
50
|
+
when :nullify
|
|
51
|
+
self.get_proxy(association).nullify
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def autosave?
|
|
58
|
+
options.fetch(:autosave, true)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|