jnunemaker-mongomapper 0.3.2 → 0.3.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/History +10 -0
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +3 -1
- data/lib/mongomapper/associations/belongs_to_proxy.rb +2 -2
- data/lib/mongomapper/associations/many_documents_proxy.rb +32 -14
- data/lib/mongomapper/associations/proxy.rb +2 -6
- data/lib/mongomapper/associations.rb +44 -9
- data/lib/mongomapper/document.rb +142 -89
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +102 -85
- data/lib/mongomapper/finder_options.rb +3 -14
- data/lib/mongomapper/key.rb +10 -15
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper.rb +4 -31
- data/mongomapper.gemspec +12 -10
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +14 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +10 -0
- data/test/functional/associations/test_many_proxy.rb +63 -4
- data/test/functional/test_document.rb +371 -120
- data/test/functional/test_rails_compatibility.rb +2 -3
- data/test/models.rb +10 -6
- data/test/unit/serializers/test_json_serializer.rb +1 -1
- data/test/unit/test_document.rb +7 -1
- data/test/unit/test_embedded_document.rb +115 -24
- data/test/unit/test_finder_options.rb +7 -38
- data/test/unit/test_key.rb +46 -23
- metadata +7 -7
- data/test/unit/test_mongo_id.rb +0 -35
data/History
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.3.3 8/16/2009
|
2
|
+
* BACKWORDS COMPATIBILITY BREAK: _id is now once again a string rather than an object id and will stay that way.
|
3
|
+
* Custom id's can now be used because of the change to string id's
|
4
|
+
* Added dynamic finders to document. (dcu)
|
5
|
+
* Added destroy_all, delete_all and nullify for many document association
|
6
|
+
* Added :dependent option for many documents assocation (dcu)
|
7
|
+
* update_attributes now returns true or false instead of the document. (Durran Jordan and me)
|
8
|
+
* Keys no longer require a type
|
9
|
+
* Keys can now be added on the fly using []=
|
10
|
+
|
1
11
|
0.3.2 8/6/2009
|
2
12
|
* Added many polymorphic documents association
|
3
13
|
* Implemented build and create for many and many polymorphic documents
|
data/Rakefile
CHANGED
@@ -12,14 +12,16 @@ begin
|
|
12
12
|
gem.rubyforge_project = "mongomapper"
|
13
13
|
|
14
14
|
gem.add_dependency('activesupport')
|
15
|
-
gem.add_dependency('mongodb-mongo', '0.
|
15
|
+
gem.add_dependency('mongodb-mongo', '0.11.1')
|
16
16
|
gem.add_dependency('jnunemaker-validatable', '1.7.2')
|
17
17
|
|
18
18
|
gem.add_development_dependency('mocha', '0.9.4')
|
19
19
|
gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
|
20
20
|
end
|
21
|
-
|
22
|
-
Jeweler::RubyforgeTasks.new
|
21
|
+
|
22
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
23
|
+
rubyforge.doc_task = "rdoc"
|
24
|
+
end
|
23
25
|
rescue LoadError
|
24
26
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
25
27
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
@@ -6,7 +6,7 @@ module MongoMapper
|
|
6
6
|
doc.save if doc.new?
|
7
7
|
id = doc.id
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
@owner.send("#{@association.belongs_to_key_name}=", id)
|
11
11
|
reset
|
12
12
|
end
|
@@ -14,7 +14,7 @@ module MongoMapper
|
|
14
14
|
protected
|
15
15
|
def find_target
|
16
16
|
if association_id = @owner.send(@association.belongs_to_key_name)
|
17
|
-
@association.klass.
|
17
|
+
@association.klass.find_by_id(association_id)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -2,38 +2,38 @@ module MongoMapper
|
|
2
2
|
module Associations
|
3
3
|
class ManyDocumentsProxy < Proxy
|
4
4
|
delegate :klass, :to => :@association
|
5
|
-
|
5
|
+
|
6
6
|
def find(*args)
|
7
7
|
options = args.extract_options!
|
8
8
|
klass.find(*args << scoped_options(options))
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def paginate(options)
|
12
12
|
klass.paginate(scoped_options(options))
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def all(options={})
|
16
16
|
find(:all, scoped_options(options))
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def first(options={})
|
20
20
|
find(:first, scoped_options(options))
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def last(options={})
|
24
24
|
find(:last, scoped_options(options))
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def count(conditions={})
|
28
28
|
klass.count(conditions.deep_merge(scoped_conditions))
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def replace(docs)
|
32
32
|
@target.map(&:destroy) if load_target
|
33
33
|
docs.each { |doc| apply_scope(doc).save }
|
34
34
|
reset
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def <<(*docs)
|
38
38
|
ensure_owner_saved
|
39
39
|
flatten_deeper(docs).each { |doc| apply_scope(doc).save }
|
@@ -41,36 +41,54 @@ module MongoMapper
|
|
41
41
|
end
|
42
42
|
alias_method :push, :<<
|
43
43
|
alias_method :concat, :<<
|
44
|
-
|
44
|
+
|
45
45
|
def build(attrs={})
|
46
46
|
doc = klass.new(attrs)
|
47
47
|
apply_scope(doc)
|
48
48
|
doc
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def create(attrs={})
|
52
52
|
doc = klass.new(attrs)
|
53
53
|
apply_scope(doc).save
|
54
54
|
doc
|
55
55
|
end
|
56
|
+
|
57
|
+
def destroy_all(conditions={})
|
58
|
+
all(:conditions => conditions).map(&:destroy)
|
59
|
+
reset
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete_all(conditions={})
|
63
|
+
klass.delete_all(conditions.deep_merge(scoped_conditions))
|
64
|
+
reset
|
65
|
+
end
|
56
66
|
|
67
|
+
def nullify
|
68
|
+
criteria = FinderOptions.to_mongo_criteria(scoped_conditions)
|
69
|
+
all(criteria).each do |doc|
|
70
|
+
doc.update_attributes self.foreign_key => nil
|
71
|
+
end
|
72
|
+
reset
|
73
|
+
end
|
74
|
+
|
57
75
|
protected
|
58
76
|
def scoped_conditions
|
59
77
|
{self.foreign_key => @owner.id}
|
60
78
|
end
|
61
|
-
|
79
|
+
|
62
80
|
def scoped_options(options)
|
63
81
|
options.deep_merge({:conditions => scoped_conditions})
|
64
82
|
end
|
65
|
-
|
83
|
+
|
66
84
|
def find_target
|
67
85
|
find(:all)
|
68
86
|
end
|
69
|
-
|
87
|
+
|
70
88
|
def ensure_owner_saved
|
71
89
|
@owner.save if @owner.new?
|
72
90
|
end
|
73
|
-
|
91
|
+
|
74
92
|
def apply_scope(doc)
|
75
93
|
ensure_owner_saved
|
76
94
|
doc.send("#{self.foreign_key}=", @owner.id)
|
@@ -1,12 +1,8 @@
|
|
1
1
|
module MongoMapper
|
2
2
|
module Associations
|
3
|
-
class Proxy
|
3
|
+
class Proxy < BasicObject
|
4
4
|
attr_reader :owner, :association
|
5
|
-
|
6
|
-
instance_methods.each do |m|
|
7
|
-
undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/
|
8
|
-
end
|
9
|
-
|
5
|
+
|
10
6
|
def initialize(owner, association)
|
11
7
|
@owner = owner
|
12
8
|
@association = association
|
@@ -2,12 +2,12 @@ module MongoMapper
|
|
2
2
|
module Associations
|
3
3
|
module ClassMethods
|
4
4
|
def belongs_to(association_id, options = {})
|
5
|
-
create_association(:belongs_to, association_id, options)
|
5
|
+
create_association(:belongs_to, association_id, options)
|
6
6
|
self
|
7
7
|
end
|
8
8
|
|
9
9
|
def many(association_id, options = {})
|
10
|
-
create_association(:many, association_id, options)
|
10
|
+
create_association(:many, association_id, options)
|
11
11
|
self
|
12
12
|
end
|
13
13
|
|
@@ -21,39 +21,74 @@ module MongoMapper
|
|
21
21
|
associations[association.name] = association
|
22
22
|
define_association_methods(association)
|
23
23
|
define_association_keys(association)
|
24
|
+
define_dependent_callback(association)
|
24
25
|
association
|
25
26
|
end
|
26
|
-
|
27
|
+
|
27
28
|
def define_association_methods(association)
|
28
29
|
define_method(association.name) do
|
29
30
|
get_proxy(association)
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
define_method("#{association.name}=") do |value|
|
33
34
|
get_proxy(association).replace(value)
|
34
35
|
value
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
+
|
38
39
|
def define_association_keys(association)
|
39
40
|
if association.belongs_to?
|
40
41
|
key(association.belongs_to_key_name, String)
|
41
|
-
key(association.type_key_name, String) if association.polymorphic?
|
42
|
+
key(association.type_key_name, String) if association.polymorphic?
|
42
43
|
end
|
43
|
-
|
44
|
+
|
44
45
|
if association.many? && association.polymorphic?
|
45
46
|
association.klass.send(:key, association.type_key_name, String)
|
46
47
|
end
|
47
48
|
end
|
49
|
+
|
50
|
+
def define_dependent_callback(association)
|
51
|
+
if association.options[:dependent]
|
52
|
+
if association.many?
|
53
|
+
define_dependent_callback_for_many(association)
|
54
|
+
elsif association.belongs_to?
|
55
|
+
define_dependent_callback_for_belongs_to(association)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def define_dependent_callback_for_many(association)
|
61
|
+
return if association.embeddable?
|
62
|
+
|
63
|
+
after_destroy do |doc|
|
64
|
+
case association.options[:dependent]
|
65
|
+
when :destroy
|
66
|
+
doc.get_proxy(association).destroy_all
|
67
|
+
when :delete_all
|
68
|
+
doc.get_proxy(association).delete_all
|
69
|
+
when :nullify
|
70
|
+
doc.get_proxy(association).nullify
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def define_dependent_callback_for_belongs_to(association)
|
76
|
+
after_destroy do |doc|
|
77
|
+
case association.options[:dependent]
|
78
|
+
when :destroy
|
79
|
+
doc.get_proxy(association).destroy
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
48
83
|
end
|
49
84
|
|
50
85
|
module InstanceMethods
|
51
86
|
def get_proxy(association)
|
52
87
|
unless proxy = self.instance_variable_get(association.ivar)
|
53
88
|
proxy = association.proxy_class.new(self, association)
|
54
|
-
self.instance_variable_set(association.ivar, proxy)
|
89
|
+
self.instance_variable_set(association.ivar, proxy) if !frozen?
|
55
90
|
end
|
56
|
-
|
91
|
+
|
57
92
|
proxy
|
58
93
|
end
|
59
94
|
end
|
data/lib/mongomapper/document.rb
CHANGED
@@ -11,18 +11,18 @@ module MongoMapper
|
|
11
11
|
include SaveWithValidation
|
12
12
|
include RailsCompatibility::Document
|
13
13
|
extend ClassMethods
|
14
|
-
|
14
|
+
|
15
15
|
key :created_at, Time
|
16
16
|
key :updated_at, Time
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
descendants << model
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.descendants
|
23
23
|
@descendants ||= Set.new
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
module ClassMethods
|
27
27
|
def find(*args)
|
28
28
|
options = args.extract_options!
|
@@ -35,16 +35,15 @@ module MongoMapper
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def paginate(options)
|
38
|
+
def paginate(options)
|
39
39
|
per_page = options.delete(:per_page)
|
40
40
|
page = options.delete(:page)
|
41
41
|
total_entries = count(options[:conditions] || {})
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
options[:limit] = collection.limit
|
42
|
+
collection = Pagination::PaginationProxy.new(total_entries, page, per_page)
|
43
|
+
|
44
|
+
options[:limit] = collection.limit
|
46
45
|
options[:offset] = collection.offset
|
47
|
-
|
46
|
+
|
48
47
|
collection.subject = find_every(options)
|
49
48
|
collection
|
50
49
|
end
|
@@ -67,11 +66,11 @@ module MongoMapper
|
|
67
66
|
new(doc)
|
68
67
|
end
|
69
68
|
end
|
70
|
-
|
69
|
+
|
71
70
|
def count(conditions={})
|
72
71
|
collection.count(FinderOptions.to_mongo_criteria(conditions))
|
73
72
|
end
|
74
|
-
|
73
|
+
|
75
74
|
def create(*docs)
|
76
75
|
instances = []
|
77
76
|
docs = [{}] if docs.blank?
|
@@ -81,7 +80,7 @@ module MongoMapper
|
|
81
80
|
end
|
82
81
|
instances.size == 1 ? instances[0] : instances
|
83
82
|
end
|
84
|
-
|
83
|
+
|
85
84
|
# For updating single document
|
86
85
|
# Person.update(1, {:foo => 'bar'})
|
87
86
|
#
|
@@ -96,25 +95,25 @@ module MongoMapper
|
|
96
95
|
update_single(id, attributes)
|
97
96
|
end
|
98
97
|
end
|
99
|
-
|
98
|
+
|
100
99
|
def delete(*ids)
|
101
100
|
criteria = FinderOptions.to_mongo_criteria(:_id => ids.flatten)
|
102
101
|
collection.remove(criteria)
|
103
102
|
end
|
104
|
-
|
103
|
+
|
105
104
|
def delete_all(conditions={})
|
106
105
|
criteria = FinderOptions.to_mongo_criteria(conditions)
|
107
106
|
collection.remove(criteria)
|
108
107
|
end
|
109
|
-
|
108
|
+
|
110
109
|
def destroy(*ids)
|
111
110
|
find_some(ids.flatten).each(&:destroy)
|
112
111
|
end
|
113
|
-
|
112
|
+
|
114
113
|
def destroy_all(conditions={})
|
115
114
|
find(:all, :conditions => conditions).each(&:destroy)
|
116
115
|
end
|
117
|
-
|
116
|
+
|
118
117
|
def connection(mongo_connection=nil)
|
119
118
|
if mongo_connection.nil?
|
120
119
|
@connection ||= MongoMapper.connection
|
@@ -123,7 +122,7 @@ module MongoMapper
|
|
123
122
|
end
|
124
123
|
@connection
|
125
124
|
end
|
126
|
-
|
125
|
+
|
127
126
|
def database(name=nil)
|
128
127
|
if name.nil?
|
129
128
|
@database ||= MongoMapper.database
|
@@ -132,7 +131,7 @@ module MongoMapper
|
|
132
131
|
end
|
133
132
|
@database
|
134
133
|
end
|
135
|
-
|
134
|
+
|
136
135
|
def collection(name=nil)
|
137
136
|
if name.nil?
|
138
137
|
@collection ||= database.collection(self.to_s.demodulize.tableize)
|
@@ -141,96 +140,137 @@ module MongoMapper
|
|
141
140
|
end
|
142
141
|
@collection
|
143
142
|
end
|
144
|
-
|
143
|
+
|
145
144
|
def validates_uniqueness_of(*args)
|
146
145
|
add_validations(args, MongoMapper::Validations::ValidatesUniquenessOf)
|
147
146
|
end
|
148
|
-
|
147
|
+
|
149
148
|
def validates_exclusion_of(*args)
|
150
149
|
add_validations(args, MongoMapper::Validations::ValidatesExclusionOf)
|
151
150
|
end
|
152
|
-
|
151
|
+
|
153
152
|
def validates_inclusion_of(*args)
|
154
153
|
add_validations(args, MongoMapper::Validations::ValidatesInclusionOf)
|
155
154
|
end
|
156
155
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
def find_some(ids, options={})
|
173
|
-
documents = find_every(options.deep_merge(:conditions => {'_id' => ids}))
|
174
|
-
if ids.size == documents.size
|
175
|
-
documents
|
176
|
-
else
|
177
|
-
raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{documents.size}, but was expecting #{ids.size}"
|
156
|
+
protected
|
157
|
+
def method_missing(method, *args)
|
158
|
+
finder = DynamicFinder.new(self, method)
|
159
|
+
|
160
|
+
if finder.valid?
|
161
|
+
meta_def(finder.options[:method]) do |*args|
|
162
|
+
find_with_args(args, finder.options)
|
163
|
+
end
|
164
|
+
|
165
|
+
send(finder.options[:method], *args)
|
166
|
+
else
|
167
|
+
super
|
168
|
+
end
|
178
169
|
end
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
doc
|
184
|
-
else
|
185
|
-
raise DocumentNotFound, "Document with id of #{id} does not exist in collection named #{collection.name}"
|
170
|
+
|
171
|
+
private
|
172
|
+
def find_every(options)
|
173
|
+
criteria, options = FinderOptions.new(options).to_a
|
174
|
+
collection.find(criteria, options).to_a.map { |doc| new(doc) }
|
186
175
|
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
176
|
+
|
177
|
+
def find_first(options)
|
178
|
+
options.merge!(:limit => 1)
|
179
|
+
find_every({:order => '$natural asc'}.merge(options))[0]
|
180
|
+
end
|
181
|
+
|
182
|
+
def find_last(options)
|
183
|
+
options.merge!(:limit => 1)
|
184
|
+
find_every({:order => '$natural desc'}.merge(options))[0]
|
185
|
+
end
|
186
|
+
|
187
|
+
def find_some(ids, options={})
|
188
|
+
documents = find_every(options.deep_merge(:conditions => {'_id' => ids}))
|
189
|
+
if ids.size == documents.size
|
190
|
+
documents
|
197
191
|
else
|
198
|
-
|
192
|
+
raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{documents.size}, but was expecting #{ids.size}"
|
193
|
+
end
|
199
194
|
end
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
195
|
+
|
196
|
+
def find_one(id, options={})
|
197
|
+
if doc = find_every(options.deep_merge(:conditions => {:_id => id})).first
|
198
|
+
doc
|
199
|
+
else
|
200
|
+
raise DocumentNotFound, "Document with id of #{id} does not exist in collection named #{collection.name}"
|
201
|
+
end
|
205
202
|
end
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
203
|
+
|
204
|
+
def find_from_ids(ids, options={})
|
205
|
+
ids = ids.flatten.compact.uniq
|
206
|
+
|
207
|
+
case ids.size
|
208
|
+
when 0
|
209
|
+
raise(DocumentNotFound, "Couldn't find without an ID")
|
210
|
+
when 1
|
211
|
+
find_one(ids[0], options)
|
212
|
+
else
|
213
|
+
find_some(ids, options)
|
214
|
+
end
|
213
215
|
end
|
214
216
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
217
|
+
def find_with_args(args, options)
|
218
|
+
attributes, = {}
|
219
|
+
find_options = args.extract_options!.deep_merge(:conditions => attributes)
|
220
|
+
|
221
|
+
options[:attribute_names].each_with_index do |attr, index|
|
222
|
+
attributes[attr] = args[index]
|
223
|
+
end
|
224
|
+
|
225
|
+
result = find(options[:finder], find_options)
|
226
|
+
|
227
|
+
if result.nil?
|
228
|
+
if options[:bang]
|
229
|
+
raise DocumentNotFound, "Couldn't find Document with #{attributes.inspect} in collection named #{collection.name}"
|
230
|
+
end
|
231
|
+
|
232
|
+
if options[:instantiator]
|
233
|
+
self.send(options[:instantiator], attributes)
|
234
|
+
end
|
235
|
+
else
|
236
|
+
result
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def update_single(id, attrs)
|
241
|
+
if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
|
242
|
+
raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
|
243
|
+
end
|
244
|
+
|
245
|
+
doc = find(id)
|
246
|
+
doc.update_attributes(attrs)
|
247
|
+
doc
|
248
|
+
end
|
249
|
+
|
250
|
+
def update_multiple(docs)
|
251
|
+
unless docs.is_a?(Hash)
|
252
|
+
raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
|
253
|
+
end
|
254
|
+
|
255
|
+
instances = []
|
256
|
+
docs.each_pair { |id, attrs| instances << update(id, attrs) }
|
257
|
+
instances
|
258
|
+
end
|
219
259
|
end
|
220
|
-
|
260
|
+
|
221
261
|
module InstanceMethods
|
222
262
|
def collection
|
223
263
|
self.class.collection
|
224
264
|
end
|
225
|
-
|
265
|
+
|
226
266
|
def new?
|
227
|
-
read_attribute('_id').blank?
|
267
|
+
read_attribute('_id').blank? || using_custom_id?
|
228
268
|
end
|
229
|
-
|
269
|
+
|
230
270
|
def save
|
231
271
|
create_or_update
|
232
272
|
end
|
233
|
-
|
273
|
+
|
234
274
|
def save!
|
235
275
|
create_or_update || raise(DocumentNotValid.new(self))
|
236
276
|
end
|
@@ -238,41 +278,54 @@ module MongoMapper
|
|
238
278
|
def update_attributes(attrs={})
|
239
279
|
self.attributes = attrs
|
240
280
|
save
|
241
|
-
self
|
242
281
|
end
|
243
|
-
|
282
|
+
|
244
283
|
def destroy
|
284
|
+
return false if frozen?
|
285
|
+
|
245
286
|
criteria = FinderOptions.to_mongo_criteria(:_id => id)
|
246
287
|
collection.remove(criteria) unless new?
|
247
288
|
freeze
|
248
289
|
end
|
249
|
-
|
290
|
+
|
250
291
|
private
|
251
292
|
def create_or_update
|
252
293
|
result = new? ? create : update
|
253
294
|
result != false
|
254
295
|
end
|
255
|
-
|
296
|
+
|
256
297
|
def create
|
257
298
|
update_timestamps
|
258
|
-
|
299
|
+
assign_id
|
300
|
+
save_to_collection
|
259
301
|
end
|
260
302
|
|
303
|
+
def assign_id
|
304
|
+
if read_attribute(:_id).blank?
|
305
|
+
write_attribute(:_id, XGen::Mongo::Driver::ObjectID.new.to_s)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
261
309
|
def update
|
262
310
|
update_timestamps
|
263
311
|
save_to_collection
|
264
312
|
end
|
265
|
-
|
313
|
+
|
266
314
|
# collection.save returns mongoid
|
267
315
|
def save_to_collection
|
316
|
+
clear_custom_id_flag
|
268
317
|
collection.save(attributes)
|
269
318
|
end
|
270
|
-
|
319
|
+
|
271
320
|
def update_timestamps
|
272
321
|
now = Time.now.utc
|
273
322
|
write_attribute('created_at', now) if new?
|
274
323
|
write_attribute('updated_at', now)
|
275
324
|
end
|
325
|
+
|
326
|
+
def clear_custom_id_flag
|
327
|
+
@using_custom_id = nil
|
328
|
+
end
|
276
329
|
end
|
277
330
|
end # Document
|
278
331
|
end # MongoMapper
|