MongoMapper - Mapping Ruby to and from Mongo
-
Upload
john-nunemaker -
Category
Documents
-
view
9.973 -
download
1
Transcript of MongoMapper - Mapping Ruby to and from Mongo
Ordered ListJohn NunemakerMongoSF San Francisco, CA
April 30, 2010
MongoMapperMapping Ruby To and From Mongo
UsingExtendingProphesying
UsingExtendingProphesying
...and many more.
class Itemend
class Item include MongoMapper::Documentend
class Datum include MongoMapper::EmbeddedDocumentend
Free Stuff
Free StuffPersistence
Free StuffPersistence
Validations [presence, length, inclusion, ...]
Free StuffPersistence
Validations [presence, length, inclusion, ...]
Callbacks [before/after validate, create, save, ...]
Free StuffPersistence
Validations [presence, length, inclusion, ...]
Callbacks [before/after validate, create, save, ...]
Associations [many, belongs_to, one, ...]
Free StuffPersistence
Validations [presence, length, inclusion, ...]
Callbacks [before/after validate, create, save, ...]
Associations [many, belongs_to, one, ...]
Serialization [to_json]
PersistenceNever gonna give you up
item = Item.create({ :title => 'MongoSF', :location => 'San Fran', :when => Time.now})
puts item.to_mongo
{ "_id" => ObjectID('4bd8cc5cbcd1b313b3000001'), "title" => "MongoSF", "location" => "San Fran", "when" => Wed Apr 28 17:01:32 -0700 2010}
item = Item.newitem[:title] = 'MongoSF'item[:location] = 'San Fran'item[:when] = Time.nowitem.save
puts item.to_mongo
{ "_id" => ObjectID('4bd8cc5cbcd1b313b3000001'), "title" => "MongoSF", "location" => "San Fran", "when" => Wed Apr 28 17:01:32 -0700 2010}
TypesWhat you be baby boo?
class Item include MongoMapper::Document key :title, String key :path, Stringend
But Mongo is Schema-less?
Think App SchemaInstead of database schema
Built-in TypesArray, Binary, Boolean, Date, Float, Hash, Integer, Nil, ObjectId, Set, String, Time
Custom TypesIts shake and bake and I helped!
class Set def self.to_mongo(value) value.to_a end def self.from_mongo(value) Set.new(value || []) endend
class DowncasedString def self.to_mongo(value) value.nil? ? nil : value.to_s.downcase end def self.from_mongo(value) value.nil? ? nil : value.to_s.downcase endend
class User include MongoMapper::Document key :email, DowncasedStringend
TypelessI do not know who I am
class Foo include MongoMapper::Document key :barend
foo = Foo.new
foo.bar = 'Some text'# foo.bar => "Some text"
foo.bar = 24# foo.bar => 24
ValidationsCurrently using fork of validatable
class Item include MongoMapper::Document
key :title, String validates_presence_of :titleend
class Item include MongoMapper::Document
key :title, String, :required => trueend
validates_presence_of validates_length_ofvalidates_format_ofvalidates_numericality_ofvalidates_acceptance_ofvalidates_confirmation_ofvalidates_inclusion_of validates_exclusion_of
CallbacksRipped from AS2’s cold, dead fingers
class Item include MongoMapper::Document key :title, String key :path, String key :parent_id, ObjectId belongs_to :parent
before_validation :set_path
private def set_path self.path = parent.path + title.parameterize endend
:before_save, :after_save,:before_create, :after_create,:before_update, :after_update,:before_validation, :after_validation,:before_validation_on_create, :after_validation_on_create,:before_validation_on_update, :after_validation_on_update,:before_destroy, :after_destroy,:validate_on_create, :validate_on_update,:validate
AssociationsI belong to you
to Docsbelongs_to, one, many, many :in
class Account include MongoMapper::Document
many :sitesend
class Site include MongoMapper::Document
key :account_id, ObjectId belongs_to :accountend
account = Account.create(:title => 'OL', :sites => [ Site.new(:title => 'OL', :domain => 'orderedlist.com'), Site.new(:title => 'RT', :domain => 'railstips.org'),])
[ { '_id' => ObjectID('...'), 'title' => 'OL', 'domain' => 'orderedlist.com' 'account_id' => ObjectID('...'), }, { '_id' => ObjectID('...'), 'title' => 'RT', 'domain' => 'railstips.org' 'account_id' => ObjectID('...'), }]
to Embedded Docsmany, one
class Item include MongoMapper::Document
many :dataend
class Datum include MongoMapper::EmbeddedDocument
key :key, String key :valueend
Item.create(:title => 'MongoSF', :data => [ Datum.new(:key => 'description', :value => 'Awesome.')])
{ '_id' => ObjectID('...'), 'title' => 'MongoSF', 'data' => [ { '_id' => ObjectID('...'), 'key' => 'description' 'value' => 'Awesome.', } ]}
UsingExtendingProphesying
PluginsConventional way to extend
Powered by PluginsMongoMapper is
associations, callbacks, clone, descendants, dirty, equality, identity_map, inspect, keys, logger, modifiers, pagination, persistence, protected, rails, serialization, timestamps, userstamps, validations
module MongoMapper module Plugins def plugins @plugins ||= [] end
def plugin(mod) extend mod::ClassMethods if mod.const_defined?(:ClassMethods) include mod::InstanceMethods if mod.const_defined?(:InstanceMethods) mod.configure(self) if mod.respond_to?(:configure) plugins << mod end endend
module ActsAsListFu module ClassMethods def reorder(ids) # reorder ids... end end
module InstanceMethods def move_to_top # move to top end end
def self.configure(model) model.key :position, Integer, :default => 1 endend
class Foo include MongoMapper::Document plugin ActsAsListFuend
Foo.reorder(...)Foo.new.move_to_top
Good ExampleJoint: github.com/jnunemaker/joint
class Asset include MongoMapper::Document plugin Joint
attachment :image attachment :fileend
asset = Asset.create({ :image => File.open('john.jpg', 'r'), :file => File.open('foo.txt', 'r'),})
asset.image.idasset.image.nameasset.image.typeasset.image.sizeasset.image.read
Descendant AppendsFancy Schmancy and Stolen
module FancySchmancy def some_method puts 'some method' endend
MongoMapper::Document.append_extensions(FancySchmancy)
class Foo include MongoMapper::Documentend
Foo.some_method # puts 'some method'Foo.new.some_method # NoMethodError
module FancySchmancy def some_method puts 'some method' endend
MongoMapper::Document.append_inclusions(FancySchmancy)
class Foo include MongoMapper::Documentend
Foo.new.some_method # puts 'some method'Foo.some_method # NoMethodError
module FancySchmancy def some_method puts 'some method' endend
class Foo include MongoMapper::Documentend
MongoMapper::Document.append_extensions(FancySchmancy)
class Bar include MongoMapper::Documentend
Foo.some_method # puts 'some method'Bar.some_method # puts 'some method'
module IdentityMapAddition def self.included(model) model.plugin MongoMapper::Plugins::IdentityMap endend
MongoMapper::Document.append_inclusions(IdentityMapAddition)
UsingExtendingProphesying
Active ModelValidations, callbacks, serialization, etc.
Blank DocumentMix and match whatever you want
Mongo::QueryFancy query magic for the ruby drivergithub.com/jnunemaker/mongo-query
Ordered List
Thank [email protected]
John NunemakerMongoSF San Francisco, CAApril 30, 2010
@jnunemaker