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.
- .insert(doc_hash, opts = {}) ⇒ Object
- .insert!(doc_hash, opts = {}) ⇒ Object
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.
91 92 93 94 95 96 97 |
# 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 |
Instance Attribute Details
#errors ⇒ Object
Returns the value of attribute errors.
89 90 91 |
# File 'lib/mongomatic/base.rb', line 89 def errors @errors end |
#is_new ⇒ Object
Returns the value of attribute is_new.
89 90 91 |
# File 'lib/mongomatic/base.rb', line 89 def is_new @is_new end |
#removed ⇒ Object
Returns the value of attribute removed.
89 90 91 |
# File 'lib/mongomatic/base.rb', line 89 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.tableize 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 |
.insert(doc_hash, opts = {}) ⇒ Object
79 80 81 82 |
# File 'lib/mongomatic/base.rb', line 79 def insert(doc_hash, opts={}) d = new(doc_hash) d.insert(opts) end |
.insert!(doc_hash, opts = {}) ⇒ Object
84 85 86 |
# File 'lib/mongomatic/base.rb', line 84 def insert!(doc_hash, opts={}) insert(doc_hash, opts.merge(:safe => true)) end |
Instance Method Details
#==(obj) ⇒ Object
Check equality with another Mongomatic document
188 189 190 |
# File 'lib/mongomatic/base.rb', line 188 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"
172 173 174 |
# File 'lib/mongomatic/base.rb', line 172 def [](k) @doc[k.to_s] end |
#[]=(k, v) ⇒ Object
Set a field on this document:
mydoc["name"] = "Ben"
mydoc["address"] = { "city" => "San Francisco" }
138 139 140 |
# File 'lib/mongomatic/base.rb', line 138 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
165 166 167 |
# File 'lib/mongomatic/base.rb', line 165 def delete(key) @doc.delete(key) end |
#do_callback(meth) ⇒ Object
315 316 317 318 319 320 |
# 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 ⇒ Object
104 105 106 |
# File 'lib/mongomatic/base.rb', line 104 def doc @doc end |
#doc=(hash) ⇒ Object
99 100 101 102 |
# 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) ⇒ Boolean
Returns true if document contains key
143 144 145 146 |
# 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) ⇒ Object
302 303 304 305 306 307 308 309 310 311 312 313 |
# 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 = {}) ⇒ 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
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# 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 = {}) ⇒ 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
231 232 233 |
# File 'lib/mongomatic/base.rb', line 231 def insert!(opts={}) insert(opts.merge(:safe => true)) end |
#is_new? ⇒ Boolean
127 128 129 |
# File 'lib/mongomatic/base.rb', line 127 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])
178 179 180 |
# File 'lib/mongomatic/base.rb', line 178 def merge(hash) hash.each { |k,v| self[k] = v }; @doc end |
#new? ⇒ Boolean
131 132 133 |
# File 'lib/mongomatic/base.rb', line 131 def new? self.is_new == true end |
#reload ⇒ Object
Reload the document from the database
193 194 195 196 197 |
# 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 = {}) ⇒ 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
273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# 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 = {}) ⇒ 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
293 294 295 |
# File 'lib/mongomatic/base.rb', line 293 def remove!(opts={}) remove(opts.merge(:safe => true)) end |
#removed? ⇒ Boolean
Will return true if the document has been removed.
183 184 185 |
# File 'lib/mongomatic/base.rb', line 183 def removed? self.removed == true end |
#set_value_for_key(key, value) ⇒ Object
148 149 150 151 |
# 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 ⇒ Object
Return this document as a hash.
298 299 300 |
# File 'lib/mongomatic/base.rb', line 298 def to_hash @doc || {} end |
#transaction(key = nil, duration = 5, &block) ⇒ Object
322 323 324 325 326 327 328 329 330 |
# 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) ⇒ 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
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# 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) ⇒ 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
264 265 266 |
# File 'lib/mongomatic/base.rb', line 264 def update!(opts={},update_doc=@doc) update(opts.merge(:safe => true),update_doc) end |
#valid? ⇒ Boolean
118 119 120 121 122 123 124 125 |
# 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 ⇒ 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
114 115 116 |
# File 'lib/mongomatic/base.rb', line 114 def validate true end |
#value_for_key(key) ⇒ Object
153 154 155 156 |
# File 'lib/mongomatic/base.rb', line 153 def value_for_key(key) field, hash = hash_for_field(key.to_s, true) hash[field] end |