class Mongomatic::Base

Attributes

errors[RW]
is_new[RW]
removed[RW]

Public Class Methods

all() click to toggle source

Return a Mongomatic::Cursor instance of all documents in the collection.

# File lib/mongomatic/base.rb, line 44
def all
  find
end
collection() click to toggle source

Return the raw MongoDB collection for this model

# File lib/mongomatic/base.rb, line 28
def collection
  @collection ||= self.db.collection(self.collection_name)
end
collection_name() click to toggle source

Override this method on your model if you want to use a different collection name

# File lib/mongomatic/base.rb, line 23
def collection_name
  self.to_s.tableize
end
count() click to toggle source

Return the number of documents in the collection

# File lib/mongomatic/base.rb, line 64
def count
  find.count
end
db() click to toggle source

Returns this models own db attribute if set, otherwise will return Mongomatic.db

# File lib/mongomatic/base.rb, line 10
def db
  @db || Mongomatic.db || raise(ArgumentError, "No db supplied")
end
db=(obj) click to toggle source

Override Mongomatic.db with a Mongo::DB instance for this model specifically

MyModel.db = Mongo::Connection.new().db('mydb_mymodel')
# File lib/mongomatic/base.rb, line 16
def db=(obj)
  unless obj.is_a?(Mongo::DB)
    raise(ArgumentError, "Must supply a Mongo::DB object")
  end; @db = obj
end
do_callback(meth) click to toggle source
# File lib/mongomatic/base.rb, line 74
def do_callback(meth)
  return false unless respond_to?(meth, true)
  send(meth)
end
drop() click to toggle source
# File lib/mongomatic/base.rb, line 68
def drop
  do_callback(:before_drop)
  collection.drop
  do_callback(:after_drop)
end
each() { |found| ... } click to toggle source

Iterate over all documents in the collection (uses a Mongomatic::Cursor)

# File lib/mongomatic/base.rb, line 49
def each
  find.each { |found| yield(found) }
end
empty?() click to toggle source

Is the collection empty? This method is much more efficient than doing Collection.count == 0

# File lib/mongomatic/base.rb, line 59
def empty?
  find.limit(1).has_next? == false
end
find(query={}, opts={}) click to toggle source

Query MongoDB for documents. Same arguments as api.mongodb.org/ruby/current/Mongo/Collection.html#find-instance_method

# File lib/mongomatic/base.rb, line 33
def find(query={}, opts={})
  Mongomatic::Cursor.new(self, collection.find(query, opts))
end
find_one(query={}, opts={}) click to toggle source

Query MongoDB and return one document only. Same arguments as api.mongodb.org/ruby/current/Mongo/Collection.html#find_one-instance_method

# File lib/mongomatic/base.rb, line 38
def find_one(query={}, opts={})
  return nil unless doc = self.collection.find_one(query, opts)
  self.new(doc, false)
end
first() click to toggle source

Return the first document in the collection

# File lib/mongomatic/base.rb, line 54
def first
  find.limit(1).next_document
end
insert(doc_hash, opts={}) click to toggle source
# File lib/mongomatic/base.rb, line 79
def insert(doc_hash, opts={})
  d = new(doc_hash)
  d.insert(opts)
end
insert!(doc_hash, opts={}) click to toggle source
# File lib/mongomatic/base.rb, line 84
def insert!(doc_hash, opts={})
  insert(doc_hash, opts.merge(:safe => true))
end
new(doc_hash=Mongomatic::MHash.new, is_new=true) click to toggle source
# File lib/mongomatic/base.rb, line 91
def initialize(doc_hash=Mongomatic::MHash.new, is_new=true)
  self.doc = doc_hash
  self.removed = false
  self.is_new  = is_new
  self.errors  = Mongomatic::Errors.new
  do_callback(:after_initialize)
end

Public Instance Methods

==(obj) click to toggle source

Check equality with another Mongomatic document

# File lib/mongomatic/base.rb, line 188
def ==(obj)
  obj.is_a?(self.class) && obj.doc["_id"] == @doc["_id"]
end
[](k) click to toggle source

Fetch a field (just like a hash):

mydoc["name"]
 => "Ben"
# File lib/mongomatic/base.rb, line 172
def [](k)
  @doc[k.to_s]
end
[]=(k,v) click to toggle source

Set a field on this document:

mydoc["name"] = "Ben"
mydoc["address"] = { "city" => "San Francisco" }
# File lib/mongomatic/base.rb, line 138
def []=(k,v)
  @doc[k.to_s] = v
end
delete(key) click to toggle source

Same as Hash#delete

mydoc.delete(“name”)

=> "Ben"

mydoc.has_hey?(“name”)

=> false
# File lib/mongomatic/base.rb, line 165
def delete(key)
  @doc.delete(key)
end
do_callback(meth) click to toggle source
# File lib/mongomatic/base.rb, line 315
def do_callback(meth)
  notify(meth) if self.class.included_modules.include?(Mongomatic::Observable) # TODO entire block is smelly, doesnt belong here
  
  return false unless respond_to?(meth, true)
  send(meth)
end
doc() click to toggle source
# File lib/mongomatic/base.rb, line 104
def doc
  @doc
end
doc=(hash) click to toggle source
# File lib/mongomatic/base.rb, line 99
def doc=(hash)
  hash = Mongomatic::MHash.new(hash) unless hash.is_a?(Mongomatic::MHash)
  @doc = hash
end
has_key?(key) click to toggle source

Returns true if document contains key

# File lib/mongomatic/base.rb, line 143
def has_key?(key)
  field, hash = hash_for_field(key.to_s, true)
  hash.has_key?(field)
end
hash_for_field(field, break_if_dne=false) click to toggle source
# File lib/mongomatic/base.rb, line 302
def hash_for_field(field, break_if_dne=false)
  parts = field.split(".")
  curr_hash = self.doc
  return [parts[0], curr_hash] if parts.size == 1
  field = parts.pop # last one is the field
  parts.each_with_index do |part, i|
    return [part, curr_hash] if break_if_dne && !curr_hash.has_key?(part)
    curr_hash[part] ||= {}
    return [field, curr_hash[part]] if parts.size == i+1
    curr_hash = curr_hash[part]
  end
end
insert(opts={}) click to toggle source

Insert the document into the database. Will return false if the document has already been inserted or is invalid. Returns the generated BSON::ObjectId for the new document. Will silently fail if MongoDB is unable to insert the document, use insert! or send in {:safe => true} if you want a Mongo::OperationError. If you want to raise the following errors also, pass in {:raise => true}

* Raises Mongomatic::Exceptions::DocumentNotNew if document is not new
* Raises Mongomatic::Exceptions::DocumentNotValid if there are validation errors
# File lib/mongomatic/base.rb, line 206
def insert(opts={})
  if opts[:raise] == true
    raise Mongomatic::Exceptions::DocumentWasRemoved if removed?
    raise Mongomatic::Exceptions::DocumentNotNew unless new?
    raise Mongomatic::Exceptions::DocumentNotValid unless valid?
  else
    return false unless new? && valid?
  end

  do_callback(:before_insert)
  do_callback(:before_insert_or_update)
  if ret = self.class.collection.insert(@doc,opts)
    @doc["_id"] = @doc.delete(:_id) if @doc[:_id]
    self.is_new = false
  end
  do_callback(:after_insert)
  do_callback(:after_insert_or_update)
  ret
end
insert!(opts={}) click to toggle source

Calls insert(…) with {:safe => true} passed in as an option.

* Raises Mongo::OperationError if there was a DB error on inserting

If you want to raise the following errors also, pass in {:raise => true}

* Raises Mongomatic::Exceptions::DocumentNotNew if document is not new
* Raises Mongomatic::Exceptions::DocumentNotValid if there are validation errors
# File lib/mongomatic/base.rb, line 231
def insert!(opts={})
  insert(opts.merge(:safe => true))
end
is_new?() click to toggle source
# File lib/mongomatic/base.rb, line 127
def is_new?
  self.is_new == true
end
merge(hash) click to toggle source

Merge this document with the supplied hash. Useful for updates:

mydoc.merge(params[:user])
# File lib/mongomatic/base.rb, line 178
def merge(hash)
  hash.each { |k,v| self[k] = v }; @doc
end
new?() click to toggle source
# File lib/mongomatic/base.rb, line 131
def new?
  self.is_new == true
end
reload() click to toggle source

Reload the document from the database

# File lib/mongomatic/base.rb, line 193
def reload
  if obj = self.class.find({"_id" => @doc["_id"]}).next_document
    self.doc = obj.doc; true
  end
end
remove(opts={}) click to toggle source

Remove this document from the collection. Silently fails on db error, use remove! or pass in {:safe => true} if you want an exception raised. If you want to raise the following errors also, pass in {:raise => true}

* Raises Mongomatic::Exceptions::DocumentIsNew if document is new
* Raises Mongomatic::Exceptions::DocumentWasRemoved if document has been already removed
# File lib/mongomatic/base.rb, line 273
def remove(opts={})
  if opts[:raise] == true
    raise Mongomatic::Exceptions::DocumentWasRemoved if removed?
    raise Mongomatic::Exceptions::DocumentIsNew      if new?
  else
    return false if new? || removed?
  end
  do_callback(:before_remove)
  if ret = self.class.collection.remove({"_id" => @doc["_id"]})
    self.removed = true; freeze; ret
  end
  do_callback(:after_remove)
  ret
end
remove!(opts={}) click to toggle source

Calls remove(…) with {:safe => true} passed in as an option.

* Raises Mongo::OperationError if there was a DB error on removing

If you want to raise the following errors also, pass in {:raise => true}

* Raises Mongomatic::Exceptions::DocumentIsNew if document is new
* Raises Mongomatic::Exceptions::DocumentWasRemoved if document has been already removed
# File lib/mongomatic/base.rb, line 293
def remove!(opts={})
  remove(opts.merge(:safe => true))
end
removed?() click to toggle source

Will return true if the document has been removed.

# File lib/mongomatic/base.rb, line 183
def removed?
  self.removed == true
end
set_value_for_key(key, value) click to toggle source
# File lib/mongomatic/base.rb, line 148
def set_value_for_key(key, value)
  field, hash = hash_for_field(key.to_s)
  hash[field] = value
end
to_hash() click to toggle source

Return this document as a hash.

# File lib/mongomatic/base.rb, line 298
def to_hash
  @doc || {}
end
transaction(key=nil, duration=5, &block) click to toggle source
# File lib/mongomatic/base.rb, line 322
def transaction(key=nil, duration=5, &block)
  raise Mongomatic::Exceptions::DocumentIsNew if new?
  if key.is_a?(Hash) && key[:scope]
    key = [self.class.name, self["_id"].to_s, key[:scope]].join("-")
  else
    key ||= [self.class.name, self["_id"].to_s].join("-")
  end
  TransactionLock.start(key, duration, &block)
end
update(opts={},update_doc=@doc) click to toggle source

Will persist any changes you have made to the document. Silently fails on db update error. Use update! or pass in {:safe => true} to raise a Mongo::OperationError if that’s what you want. If you want to raise the following errors also, pass in {:raise => true}

* Raises Mongomatic::Exceptions::DocumentIsNew if document is new
* Raises Mongomatic::Exceptions::DocumentNotValid if there are validation errors
* Raises Mongomatic::Exceptions::DocumentWasRemoved if document has been removed
# File lib/mongomatic/base.rb, line 242
def update(opts={},update_doc=@doc)
  if opts[:raise] == true
    raise Mongomatic::Exceptions::DocumentWasRemoved if removed?
    raise Mongomatic::Exceptions::DocumentIsNew      if new?
    raise Mongomatic::Exceptions::DocumentNotValid   unless valid?
  else
    return false if new? || removed? || !valid?
  end
  do_callback(:before_update)
  do_callback(:before_insert_or_update)
  ret = self.class.collection.update({"_id" => @doc["_id"]}, update_doc, opts)
  do_callback(:after_update)
  do_callback(:after_insert_or_update)
  ret
end
update!(opts={},update_doc=@doc) click to toggle source

Calls update(…) with {:safe => true} passed in as an option.

* Raises Mongo::OperationError if there was a DB error on updating

If you want to raise the following errors also, pass in {:raise => true}

* Raises Mongomatic::Exceptions::DocumentIsNew if document is new
* Raises Mongomatic::Exceptions::DocumentNotValid if there are validation errors
* Raises Mongomatic::Exceptions::DocumentWasRemoved if document has been removed
# File lib/mongomatic/base.rb, line 264
def update!(opts={},update_doc=@doc)
  update(opts.merge(:safe => true),update_doc)
end
valid?() click to toggle source
# File lib/mongomatic/base.rb, line 118
def valid?
  check_typed_fields!
  self.errors = Mongomatic::Errors.new
  do_callback(:before_validate)
  validate
  do_callback(:after_validate)
  self.errors.empty?
end
validate() click to toggle source

Override this with your own validate() method for validations. Simply push your errors into the self.errors property and if self.errors remains empty your document will be valid.

def validate
  self.errors.add "name", "cannot be blank"
end
# File lib/mongomatic/base.rb, line 114
def validate
  true
end
value_for_key(key) click to toggle source
# File lib/mongomatic/base.rb, line 153
def value_for_key(key)
  field, hash = hash_for_field(key.to_s, true)
  hash[field]
end