MongoMapper - Mapping Ruby to and from Mongo

69
Ordered List John Nunemaker MongoSF San Francisco, CA April 30, 2010 MongoMapper Mapping Ruby To and From Mongo

Transcript of MongoMapper - Mapping Ruby to and from Mongo

Page 1: MongoMapper - Mapping Ruby to and from Mongo

Ordered ListJohn NunemakerMongoSF San Francisco, CA

April 30, 2010

MongoMapperMapping Ruby To and From Mongo

Page 2: MongoMapper - Mapping Ruby to and from Mongo

UsingExtendingProphesying

Page 3: MongoMapper - Mapping Ruby to and from Mongo

UsingExtendingProphesying

Page 4: MongoMapper - Mapping Ruby to and from Mongo

...and many more.

Page 5: MongoMapper - Mapping Ruby to and from Mongo

class Itemend

Page 6: MongoMapper - Mapping Ruby to and from Mongo

class Item include MongoMapper::Documentend

Page 7: MongoMapper - Mapping Ruby to and from Mongo

class Datum include MongoMapper::EmbeddedDocumentend

Page 8: MongoMapper - Mapping Ruby to and from Mongo

Free Stuff

Page 9: MongoMapper - Mapping Ruby to and from Mongo

Free StuffPersistence

Page 10: MongoMapper - Mapping Ruby to and from Mongo

Free StuffPersistence

Validations [presence, length, inclusion, ...]

Page 11: MongoMapper - Mapping Ruby to and from Mongo

Free StuffPersistence

Validations [presence, length, inclusion, ...]

Callbacks [before/after validate, create, save, ...]

Page 12: MongoMapper - Mapping Ruby to and from Mongo

Free StuffPersistence

Validations [presence, length, inclusion, ...]

Callbacks [before/after validate, create, save, ...]

Associations [many, belongs_to, one, ...]

Page 13: MongoMapper - Mapping Ruby to and from Mongo

Free StuffPersistence

Validations [presence, length, inclusion, ...]

Callbacks [before/after validate, create, save, ...]

Associations [many, belongs_to, one, ...]

Serialization [to_json]

Page 14: MongoMapper - Mapping Ruby to and from Mongo

PersistenceNever gonna give you up

Page 15: MongoMapper - Mapping Ruby to and from Mongo

item = Item.create({ :title => 'MongoSF', :location => 'San Fran', :when => Time.now})

Page 16: MongoMapper - Mapping Ruby to and from Mongo

puts item.to_mongo

{ "_id" => ObjectID('4bd8cc5cbcd1b313b3000001'), "title" => "MongoSF", "location" => "San Fran", "when" => Wed Apr 28 17:01:32 -0700 2010}

Page 17: MongoMapper - Mapping Ruby to and from Mongo

item = Item.newitem[:title] = 'MongoSF'item[:location] = 'San Fran'item[:when] = Time.nowitem.save

Page 18: MongoMapper - Mapping Ruby to and from Mongo

puts item.to_mongo

{ "_id" => ObjectID('4bd8cc5cbcd1b313b3000001'), "title" => "MongoSF", "location" => "San Fran", "when" => Wed Apr 28 17:01:32 -0700 2010}

Page 19: MongoMapper - Mapping Ruby to and from Mongo

TypesWhat you be baby boo?

Page 20: MongoMapper - Mapping Ruby to and from Mongo

class Item include MongoMapper::Document key :title, String key :path, Stringend

Page 21: MongoMapper - Mapping Ruby to and from Mongo

But Mongo is Schema-less?

Page 22: MongoMapper - Mapping Ruby to and from Mongo

Think App SchemaInstead of database schema

Page 23: MongoMapper - Mapping Ruby to and from Mongo

Built-in TypesArray, Binary, Boolean, Date, Float, Hash, Integer, Nil, ObjectId, Set, String, Time

Page 24: MongoMapper - Mapping Ruby to and from Mongo

Custom TypesIts shake and bake and I helped!

Page 25: MongoMapper - Mapping Ruby to and from Mongo

class Set def self.to_mongo(value) value.to_a end def self.from_mongo(value) Set.new(value || []) endend

Page 26: MongoMapper - Mapping Ruby to and from Mongo

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

Page 27: MongoMapper - Mapping Ruby to and from Mongo

class User include MongoMapper::Document key :email, DowncasedStringend

Page 28: MongoMapper - Mapping Ruby to and from Mongo

TypelessI do not know who I am

Page 29: MongoMapper - Mapping Ruby to and from Mongo

class Foo include MongoMapper::Document key :barend

foo = Foo.new

foo.bar = 'Some text'# foo.bar => "Some text"

foo.bar = 24# foo.bar => 24

Page 30: MongoMapper - Mapping Ruby to and from Mongo

ValidationsCurrently using fork of validatable

Page 31: MongoMapper - Mapping Ruby to and from Mongo

class Item include MongoMapper::Document

key :title, String validates_presence_of :titleend

Page 32: MongoMapper - Mapping Ruby to and from Mongo

class Item include MongoMapper::Document

key :title, String, :required => trueend

Page 33: MongoMapper - Mapping Ruby to and from Mongo

validates_presence_of validates_length_ofvalidates_format_ofvalidates_numericality_ofvalidates_acceptance_ofvalidates_confirmation_ofvalidates_inclusion_of validates_exclusion_of

Page 34: MongoMapper - Mapping Ruby to and from Mongo

CallbacksRipped from AS2’s cold, dead fingers

Page 35: MongoMapper - Mapping Ruby to and from Mongo

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

Page 36: MongoMapper - Mapping Ruby to and from Mongo

: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

Page 37: MongoMapper - Mapping Ruby to and from Mongo

AssociationsI belong to you

Page 38: MongoMapper - Mapping Ruby to and from Mongo

to Docsbelongs_to, one, many, many :in

Page 39: MongoMapper - Mapping Ruby to and from Mongo

class Account include MongoMapper::Document

many :sitesend

class Site include MongoMapper::Document

key :account_id, ObjectId belongs_to :accountend

Page 40: MongoMapper - Mapping Ruby to and from Mongo

account = Account.create(:title => 'OL', :sites => [ Site.new(:title => 'OL', :domain => 'orderedlist.com'), Site.new(:title => 'RT', :domain => 'railstips.org'),])

Page 41: MongoMapper - Mapping Ruby to and from Mongo

[ { '_id' => ObjectID('...'), 'title' => 'OL', 'domain' => 'orderedlist.com' 'account_id' => ObjectID('...'), }, { '_id' => ObjectID('...'), 'title' => 'RT', 'domain' => 'railstips.org' 'account_id' => ObjectID('...'), }]

Page 42: MongoMapper - Mapping Ruby to and from Mongo

to Embedded Docsmany, one

Page 43: MongoMapper - Mapping Ruby to and from Mongo

class Item include MongoMapper::Document

many :dataend

class Datum include MongoMapper::EmbeddedDocument

key :key, String key :valueend

Page 44: MongoMapper - Mapping Ruby to and from Mongo

Item.create(:title => 'MongoSF', :data => [ Datum.new(:key => 'description', :value => 'Awesome.')])

Page 45: MongoMapper - Mapping Ruby to and from Mongo

{ '_id' => ObjectID('...'), 'title' => 'MongoSF', 'data' => [ { '_id' => ObjectID('...'), 'key' => 'description' 'value' => 'Awesome.', } ]}

Page 46: MongoMapper - Mapping Ruby to and from Mongo

UsingExtendingProphesying

Page 47: MongoMapper - Mapping Ruby to and from Mongo

PluginsConventional way to extend

Page 48: MongoMapper - Mapping Ruby to and from Mongo

Powered by PluginsMongoMapper is

associations, callbacks, clone, descendants, dirty, equality, identity_map, inspect, keys, logger, modifiers, pagination, persistence, protected, rails, serialization, timestamps, userstamps, validations

Page 49: MongoMapper - Mapping Ruby to and from Mongo
Page 50: MongoMapper - Mapping Ruby to and from Mongo
Page 51: MongoMapper - Mapping Ruby to and from Mongo

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

Page 52: MongoMapper - Mapping Ruby to and from Mongo

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

Page 53: MongoMapper - Mapping Ruby to and from Mongo

class Foo include MongoMapper::Document plugin ActsAsListFuend

Foo.reorder(...)Foo.new.move_to_top

Page 54: MongoMapper - Mapping Ruby to and from Mongo

Good ExampleJoint: github.com/jnunemaker/joint

Page 55: MongoMapper - Mapping Ruby to and from Mongo

class Asset include MongoMapper::Document plugin Joint

attachment :image attachment :fileend

Page 56: MongoMapper - Mapping Ruby to and from Mongo

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

Page 57: MongoMapper - Mapping Ruby to and from Mongo

Descendant AppendsFancy Schmancy and Stolen

Page 58: MongoMapper - Mapping Ruby to and from Mongo

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

Page 59: MongoMapper - Mapping Ruby to and from Mongo

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

Page 60: MongoMapper - Mapping Ruby to and from Mongo

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'

Page 61: MongoMapper - Mapping Ruby to and from Mongo

module IdentityMapAddition def self.included(model) model.plugin MongoMapper::Plugins::IdentityMap endend

MongoMapper::Document.append_inclusions(IdentityMapAddition)

Page 62: MongoMapper - Mapping Ruby to and from Mongo

UsingExtendingProphesying

Page 63: MongoMapper - Mapping Ruby to and from Mongo

Active ModelValidations, callbacks, serialization, etc.

Page 64: MongoMapper - Mapping Ruby to and from Mongo

Blank DocumentMix and match whatever you want

Page 65: MongoMapper - Mapping Ruby to and from Mongo

Mongo::QueryFancy query magic for the ruby drivergithub.com/jnunemaker/mongo-query

Page 69: MongoMapper - Mapping Ruby to and from Mongo

Ordered List

Thank [email protected]

John NunemakerMongoSF San Francisco, CAApril 30, 2010

@jnunemaker