tame accidental complexity with ruby and mongomapper
Post on 19-Oct-2014
3.212 views
DESCRIPTION
Gentle introduction to MongoDb with Ruby and MongoMapperTRANSCRIPT
Tame accidental complexityIntroduction to NoSQL with MongoMapper
Giordano Scalzo
I’m not here to talk about performance
I’m not here to talk about scalability
but I’m here to talk about simplicity
Rails has been a first step
Anatomy of a Rails Application
Anatomy of a Rails Application
view
Anatomy of a Rails Application
view controller
Anatomy of a Rails Application
modelview controller
Different languages
modelview controller
html+css
Different languages
modelview controller
html+css oop
Different languages
modelview controller
html+css oop sql
Impedance mismatch
modelview controller
html+css oop sql
Origin of Sql
SQL (...), is a database computer language designed for managing data in relational database management systems (RDBMS)
SQLFrom Wikipedia, the free encyclopedia
Origin of Sql
SQL (...), is a database computer language designed for managing data in relational database management systems (RDBMS)
SQLFrom Wikipedia, the free encyclopedia
We need persistent objects!
We need persistent objects!
class User def initialize(username, password) @username = username @password = password endend
We need persistent objects!
{ username: "giordano", password: "123"}
ActiveRecord tries its best
We need something different
Persistence
Persistence
class User include MongoMapper::Documentend
Persistence
class User include MongoMapper::Documentend
user = User.create({ :username => "giordano", :password => "123"})user.save
Persistence
class User include MongoMapper::Documentend
user = User.create({ :username => "giordano", :password => "123"})user.save
puts User.all.last.to_mongo
Persistence
{ "_id"=>BSON::ObjectId('4d643a274d8ff683dd000001'), "username"=>"giordano", "password"=>"123"}
Types
Types
class User include MongoMapper::Document key :username, String key :password , Stringend
Built-in Types
Array, Binary, Boolean, Date, Float, Hash, Integer, Nil, ObjectId, Set, String, Time
Custom Types
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
Custom Types
class User include MongoMapper::Document key :username, String key :password , String key :email, DowncasedStringend
Custom Types
user = User.newuser.username = "giordano"user.password = "123"user.email = "[email protected]"
user.save
puts User.all.last.to_mongo
Custom Types
{ "_id"=>BSON::ObjectId('4d6442d94d8ff684d3000001'), "username"=>"giordano", "password"=>"123", "email"=>"[email protected]"}
Embedded Documents
Embedded Documents
class Task include MongoMapper::EmbeddedDocument key :description, String key :pomodori, Integer key :is_done, Booleanend
Embedded Documents
class User include MongoMapper::Document key :username, String key :password , String key :email, DowncasedString many :tasksend
Embedded Documents
user.tasks << Task.new({ description: 'refactor server', pomodori: 8, is_done: false})
user.tasks << Task.new({ description: 'timer sound', pomodori: 2, is_done: false})
Embedded Documents
{"_id"=>BSON::ObjectId('4d6575e84d8ff692e6000001'), "username"=>"giordano", "password"=>"123", "email"=>"[email protected]", "tasks"=>[{ "_id"=>BSON::ObjectId('4d6575e84d8ff692e6000002'), "description"=>"refactor server", "pomodori"=>8, "is_done"=>false }, { "_id"=>BSON::ObjectId('4d6575e84d8ff692e6000003'), "description"=>"timer sound", "pomodori"=>2, "is_done"=>false }]}
Embedded Documents
{"_id"=>BSON::ObjectId('4d6575e84d8ff692e6000001'), "username"=>"giordano", "password"=>"123", "email"=>"[email protected]", "tasks"=>[{ "_id"=>BSON::ObjectId('4d6575e84d8ff692e6000002'), "description"=>"refactor server", "pomodori"=>8, "is_done"=>false }, { "_id"=>BSON::ObjectId('4d6575e84d8ff692e6000003'), "description"=>"timer sound", "pomodori"=>2, "is_done"=>false }]}
Documents
class Task include MongoMapper::Document key :description, String key :pomodori, Integer key :is_done, Booleanend
Documents
p User.all.last.to_mongo
{ "_id"=>BSON::ObjectId('4d657e924d8ff6949c000001'), "username"=>"giordano", "password"=>"123", "email"=>"[email protected]"}
Documents
p User.all.last.tasks
[#<Task _id: BSON::ObjectId('4d65822b4d8ff69542000002'), description: "refactor server", pomodori: 8, is_done: false, user_id: BSON::ObjectId('4d65822b4d8ff69542000001') >, #<Task _id: BSON::ObjectId('4d65822b4d8ff69542000003'), description: "timer sound", pomodori: 2, is_done: false, user_id: BSON::ObjectId('4d65822b4d8ff69542000001') >]
Validations & Callbacks
Validations & Callbacks
class User include MongoMapper::Document key :username, String, validates_presence_of :username key :password, String validates_presence_of :passwordend
Validations & Callbacks
class User include MongoMapper::Document key :username, String, :required => true key :password, String, :required => trueend
Validations & Callbacks
validates_presence_ofvalidates_length_ofvalidates_format_ofvalidates_numericality_ofvalidates_acceptance_ofvalidates_confirmation_ofvalidates_inclusion_ofvalidates_exclusion_of
Validations & Callbacks
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
Validations & Callbacks
forked in current gem 0.8.6using Rails3 ActiveModel in Rails3 branch just merged
What about querying?
What about querying?
Plucky: ActiveRecord-like language
query = User.where(:last_name.exists => true, :created_at.gte => from_date, :created_at.lt => Time.now) .skip(0).limit(5)
query.all
What about querying?
Plucky: ActiveRecord-like language
query = User.where(:last_name.exists => true, :created_at.gte => from_date, :created_at.lt => Time.now) .skip(0).limit(5)
#<Plucky::Query created_at: { "$gte"=>"1", "$lt"=>2011-02-24 10:54:36 UTC}, last_name: {"$exists"=>true}, limit: 5, skip: 0>
What about querying?
Plucky: ActiveRecord-like language
query = User.where(:last_name.exists => true) .where(:created_at.gte => from_date) .where(:created_at.lt => Time.now) .skip(0).limit(5)
#<Plucky::Query created_at: { "$gte"=>"1", "$lt"=>2011-02-24 10:54:36 UTC}, last_name: {"$exists"=>true}, limit: 5, skip: 0>
What about plugins?
What about plugins?AccessibleAssociationsCachingCallbacksCloneDirtyDocumentDynamic QueryingEmbeddedDocumentEqualityIdentityMapIndexesInspectKeysLogger
ModifiersPaginationPersistenceProtectedQueryingRailsSafeSingle Collection InheritanceScopesSerializationTimestampsUserstampsValidations
Itʼs just a beginning
http://mongomapper.com/documentation/
@giordanoscalzo
www.slideshare.net/giordano
github.com/gscalzo