Class: Mongomatic::Base
- Inherits:
-
Object
- Object
- Mongomatic::Base
- Includes:
- ActiveModelCompliancy, Modifiers, TypedFields, Util
- Defined in:
- lib/mongomatic/base.rb
Direct Known Subclasses
Constant Summary
Constants included from TypedFields
Instance Attribute Summary collapse
-
#errors ⇒ Object
Returns the value of attribute errors.
-
#is_new ⇒ Object
Returns the value of attribute is_new.
-
#removed ⇒ Object
Returns the value of attribute removed.
Class Method Summary collapse
-
.all ⇒ Object
Return a Mongomatic::Cursor instance of all documents in the collection.
-
.collection ⇒ Object
Return the raw MongoDB collection for this model.
-
.collection_name ⇒ Object
Override this method on your model if you want to use a different collection name.
-
.count ⇒ Object
Return the number of documents in the collection.
-
.db ⇒ Object
Returns this models own db attribute if set, otherwise will return Mongomatic.db.
-
.db=(obj) ⇒ Object
Override Mongomatic.db with a Mongo::DB instance for this model specifically MyModel.db = Mongo::Connection.new().db(‘mydb_mymodel’).
- .do_callback(meth) ⇒ Object
- .drop ⇒ Object
-
.each ⇒ Object
Iterate over all documents in the collection (uses a Mongomatic::Cursor).
-
.empty? ⇒ Boolean
Is the collection empty? This method is much more efficient than doing Collection.count == 0.
-
.find(query = {}, opts = {}) ⇒ Object
Query MongoDB for documents.
-
.find_one(query = {}, opts = {}) ⇒ Object
Query MongoDB and return one document only.
-
.first ⇒ Object
Return the first document in the collection.
Instance Method Summary collapse
-
#==(obj) ⇒ Object
Check equality with another Mongomatic document.
-
#[](k) ⇒ Object
Fetch a field (just like a hash): mydoc => “Ben”.
- #[]=(k, v) ⇒ Object
-
#delete(key) ⇒ Object
Same as Hash#delete.
- #do_callback(meth) ⇒ Object
- #doc ⇒ Object
- #doc=(hash) ⇒ Object
-
#has_key?(key) ⇒ Boolean
Returns true if document contains key.
- #hash_for_field(field, break_if_dne = false) ⇒ Object
-
#initialize(doc_hash = Mongomatic::MHash.new, is_new = true) ⇒ Base
constructor
A new instance of Base.
-
#insert(opts = {}) ⇒ Object
Insert the document into the database.
-
#insert!(opts = {}) ⇒ Object
Calls insert(…) with => true passed in as an option.
- #is_new? ⇒ Boolean
-
#merge(hash) ⇒ Object
Merge this document with the supplied hash.
- #new? ⇒ Boolean
-
#reload ⇒ Object
Reload the document from the database.
-
#remove(opts = {}) ⇒ Object
Remove this document from the collection.
-
#remove!(opts = {}) ⇒ Object
Calls remove(…) with => true passed in as an option.
-
#removed? ⇒ Boolean
Will return true if the document has been removed.
- #set_value_for_key(key, value) ⇒ Object
-
#to_hash ⇒ Object
Return this document as a hash.
- #transaction(key = nil, duration = 5, &block) ⇒ Object
-
#update(opts = {}, update_doc = @doc) ⇒ Object
Will persist any changes you have made to the document.
-
#update!(opts = {}, update_doc = @doc) ⇒ Object
Calls update(…) with => true passed in as an option.
- #valid? ⇒ Boolean
-
#validate ⇒ Object
Override this with your own validate() method for validations.
- #value_for_key(key) ⇒ Object
Methods included from TypedFields
Methods included from ActiveModelCompliancy
#destroyed?, #new_record?, #persisted?, #to_key, #to_model, #to_param
Methods included from Util
Methods included from Modifiers
#add_to_set, #add_to_set!, #inc, #inc!, #pop_first, #pop_first!, #pop_last, #pop_last!, #pull, #pull!, #pull_all, #pull_all!, #push, #push!, #push_all, #push_all!, #set, #set!, #unset, #unset!
Constructor Details
#initialize(doc_hash = Mongomatic::MHash.new, is_new = true) ⇒ Base
Returns a new instance of Base.
82 83 84 85 86 87 88 |
# File 'lib/mongomatic/base.rb', line 82 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 |
Instance Attribute Details
#errors ⇒ Object
Returns the value of attribute errors.
80 81 82 |
# File 'lib/mongomatic/base.rb', line 80 def errors @errors end |
#is_new ⇒ Object
Returns the value of attribute is_new.
80 81 82 |
# File 'lib/mongomatic/base.rb', line 80 def is_new @is_new end |
#removed ⇒ Object
Returns the value of attribute removed.
80 81 82 |
# File 'lib/mongomatic/base.rb', line 80 def removed @removed end |
Class Method Details
.all ⇒ Object
Return a Mongomatic::Cursor instance of all documents in the collection.
44 45 46 |
# File 'lib/mongomatic/base.rb', line 44 def all find end |
.collection ⇒ Object
Return the raw MongoDB collection for this model
28 29 30 |
# File 'lib/mongomatic/base.rb', line 28 def collection @collection ||= self.db.collection(self.collection_name) end |
.collection_name ⇒ Object
Override this method on your model if you want to use a different collection name
23 24 25 |
# File 'lib/mongomatic/base.rb', line 23 def collection_name self.to_s end |
.count ⇒ Object
Return the number of documents in the collection
64 65 66 |
# File 'lib/mongomatic/base.rb', line 64 def count find.count end |
.db ⇒ Object
Returns this models own db attribute if set, otherwise will return Mongomatic.db
10 11 12 |
# File 'lib/mongomatic/base.rb', line 10 def db @db || Mongomatic.db || raise(ArgumentError, "No db supplied") end |
.db=(obj) ⇒ Object
Override Mongomatic.db with a Mongo::DB instance for this model specifically
MyModel.db = Mongo::Connection.new().db('mydb_mymodel')
16 17 18 19 20 |
# 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) ⇒ Object
74 75 76 77 |
# File 'lib/mongomatic/base.rb', line 74 def do_callback(meth) return false unless respond_to?(meth, true) send(meth) end |
.drop ⇒ Object
68 69 70 71 72 |
# File 'lib/mongomatic/base.rb', line 68 def drop do_callback(:before_drop) collection.drop do_callback(:after_drop) end |
.each ⇒ Object
Iterate over all documents in the collection (uses a Mongomatic::Cursor)
49 50 51 |
# File 'lib/mongomatic/base.rb', line 49 def each find.each { |found| yield(found) } end |
.empty? ⇒ Boolean
Is the collection empty? This method is much more efficient than doing Collection.count == 0
59 60 61 |
# File 'lib/mongomatic/base.rb', line 59 def empty? find.limit(1).has_next? == false end |
.find(query = {}, opts = {}) ⇒ Object
Query MongoDB for documents. Same arguments as api.mongodb.org/ruby/current/Mongo/Collection.html#find-instance_method
33 34 35 |
# File 'lib/mongomatic/base.rb', line 33 def find(query={}, opts={}) Mongomatic::Cursor.new(self, collection.find(query, opts)) end |
.find_one(query = {}, opts = {}) ⇒ Object
Query MongoDB and return one document only. Same arguments as api.mongodb.org/ruby/current/Mongo/Collection.html#find_one-instance_method
38 39 40 41 |
# 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 ⇒ Object
Return the first document in the collection
54 55 56 |
# File 'lib/mongomatic/base.rb', line 54 def first find.limit(1).next_document end |
Instance Method Details
#==(obj) ⇒ Object
Check equality with another Mongomatic document
179 180 181 |
# File 'lib/mongomatic/base.rb', line 179 def ==(obj) obj.is_a?(self.class) && obj.doc["_id"] == @doc["_id"] end |
#[](k) ⇒ Object
Fetch a field (just like a hash):
mydoc["name"]
=> "Ben"
163 164 165 |
# File 'lib/mongomatic/base.rb', line 163 def [](k) @doc[k.to_s] end |
#[]=(k, v) ⇒ Object
Set a field on this document:
mydoc["name"] = "Ben"
mydoc["address"] = { "city" => "San Francisco" }
129 130 131 |
# File 'lib/mongomatic/base.rb', line 129 def []=(k,v) @doc[k.to_s] = v end |
#delete(key) ⇒ Object
Same as Hash#delete
mydoc.delete(“name”)
=> "Ben"
mydoc.has_hey?(“name”)
=> false
156 157 158 |
# File 'lib/mongomatic/base.rb', line 156 def delete(key) @doc.delete(key) end |
#do_callback(meth) ⇒ Object
306 307 308 309 310 311 |
# File 'lib/mongomatic/base.rb', line 306 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 ⇒ Object
95 96 97 |
# File 'lib/mongomatic/base.rb', line 95 def doc @doc end |
#doc=(hash) ⇒ Object
90 91 92 93 |
# File 'lib/mongomatic/base.rb', line 90 def doc=(hash) hash = Mongomatic::MHash.new(hash) unless hash.is_a?(Mongomatic::MHash) @doc = hash end |
#has_key?(key) ⇒ Boolean
Returns true if document contains key
134 135 136 137 |
# File 'lib/mongomatic/base.rb', line 134 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) ⇒ Object
293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/mongomatic/base.rb', line 293 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 = {}) ⇒ Object
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 => true if you want a Mongo::OperationError. If you want to raise the following errors also, pass in => true
* Raises Mongomatic::Exceptions::DocumentNotNew if document is not new
* Raises Mongomatic::Exceptions::DocumentNotValid if there are validation errors
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/mongomatic/base.rb', line 197 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 = {}) ⇒ Object
Calls insert(…) with => 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 => true
* Raises Mongomatic::Exceptions::DocumentNotNew if document is not new
* Raises Mongomatic::Exceptions::DocumentNotValid if there are validation errors
222 223 224 |
# File 'lib/mongomatic/base.rb', line 222 def insert!(opts={}) insert(opts.merge(:safe => true)) end |
#is_new? ⇒ Boolean
118 119 120 |
# File 'lib/mongomatic/base.rb', line 118 def is_new? self.is_new == true end |
#merge(hash) ⇒ Object
Merge this document with the supplied hash. Useful for updates:
mydoc.merge(params[:user])
169 170 171 |
# File 'lib/mongomatic/base.rb', line 169 def merge(hash) hash.each { |k,v| self[k] = v }; @doc end |
#new? ⇒ Boolean
122 123 124 |
# File 'lib/mongomatic/base.rb', line 122 def new? self.is_new == true end |
#reload ⇒ Object
Reload the document from the database
184 185 186 187 188 |
# File 'lib/mongomatic/base.rb', line 184 def reload if obj = self.class.find({"_id" => @doc["_id"]}).next_document self.doc = obj.doc; true end end |
#remove(opts = {}) ⇒ Object
Remove this document from the collection. Silently fails on db error, use remove! or pass in => true if you want an exception raised. If you want to raise the following errors also, pass in => true
* Raises Mongomatic::Exceptions::DocumentIsNew if document is new
* Raises Mongomatic::Exceptions::DocumentWasRemoved if document has been already removed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/mongomatic/base.rb', line 264 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 = {}) ⇒ Object
Calls remove(…) with => 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 => true
* Raises Mongomatic::Exceptions::DocumentIsNew if document is new
* Raises Mongomatic::Exceptions::DocumentWasRemoved if document has been already removed
284 285 286 |
# File 'lib/mongomatic/base.rb', line 284 def remove!(opts={}) remove(opts.merge(:safe => true)) end |
#removed? ⇒ Boolean
Will return true if the document has been removed.
174 175 176 |
# File 'lib/mongomatic/base.rb', line 174 def removed? self.removed == true end |
#set_value_for_key(key, value) ⇒ Object
139 140 141 142 |
# File 'lib/mongomatic/base.rb', line 139 def set_value_for_key(key, value) field, hash = hash_for_field(key.to_s) hash[field] = value end |
#to_hash ⇒ Object
Return this document as a hash.
289 290 291 |
# File 'lib/mongomatic/base.rb', line 289 def to_hash @doc || {} end |
#transaction(key = nil, duration = 5, &block) ⇒ Object
313 314 315 316 317 |
# File 'lib/mongomatic/base.rb', line 313 def transaction(key=nil, duration=5, &block) raise Mongomatic::Exceptions::DocumentIsNew if new? key ||= [self.class.name, self["_id"].to_s].join("-") TransactionLock.start(key, duration, &block) end |
#update(opts = {}, update_doc = @doc) ⇒ Object
Will persist any changes you have made to the document. Silently fails on db update error. Use update! or pass in => true to raise a Mongo::OperationError if that’s what you want. If you want to raise the following errors also, pass in => 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
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/mongomatic/base.rb', line 233 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) ⇒ Object
Calls update(…) with => 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 => 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
255 256 257 |
# File 'lib/mongomatic/base.rb', line 255 def update!(opts={},update_doc=@doc) update(opts.merge(:safe => true),update_doc) end |
#valid? ⇒ Boolean
109 110 111 112 113 114 115 116 |
# File 'lib/mongomatic/base.rb', line 109 def valid? check_typed_fields! self.errors = Mongomatic::Errors.new do_callback(:before_validate) validate do_callback(:after_validate) self.errors.empty? end |
#validate ⇒ Object
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
105 106 107 |
# File 'lib/mongomatic/base.rb', line 105 def validate true end |
#value_for_key(key) ⇒ Object
144 145 146 147 |
# File 'lib/mongomatic/base.rb', line 144 def value_for_key(key) field, hash = hash_for_field(key.to_s, true) hash[field] end |