-
Notifications
You must be signed in to change notification settings - Fork 382
/
many_documents_proxy.rb
127 lines (103 loc) · 2.82 KB
/
many_documents_proxy.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
module MongoMapper
module Associations
class ManyDocumentsProxy < Proxy
delegate :klass, :to => :@association
delegate :collection, :to => :klass
include ::MongoMapper::Finders
def find(*args)
options = args.extract_options!
klass.find(*args << scoped_options(options))
end
def find!(*args)
options = args.extract_options!
klass.find!(*args << scoped_options(options))
end
def paginate(options)
klass.paginate(scoped_options(options))
end
def all(options={})
klass.all(scoped_options(options))
end
def first(options={})
klass.first(scoped_options(options))
end
def last(options={})
klass.last(scoped_options(options))
end
def count(options={})
klass.count(scoped_options(options))
end
def replace(docs)
@target.map(&:destroy) if load_target
docs.each { |doc| apply_scope(doc).save }
reset
end
def <<(*docs)
ensure_owner_saved
flatten_deeper(docs).each { |doc| apply_scope(doc).save }
reset
end
alias_method :push, :<<
alias_method :concat, :<<
def build(attrs={})
doc = klass.new(attrs)
apply_scope(doc)
doc
end
def create(attrs={})
doc = klass.new(attrs)
apply_scope(doc).save
doc
end
def create!(attrs={})
doc = klass.new(attrs)
apply_scope(doc).save!
doc
end
def destroy_all(options={})
all(options).map(&:destroy)
reset
end
def delete_all(options={})
klass.delete_all(options.merge(scoped_conditions))
reset
end
def nullify
criteria = FinderOptions.new(klass, scoped_conditions).criteria
all(criteria).each do |doc|
doc.update_attributes(self.foreign_key => nil)
end
reset
end
def method_missing(method, *args)
finder = DynamicFinder.new(method)
if finder.found?
dynamic_find(finder, args)
else
super
end
end
protected
def scoped_conditions
{self.foreign_key => @owner._id}
end
def scoped_options(options)
@association.finder_options.merge(options).merge(scoped_conditions)
end
def find_target
all
end
def ensure_owner_saved
@owner.save if @owner.new?
end
def apply_scope(doc)
ensure_owner_saved
doc.send("#{self.foreign_key}=", @owner._id)
doc
end
def foreign_key
@association.options[:foreign_key] || @owner.class.name.underscore.gsub("/", "_") + "_id"
end
end
end
end