5. Why we switched
• Modelling complex object hierarchy
• Painfully-complex polymorphic associations
• (and about to get worse)
• Data seemed to suit a document DB
6. Document
class User
include MongoMapper::Document
key :username, String
key :real_name, String
key :date_of_birth, Date
end
7. Supported types
• Array • Object • Date
• Float • String • ObjectId
• Hash • Time • Set
• Integer • Binary
• NilClass • Boolean
8. Custom types
module MongoMapper::BigDecimal
def to_mongo value
value.to_s
end
def from_mongo value
value.present? ? new(value.to_s) : nil
end
end
BigDecimal.send :extend, MongoMapper::BigDecimal
class Person
include MongoMapper::Document
key :height, BigDecimal
end
11. Time and user stamps
class Article
include MongoMapper::Document
key :title, String
key :body, String
timestamps!
userstamps!
end
class User
include MongoMapper::Document
key :name, String
end
12. Simple associations
class Owner
include MongoMapper::Document
many :pets
end
class Pet
include MongoMapper::Document
belongs_to :owner
one :bed
end
class Bed
include MongoMapper::Document
belongs_to :pet
end
13. Embedded document
class Order
include MongoMapper::Document
many :line_items
end
class LineItem
include MongoMapper::EmbeddedDocument
key :name, String
key :quantity, Integer
end
14. Many-to-many
class Book
include MongoMapper::Document
key :title
key :author_ids, Array
many :authors, :in => :author_ids
end
class Author
include MongoMapper::Document
key :name
end
15. Basic polymorphism
class BlogPost
include MongoMapper::Document
key :body
many :comments, :as => :commentable
end
class HomePage
include MongoMapper::Document
key :content
many :comments, :as => :commentable
end
class Comment
include MongoMapper::Document
key :text
belongs_to :commentable, :polymorphic => true
16. SCI polymorphism
class Commentable
include MongoMapper::Document
many :comments
end
class BlogPost < Commentable
key :body
end
class HomePage < Commentable
key :content
end
class Comment
include MongoMapper::Document
key :text
belongs_to :commentable
end
17. Reverse polymorphism
class Site
include MongoMapper::Document
many :pages
end
class Page
include MongoMapper::Document
belongs_to :site
end
class HomePage < Page
key :content
end
class BlogPost < Page
key :body
18. M2M polymorphism
class Book
include MongoMapper::Document
key :author_ids, Array
many :authors, :in => :author_ids
end
class Novel < Book
end
class Textbook < Book
end
class Author
include MongoMapper::Document
end
class Editor < Author
end
19. Validations
class Member
include MongoMapper::Document
key :name, String
key :age, Integer
key :sex, String
validates_uniqueness_of :name
validates_presence_of :name
validates_numericality_of :age
validates_inclusion_of :sex, :in => %w{male female}
validate :custom_validation
def custom_validation
...
end
end
20. Validation shorthand
class Member
include MongoMapper::Document
key :name, String, :required => true, :unique => true
key :age, Integer, :numeric => true
key :sex, String, :in => %w{male female}
validate :custom_validation
def custom_validation
...
end
end
21. Querying
class User
include MongoMapper::Document
key :first_name, String
key :last_name, String
scope :smiths, where(:last_name => "Smith")
end
User.find "4e0c70aea7a6c32ab5000003"
User.find_by_first_name "Kerry"
User.find_by_first_name! "Kerry"
User.find_by_first_name_and_last_name "Kerry", "Buckley"
User.find_all_by_last_name "Buckley"
User.smiths.find_by_first_name "John"
24. Gotchas
• No transactions
• find versus find!
• Writes are fire-and-forget by default
• Uniqueness is per class, not per collection
• Formtastic needs hints of field type