mongo_mapper-rails3 0.7.0.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/README.rdoc +8 -37
  2. metadata +16 -284
  3. data/.gitignore +0 -10
  4. data/Gemfile +0 -15
  5. data/LICENSE +0 -20
  6. data/Rakefile +0 -58
  7. data/VERSION +0 -1
  8. data/bin/mmconsole +0 -60
  9. data/lib/mongo_mapper.rb +0 -131
  10. data/lib/mongo_mapper/document.rb +0 -439
  11. data/lib/mongo_mapper/embedded_document.rb +0 -68
  12. data/lib/mongo_mapper/plugins.rb +0 -30
  13. data/lib/mongo_mapper/plugins/associations.rb +0 -106
  14. data/lib/mongo_mapper/plugins/associations/base.rb +0 -123
  15. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +0 -30
  16. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +0 -25
  17. data/lib/mongo_mapper/plugins/associations/collection.rb +0 -21
  18. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +0 -50
  19. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +0 -141
  20. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +0 -28
  21. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +0 -120
  22. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +0 -31
  23. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +0 -23
  24. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +0 -13
  25. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +0 -68
  26. data/lib/mongo_mapper/plugins/associations/proxy.rb +0 -119
  27. data/lib/mongo_mapper/plugins/callbacks.rb +0 -87
  28. data/lib/mongo_mapper/plugins/clone.rb +0 -14
  29. data/lib/mongo_mapper/plugins/descendants.rb +0 -17
  30. data/lib/mongo_mapper/plugins/dirty.rb +0 -120
  31. data/lib/mongo_mapper/plugins/equality.rb +0 -24
  32. data/lib/mongo_mapper/plugins/identity_map.rb +0 -124
  33. data/lib/mongo_mapper/plugins/inspect.rb +0 -15
  34. data/lib/mongo_mapper/plugins/keys.rb +0 -310
  35. data/lib/mongo_mapper/plugins/logger.rb +0 -19
  36. data/lib/mongo_mapper/plugins/pagination.rb +0 -26
  37. data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
  38. data/lib/mongo_mapper/plugins/protected.rb +0 -46
  39. data/lib/mongo_mapper/plugins/rails.rb +0 -46
  40. data/lib/mongo_mapper/plugins/serialization.rb +0 -50
  41. data/lib/mongo_mapper/plugins/validations.rb +0 -88
  42. data/lib/mongo_mapper/query.rb +0 -130
  43. data/lib/mongo_mapper/support.rb +0 -217
  44. data/lib/mongo_mapper/support/descendant_appends.rb +0 -46
  45. data/lib/mongo_mapper/support/find.rb +0 -77
  46. data/mongo_mapper-rails3.gemspec +0 -208
  47. data/performance/read_write.rb +0 -52
  48. data/specs.watchr +0 -51
  49. data/test/NOTE_ON_TESTING +0 -1
  50. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +0 -63
  51. data/test/functional/associations/test_belongs_to_proxy.rb +0 -101
  52. data/test/functional/associations/test_in_array_proxy.rb +0 -321
  53. data/test/functional/associations/test_many_documents_as_proxy.rb +0 -229
  54. data/test/functional/associations/test_many_documents_proxy.rb +0 -453
  55. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +0 -176
  56. data/test/functional/associations/test_many_embedded_proxy.rb +0 -256
  57. data/test/functional/associations/test_many_polymorphic_proxy.rb +0 -302
  58. data/test/functional/associations/test_one_proxy.rb +0 -161
  59. data/test/functional/test_associations.rb +0 -44
  60. data/test/functional/test_binary.rb +0 -27
  61. data/test/functional/test_callbacks.rb +0 -81
  62. data/test/functional/test_dirty.rb +0 -163
  63. data/test/functional/test_document.rb +0 -1244
  64. data/test/functional/test_embedded_document.rb +0 -125
  65. data/test/functional/test_identity_map.rb +0 -508
  66. data/test/functional/test_logger.rb +0 -20
  67. data/test/functional/test_modifiers.rb +0 -252
  68. data/test/functional/test_pagination.rb +0 -93
  69. data/test/functional/test_protected.rb +0 -161
  70. data/test/functional/test_string_id_compatibility.rb +0 -67
  71. data/test/functional/test_validations.rb +0 -329
  72. data/test/models.rb +0 -232
  73. data/test/support/custom_matchers.rb +0 -55
  74. data/test/support/timing.rb +0 -16
  75. data/test/test_helper.rb +0 -59
  76. data/test/unit/associations/test_base.rb +0 -207
  77. data/test/unit/associations/test_proxy.rb +0 -105
  78. data/test/unit/serializers/test_json_serializer.rb +0 -189
  79. data/test/unit/test_descendant_appends.rb +0 -71
  80. data/test/unit/test_document.rb +0 -231
  81. data/test/unit/test_dynamic_finder.rb +0 -123
  82. data/test/unit/test_embedded_document.rb +0 -663
  83. data/test/unit/test_keys.rb +0 -169
  84. data/test/unit/test_lint.rb +0 -8
  85. data/test/unit/test_mongo_mapper.rb +0 -125
  86. data/test/unit/test_pagination.rb +0 -160
  87. data/test/unit/test_plugins.rb +0 -51
  88. data/test/unit/test_query.rb +0 -334
  89. data/test/unit/test_rails.rb +0 -123
  90. data/test/unit/test_rails_compatibility.rb +0 -57
  91. data/test/unit/test_serialization.rb +0 -51
  92. data/test/unit/test_support.rb +0 -362
  93. data/test/unit/test_time_zones.rb +0 -39
  94. data/test/unit/test_validations.rb +0 -557
data/Rakefile DELETED
@@ -1,58 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'jeweler'
4
- require 'yard'
5
- require 'yard/rake/yardoc_task'
6
-
7
- Jeweler::Tasks.new do |gem|
8
- gem.name = "mongo_mapper-rails3"
9
- gem.summary = %Q{Rails3 / ActiveModel compatible fork of MongoMapper.}
10
- gem.email = "merbjedi@gmail.com"
11
- gem.homepage = "http://github.com/merbjedi/mongomapper"
12
- gem.authors = ["Mike Harris", "Paul Bowsher", "Jacques Crocker", "John Nunemaker"]
13
-
14
- gem.add_dependency('activesupport', '>= 3.0.0.beta')
15
- gem.add_dependency('activemodel', '>= 3.0.0.beta')
16
- gem.add_dependency('bundler', '>= 0.9.7')
17
- gem.add_dependency('mongo', '>= 0.18.3')
18
-
19
- gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
20
- gem.add_development_dependency('shoulda', '2.10.2')
21
- gem.add_development_dependency('timecop', '0.3.1')
22
- gem.add_development_dependency('mocha', '0.9.8')
23
- gem.add_development_dependency('yard', '>= 0.5.3')
24
- gem.add_development_dependency('jeweler', '>= 1.4.0')
25
- end
26
-
27
- Jeweler::GemcutterTasks.new
28
-
29
- require 'rake/testtask'
30
- Rake::TestTask.new(:test) do |test|
31
- test.libs << 'test'
32
- test.ruby_opts << '-rubygems'
33
- test.pattern = 'test/**/test_*.rb'
34
- test.verbose = true
35
- end
36
-
37
- namespace :test do
38
- Rake::TestTask.new(:units) do |test|
39
- test.libs << 'test'
40
- test.ruby_opts << '-rubygems'
41
- test.pattern = 'test/unit/**/test_*.rb'
42
- test.verbose = true
43
- end
44
-
45
- Rake::TestTask.new(:functionals) do |test|
46
- test.libs << 'test'
47
- test.ruby_opts << '-rubygems'
48
- test.pattern = 'test/functional/**/test_*.rb'
49
- test.verbose = true
50
- end
51
- end
52
-
53
- task :default => :test
54
- task :test => :check_dependencies
55
-
56
- YARD::Rake::YardocTask.new(:doc) do |t|
57
- t.options = ["--legacy"] if RUBY_VERSION < "1.9.0"
58
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.7.0.1
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $:.unshift(File.dirname(__FILE__) + '/../lib')
3
-
4
- begin
5
- require 'mongo_mapper'
6
- require 'irb'
7
- rescue LoadError
8
- require 'rubygems'
9
- retry
10
- end
11
-
12
- IRB.setup(nil)
13
- irb = IRB::Irb.new
14
-
15
- IRB.conf[:MAIN_CONTEXT] = irb.context
16
-
17
- irb.context.evaluate("require 'irb/completion'", 0)
18
- irb.context.evaluate(%@
19
- include MongoMapper
20
-
21
- MongoMapper.database = "mmtest"
22
- $db = MongoMapper.database
23
-
24
- @, 0)
25
-
26
- puts %@
27
- Welcome to the MongoMapper Console!
28
-
29
- Example 1:
30
- things = $db.collection("things")
31
- things.insert("name" => "Raw Thing")
32
- things.insert("name" => "Another Thing", "date" => Time.now)
33
-
34
- cursor = things.find("name" => "Raw Thing")
35
- puts cursor.next_object.inspect
36
-
37
- Example 2:
38
- class Thing
39
- include MongoMapper::Document
40
- key :name, String, :required => true
41
- key :date, Time
42
- end
43
-
44
- thing = Thing.new
45
- thing.name = "My thing"
46
- thing.date = Time.now
47
- thing.save
48
-
49
- all_things = Thing.all
50
- puts all_things.map { |object| object.name }.inspect
51
- @
52
-
53
- trap("SIGINT") do
54
- irb.signal_handle
55
- end
56
-
57
- catch(:IRB_EXIT) do
58
- irb.eval_input
59
- end
60
-
@@ -1,131 +0,0 @@
1
- require 'set'
2
-
3
- begin
4
- # Require the preresolved locked set of gems.
5
- require File.expand_path('../.bundle/environment', __FILE__)
6
- rescue LoadError
7
- # Fallback on doing the resolve at runtime.
8
- require "rubygems"
9
- require "bundler"
10
- Bundler.setup
11
- end
12
-
13
- require "active_model"
14
- require "active_model/callbacks"
15
- require "active_model/conversion"
16
- require "active_model/deprecated_error_methods"
17
- require "active_model/errors"
18
- require "active_model/naming"
19
- require "active_model/serialization"
20
- require "active_model/translation"
21
- require "active_model/validator"
22
- require "active_model/validations"
23
- require 'active_support/core_ext/hash/indifferent_access'
24
- require 'active_support/core_ext/hash'
25
- require 'active_support/core_ext/object/try'
26
- require 'active_support/core_ext/module'
27
-
28
- require 'mongo'
29
-
30
- module MongoMapper
31
- # generic MM error
32
- class MongoMapperError < StandardError; end
33
-
34
- # raised when key expected to exist but not found
35
- class KeyNotFound < MongoMapperError; end
36
-
37
- # raised when document expected but not found
38
- class DocumentNotFound < MongoMapperError; end
39
-
40
- # raised when document not valid and using !
41
- class DocumentNotValid < MongoMapperError
42
- def initialize(document)
43
- super("Validation failed: #{document.errors.full_messages.join(", ")}")
44
- end
45
- end
46
-
47
- # @api public
48
- def self.connection
49
- @@connection ||= Mongo::Connection.new
50
- end
51
-
52
- # @api public
53
- def self.connection=(new_connection)
54
- @@connection = new_connection
55
- end
56
-
57
- # @api public
58
- def self.logger
59
- connection.logger
60
- end
61
-
62
- # @api public
63
- def self.database=(name)
64
- @@database = nil
65
- @@database_name = name
66
- end
67
-
68
- # @api public
69
- def self.database
70
- if @@database_name.blank?
71
- raise 'You forgot to set the default database name: MongoMapper.database = "foobar"'
72
- end
73
-
74
- @@database ||= MongoMapper.connection.db(@@database_name)
75
- end
76
-
77
- def self.config=(hash)
78
- @@config = hash
79
- end
80
-
81
- def self.config
82
- raise 'Set config before connecting. MongoMapper.config = {...}' unless defined?(@@config)
83
- @@config
84
- end
85
-
86
- def self.connect(environment, options={})
87
- raise 'Set config before connecting. MongoMapper.config = {...}' if config.blank?
88
- MongoMapper.connection = Mongo::Connection.new(config[environment]['host'], config[environment]['port'], options)
89
- MongoMapper.database = config[environment]['database']
90
- if config[environment]['username'].present? && config[environment]['password'].present?
91
- MongoMapper.database.authenticate(config[environment]['username'], config[environment]['password'])
92
- end
93
- end
94
-
95
- def self.setup(config, environment, options={})
96
- using_passenger = options.delete(:passenger)
97
- handle_passenger_forking if using_passenger
98
- self.config = config
99
- connect(environment, options)
100
- end
101
-
102
- def self.handle_passenger_forking
103
- if defined?(PhusionPassenger)
104
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
105
- connection.connect_to_master if forked
106
- end
107
- end
108
- end
109
-
110
- # @api private
111
- def self.use_time_zone?
112
- Time.respond_to?(:zone) && Time.zone ? true : false
113
- end
114
-
115
- # @api private
116
- def self.time_class
117
- use_time_zone? ? Time.zone : Time
118
- end
119
-
120
- # @api private
121
- def self.normalize_object_id(value)
122
- value.is_a?(String) ? Mongo::ObjectID.from_string(value) : value
123
- end
124
-
125
- autoload :Query, 'mongo_mapper/query'
126
- autoload :Document, 'mongo_mapper/document'
127
- autoload :EmbeddedDocument, 'mongo_mapper/embedded_document'
128
- end
129
-
130
- require 'mongo_mapper/support'
131
- require 'mongo_mapper/plugins'
@@ -1,439 +0,0 @@
1
- module MongoMapper
2
- module Document
3
- extend Support::DescendantAppends
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- include InstanceMethods
8
- include ActiveModel::Conversion
9
- extend Support::Find
10
- extend ClassMethods
11
- extend Plugins
12
-
13
- plugin Plugins::Associations
14
- plugin Plugins::Clone
15
- plugin Plugins::Descendants
16
- plugin Plugins::Equality
17
- plugin Plugins::Inspect
18
- plugin Plugins::Keys
19
- plugin Plugins::Dirty # for now dirty needs to be after keys
20
- plugin Plugins::Logger
21
- plugin Plugins::Pagination
22
- plugin Plugins::Protected
23
- plugin Plugins::Rails
24
- plugin Plugins::Serialization
25
- plugin Plugins::Validations
26
- plugin Plugins::Callbacks
27
-
28
- extend Plugins::Validations::DocumentMacros
29
- end
30
-
31
- module ClassMethods
32
- def inherited(subclass)
33
- subclass.set_collection_name(collection_name)
34
- super
35
- end
36
-
37
- def ensure_index(name_or_array, options={})
38
- keys_to_index = if name_or_array.is_a?(Array)
39
- name_or_array.map { |pair| [pair[0], pair[1]] }
40
- else
41
- name_or_array
42
- end
43
-
44
- collection.create_index(keys_to_index, options[:unique])
45
- end
46
-
47
- def find(*args)
48
- assert_no_first_last_or_all(args)
49
- options = args.extract_options!
50
- return nil if args.size == 0
51
-
52
- if args.first.is_a?(Array) || args.size > 1
53
- find_some(args, options)
54
- else
55
- find_one(options.merge({:_id => args[0]}))
56
- end
57
- end
58
-
59
- def find!(*args)
60
- assert_no_first_last_or_all(args)
61
- options = args.extract_options!
62
- raise DocumentNotFound, "Couldn't find without an ID" if args.size == 0
63
-
64
- if args.first.is_a?(Array) || args.size > 1
65
- find_some!(args, options)
66
- else
67
- find_one(options.merge({:_id => args[0]})) || raise(DocumentNotFound, "Document match #{options.inspect} does not exist in #{collection.name} collection")
68
- end
69
- end
70
-
71
- def find_each(options={})
72
- criteria, options = to_query(options)
73
- collection.find(criteria, options).each do |doc|
74
- yield load(doc)
75
- end
76
- end
77
-
78
- def find_by_id(id)
79
- find(id)
80
- end
81
-
82
- def first_or_create(arg)
83
- first(arg) || create(arg)
84
- end
85
-
86
- def first_or_new(arg)
87
- first(arg) || new(arg)
88
- end
89
-
90
- def first(options={})
91
- find_one(options)
92
- end
93
-
94
- def last(options={})
95
- raise ':order option must be provided when using last' if options[:order].blank?
96
- find_one(options.merge(:order => invert_order_clause(options[:order])))
97
- end
98
-
99
- def all(options={})
100
- find_many(options)
101
- end
102
-
103
- def count(options={})
104
- collection.find(to_criteria(options)).count
105
- end
106
-
107
- def exists?(options={})
108
- !count(options).zero?
109
- end
110
-
111
- def create(*docs)
112
- initialize_each(*docs) { |doc| doc.save }
113
- end
114
-
115
- def create!(*docs)
116
- initialize_each(*docs) { |doc| doc.save! }
117
- end
118
-
119
- def update(*args)
120
- if args.length == 1
121
- update_multiple(args[0])
122
- else
123
- id, attributes = args
124
- update_single(id, attributes)
125
- end
126
- end
127
-
128
- def delete(*ids)
129
- collection.remove(to_criteria(:_id => ids.flatten))
130
- end
131
-
132
- def delete_all(options={})
133
- collection.remove(to_criteria(options))
134
- end
135
-
136
- def destroy(*ids)
137
- find_some!(ids.flatten).each(&:destroy)
138
- end
139
-
140
- def destroy_all(options={})
141
- find_each(options) { |document| document.destroy }
142
- end
143
-
144
- def increment(*args)
145
- modifier_update('$inc', args)
146
- end
147
-
148
- def decrement(*args)
149
- criteria, keys = criteria_and_keys_from_args(args)
150
- values, to_decrement = keys.values, {}
151
- keys.keys.each_with_index { |k, i| to_decrement[k] = -values[i].abs }
152
- collection.update(criteria, {'$inc' => to_decrement}, :multi => true)
153
- end
154
-
155
- def set(*args)
156
- modifier_update('$set', args)
157
- end
158
-
159
- def push(*args)
160
- modifier_update('$push', args)
161
- end
162
-
163
- def push_all(*args)
164
- modifier_update('$pushAll', args)
165
- end
166
-
167
- def push_uniq(*args)
168
- criteria, keys = criteria_and_keys_from_args(args)
169
- keys.each { |key, value | criteria[key] = {'$ne' => value} }
170
- collection.update(criteria, {'$push' => keys}, :multi => true)
171
- end
172
-
173
- def pull(*args)
174
- modifier_update('$pull', args)
175
- end
176
-
177
- def pull_all(*args)
178
- modifier_update('$pullAll', args)
179
- end
180
-
181
- def pop(*args)
182
- modifier_update('$pop', args)
183
- end
184
-
185
- def embeddable?
186
- false
187
- end
188
-
189
- def connection(mongo_connection=nil)
190
- if mongo_connection.nil?
191
- @connection ||= MongoMapper.connection
192
- else
193
- @connection = mongo_connection
194
- end
195
- @connection
196
- end
197
-
198
- def set_database_name(name)
199
- @database_name = name
200
- end
201
-
202
- def database_name
203
- @database_name
204
- end
205
-
206
- def database
207
- if database_name.nil?
208
- MongoMapper.database
209
- else
210
- connection.db(database_name)
211
- end
212
- end
213
-
214
- def set_collection_name(name)
215
- @collection_name = name
216
- end
217
-
218
- def collection_name
219
- @collection_name ||= self.to_s.tableize.gsub(/\//, '.')
220
- end
221
-
222
- def collection
223
- database.collection(collection_name)
224
- end
225
-
226
- def timestamps!
227
- key :created_at, Time
228
- key :updated_at, Time
229
- class_eval { before_save :update_timestamps }
230
- end
231
-
232
- def userstamps!
233
- key :creator_id, ObjectId
234
- key :updater_id, ObjectId
235
- belongs_to :creator, :class_name => 'User'
236
- belongs_to :updater, :class_name => 'User'
237
- end
238
-
239
- def single_collection_inherited?
240
- keys.key?(:_type) && single_collection_inherited_superclass?
241
- end
242
-
243
- def single_collection_inherited_superclass?
244
- superclass.respond_to?(:keys) && superclass.keys.key?(:_type)
245
- end
246
-
247
- private
248
- def initialize_each(*docs)
249
- instances = []
250
- docs = [{}] if docs.blank?
251
- docs.flatten.each do |attrs|
252
- doc = new(attrs)
253
- yield(doc)
254
- instances << doc
255
- end
256
- instances.size == 1 ? instances[0] : instances
257
- end
258
-
259
- def modifier_update(modifier, args)
260
- criteria, keys = criteria_and_keys_from_args(args)
261
- modifiers = {modifier => keys}
262
- collection.update(criteria, modifiers, :multi => true)
263
- end
264
-
265
- def criteria_and_keys_from_args(args)
266
- keys = args.pop
267
- criteria = args[0].is_a?(Hash) ? args[0] : {:id => args}
268
- [to_criteria(criteria), keys]
269
- end
270
-
271
- def assert_no_first_last_or_all(args)
272
- if args[0] == :first || args[0] == :last || args[0] == :all
273
- raise ArgumentError, "#{self}.find(:#{args}) is no longer supported, use #{self}.#{args} instead."
274
- end
275
- end
276
-
277
- def find_some(ids, options={})
278
- ids = ids.flatten.compact.uniq
279
- find_many(options.merge(:_id => ids)).compact
280
- end
281
-
282
- def find_some!(ids, options={})
283
- ids = ids.flatten.compact.uniq
284
- documents = find_some(ids, options)
285
-
286
- if ids.size == documents.size
287
- documents
288
- else
289
- raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{documents.size}, but was expecting #{ids.size}"
290
- end
291
- end
292
-
293
- # All query methods that load documents pass through find_one or find_many
294
- def find_one(options={})
295
- criteria, options = to_query(options)
296
- if doc = collection.find_one(criteria, options)
297
- load(doc)
298
- end
299
- end
300
-
301
- # All query methods that load documents pass through find_one or find_many
302
- def find_many(options)
303
- criteria, options = to_query(options)
304
- collection.find(criteria, options).to_a.map do |doc|
305
- load(doc)
306
- end
307
- end
308
-
309
- def invert_order_clause(order)
310
- order.split(',').map do |order_segment|
311
- if order_segment =~ /\sasc/i
312
- order_segment.sub /\sasc/i, ' desc'
313
- elsif order_segment =~ /\sdesc/i
314
- order_segment.sub /\sdesc/i, ' asc'
315
- else
316
- "#{order_segment.strip} desc"
317
- end
318
- end.join(',')
319
- end
320
-
321
- def update_single(id, attrs)
322
- if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
323
- raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
324
- end
325
-
326
- doc = find(id)
327
- doc.update_attributes(attrs)
328
- doc
329
- end
330
-
331
- def update_multiple(docs)
332
- unless docs.is_a?(Hash)
333
- raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
334
- end
335
-
336
- instances = []
337
- docs.each_pair { |id, attrs| instances << update(id, attrs) }
338
- instances
339
- end
340
-
341
- def to_criteria(options={})
342
- Query.new(self, options).criteria
343
- end
344
-
345
- def to_query(options={})
346
- Query.new(self, options).to_a
347
- end
348
- end
349
-
350
- module InstanceMethods
351
- def initialize(attrs={}, from_database=false)
352
- unless attrs.nil?
353
- provided_keys = attrs.keys.map { |k| k.to_s }
354
- unless provided_keys.include?('_id') || provided_keys.include?('id')
355
- write_key :_id, Mongo::ObjectID.new
356
- end
357
- end
358
-
359
- #here for ActiveModel compatibility, should do something real with this
360
- def destroyed?
361
- false
362
- end
363
-
364
- assign_type_if_present
365
-
366
- if from_database
367
- @new = false
368
- self.attributes = attrs
369
- else
370
- @new = true
371
- assign(attrs)
372
- end
373
- end
374
-
375
- def collection
376
- self.class.collection
377
- end
378
-
379
- def database
380
- self.class.database
381
- end
382
-
383
- def save(options={})
384
- options.assert_valid_keys(:validate, :safe)
385
- options.reverse_merge!(:validate => true)
386
- !options[:validate] || valid? ? create_or_update(options) : false
387
- end
388
-
389
- def save!(options={})
390
- options.assert_valid_keys(:safe)
391
- save(options) || raise(DocumentNotValid.new(self))
392
- end
393
-
394
- def destroy
395
- delete
396
- end
397
-
398
- def delete
399
- self.class.delete(id) unless new?
400
- end
401
-
402
- def reload
403
- if attrs = collection.find_one({:_id => _id})
404
- self.class.associations.each { |name, assoc| send(name).reset if respond_to?(name) }
405
- self.attributes = attrs
406
- self
407
- else
408
- raise DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
409
- end
410
- end
411
-
412
- private
413
- def create_or_update(options={})
414
- result = new? ? create(options) : update(options)
415
- result != false
416
- end
417
-
418
- def create(options={})
419
- save_to_collection(options)
420
- end
421
-
422
- def update(options={})
423
- save_to_collection(options)
424
- end
425
-
426
- def save_to_collection(options={})
427
- safe = options[:safe] || false
428
- @new = false
429
- collection.save(to_mongo, :safe => safe)
430
- end
431
-
432
- def update_timestamps
433
- now = Time.now.utc
434
- self[:created_at] = now if new? && !created_at?
435
- self[:updated_at] = now
436
- end
437
- end
438
- end # Document
439
- end # MongoMapper