Created
November 17, 2009 19:03
-
-
Save mharris717/237159 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'mharris_ext' | |
require 'mongo' | |
class OrderedHash | |
def reject(&b) | |
res = OrderedHash.new | |
each { |k,v| res[k] = v unless yield(k,v) } | |
res | |
end | |
end | |
class Object | |
def sos(m) | |
respond_to?(m) ? send(m) : self | |
end | |
end | |
class Object | |
def safe_to_mongo_hash | |
sos(:to_mongo_hash) | |
end | |
def safe_to_mongo_object | |
sos(:to_mongo_object) | |
end | |
end | |
class Array | |
def to_mongo_hash | |
map { |x| x.safe_to_mongo_hash } | |
end | |
def to_mongo_object | |
map { |x| x.safe_to_mongo_object } | |
end | |
end | |
module MongoHash | |
def to_mongo_object | |
return self unless self['_mongo_class'] | |
cls = eval(self['_mongo_class']) | |
h = reject { |k,v| k == '_mongo_class' || k == '_id' } | |
cls.from_mongo_hash(h) | |
end | |
end | |
[Hash,OrderedHash].each { |cls| cls.send(:include,MongoHash) } | |
module MongoPersist | |
#can be overriden by class. If not, assumes that all instance variables should be saved. | |
def mongo_attributes | |
instance_variables.map { |x| x[1..-1] } | |
end | |
def to_mongo_hash | |
mongo_attributes.inject({}) { |h,attr| h.merge(attr => send(attr).safe_to_mongo_hash) }.merge("_mongo_class" => self.class.to_s) | |
end | |
def from_mongo_hash(h) | |
h = h.map_value { |v| v.safe_to_mongo_object } | |
from_hash(h) | |
end | |
def mongo_save! | |
self.class.collection.save(to_mongo_hash) | |
end | |
module ClassMethods | |
attr_accessor :collection | |
def from_mongo_hash(h) | |
new.tap { |x| x.from_mongo_hash(h) } | |
end | |
def mongo_connection(ops) | |
ops.each { |k,v| send("#{k}=",v) } | |
end | |
end | |
def self.included(mod) | |
super(mod) | |
mod.send(:extend,ClassMethods) | |
end | |
end | |
class ObjCursor | |
attr_accessor :cursor | |
include FromHash | |
def each | |
cursor.each { |x| yield(x.to_mongo_object) } | |
end | |
end | |
class Mongo::Collection | |
def find_objects(*args) | |
ObjCursor.new(:cursor => find(*args)) | |
end | |
end | |
###### END LIBRARY, START CLIENT CODE THAT USES LIBRARY ########### | |
def get_coll | |
Mongo::Connection.new.db('test-db').collection('orders') | |
end | |
class Order | |
include FromHash | |
include MongoPersist | |
mongo_connection :collection => get_coll | |
attr_accessor :po_number | |
fattr(:products) { [] } | |
end | |
class Product | |
include FromHash | |
include MongoPersist | |
attr_accessor :sku, :price | |
end | |
Order.collection.remove | |
Order.new(:po_number => 1234, :products => [Product.new(:sku => 'ABC-454', :price => 50)]).mongo_save! | |
Order.new(:po_number => 1235, :products => [Product.new(:sku => 'ABC-455', :price => 50)]).mongo_save! | |
Order.collection.find_objects.each { |x| puts x.inspect } | |
#<Order:0x168e114 @products=[#<Product:0x168dc14 @price=50, @sku="ABC-455">], @po_number=1235> | |
#<Order:0x168d624 @products=[#<Product:0x168d124 @price=50, @sku="ABC-454">], @po_number=1234> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment