Class: Kongo::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/kongo.rb

Overview

Kongo::Model is the most important class of Kongo, it wraps around hashes representing Mongo records, provides a collection of useful methods, and allows itself to be extended by third party libraries.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash, coll) ⇒ Model

Typically, you would not call Model#new directly, but rather get a model from a method on Collections, such as a finder or #insert.



210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/kongo.rb', line 210

def initialize(hash, coll)
  @coll = coll
  @hash = hash
  @deltas = {}
  @visible_ivars = [:@hash, :@deltas]
  @@extensions ||= {}

  if @@extensions[coll.name.to_sym]
    @@extensions[coll.name.to_sym].each do |const|
      extend(const)
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(key, *args, &block) ⇒ Object

This method_missing provides accessors for keys as proprieties of the model object, so you may do:

object.key = :value
object.key #=> :value


295
296
297
298
299
300
301
302
303
304
# File 'lib/kongo.rb', line 295

def method_missing(key, *args, &block)
  key = key.to_s
  if matches = /^(.+)=$/.match(key)
    raise ArgumentError.new 'Unexpected argument count.' if args.count != 1
    self[matches[1]] = args.first
  else
    raise ArgumentError.new 'Unexpected argument count.' if args.count != 0
    return self[key]
  end
end

Instance Attribute Details

#deltasObject (readonly)

Returns the value of attribute deltas.



225
226
227
# File 'lib/kongo.rb', line 225

def deltas
  @deltas
end

#hashObject (readonly)

Returns the value of attribute hash.



224
225
226
# File 'lib/kongo.rb', line 224

def hash
  @hash
end

Class Method Details

.add_extension(collection_name, mod) ⇒ Object

Declare extensions using this method:

Kongo::Model.add_extension(:collection_name, module)


369
370
371
# File 'lib/kongo.rb', line 369

def self.add_extension(collection_name, mod)
  ((@@extensions ||= {})[collection_name.to_sym] ||= []) << mod
end

Instance Method Details

#<=>(other) ⇒ Integer

Default comparison is via the string version of the id.

Examples:

Compare two models.

person <=> other_person

Parameters:

Returns:

  • (Integer)

    -1, 0, 1.



249
250
251
# File 'lib/kongo.rb', line 249

def <=>(other)
  self['_id'].to_s <=> other['_id'].to_s
end

#==(other) ⇒ true, false

Performs equality checking on the document ids.

Examples:

Compare for equality.

model == other

Parameters:

  • other (Kongo::Model, Object)

    The other object to compare with.

Returns:

  • (true, false)

    True if the ids are equal, false if not.



262
263
264
265
# File 'lib/kongo.rb', line 262

def ==(other)
  self.class == other.class &&
    self['_id'] == other['_id']
end

#[](k) ⇒ Object

Record fields can be accessed using [] syntax.



229
# File 'lib/kongo.rb', line 229

def [](k); @hash[k]; end

#[]=(k, v) ⇒ Object

This adds to the list of deltas, so that we may update with no arguments below



234
235
236
237
238
# File 'lib/kongo.rb', line 234

def []=(k,v)
  @hash[k.to_s]=v

  delta('$set', k => v)
end

#delete!Object

Deletes this record from the database.



337
338
339
340
341
# File 'lib/kongo.rb', line 337

def delete!
  id = @hash['_id']
  raise unless id # TODO: custom exception
  @coll.remove({_id: id})
end

#delta(type, fields = {}) ⇒ Object

Add a delta

delta '$inc',
  total: 3,
  unique: 1


273
274
275
276
277
278
279
# File 'lib/kongo.rb', line 273

def delta(type, fields = {})
  fields.each do |k,v|
    @deltas[type.to_s] ||= {}
    @deltas[type.to_s][k.to_s] = v
  end
  self
end

#extend(const) ⇒ Object

This method just adds the extension to the list of extension, for the sake of inspect, and call super:



376
377
378
379
# File 'lib/kongo.rb', line 376

def extend(const)
  (@extensions ||= []) << const.to_s
  super
end

#inspectObject

Inspecting a Mongo Model attempts to only show useful information, such as what its extensions are as well as certain ivars.



352
353
354
355
356
357
358
359
360
361
# File 'lib/kongo.rb', line 352

def inspect
  proxy = Object.new
  @visible_ivars.each do |ivar|
    val = instance_variable_get(ivar)
    proxy.instance_variable_set(ivar, val) unless val.nil?
  end
  string = proxy.inspect
  ext_info = @extensions ? '(+ '+@extensions.join(', ')+')' : ''
  string.gsub(/Object:0x[0-9a-f]+/, "Kongo::Model#{ext_info}:0x#{object_id}")
end

#save!(options = {}) ⇒ Object

Deprecated.

Do not use saves, they’re dirty.



309
310
311
312
313
# File 'lib/kongo.rb', line 309

def save!(options = {})
  warn("#{Kernel.caller.first}: `save` is deprecated, use `update` instead.")
  raise if @stale unless options[:ignore_stale] # TODO: custom exception
  @coll.save(@hash, :w => 1)
end

#to_hashObject

Returns the hash of the record itself.



345
346
347
# File 'lib/kongo.rb', line 345

def to_hash
  @hash
end

#unset(key) ⇒ Object

‘unset` lets you remove a key from the hash, as well as adding it to the deltas so that the next update will unset that key in Mongo.



284
285
286
287
# File 'lib/kongo.rb', line 284

def unset(key)
  @hash.delete(key.to_s)
  delta('$unset', key => 1)
end

#update!(deltas = {}) ⇒ Object

Issues an update on the database, for this record, with the provided deltas. WARNING: the record will become stale, and should no longer be saved after an update has been issued.



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/kongo.rb', line 319

def update!(deltas = {})
  return if @deltas.empty? && deltas.empty?

  id = @hash['_id']
  raise unless id # TODO: custom exception

  if @deltas
    deltas = @deltas.merge(deltas)
    @deltas = {}
  end

  @stale = true

  @coll.update({_id: id}, deltas, :w => 1)
end