2. “MongoDB is designed to be
human-oriented.
It reduces the burden of
programming.
It tries to push jobs back to
machines. You can accomplish more
tasks with less work, in smaller yet
readable code.” - Banker
10. Spiff uses Mongoid
class Post
include Mongoid::Document
field :title, :type => String
field :body, :type => String
end
@posts = @db.collection('posts')
@document = {:title => "MongoDB on Rails",
:body => "Revelatory! Loved it!"}
@posts.save(@document)
11. Associations in Mongoid
class Post
include Mongoid::Document
field :title, :type => String
field :body, :type => String
has_many :comments
end
class Comment
include Mongoid::Document
field :rant, :type => String
belongs_to :post, :inverse_of => :comments
end
This creates an Embedded Document.
@posts = @db.collection('posts')
@document = {:title => "MongoDB on Rails",
:body => "Revelatory! Loved it!",
:comments => [{:rant => “I completely disagree”}]
}
@posts.save(@document)
12. Keys, Validations, Timestamps & Hooks
class Post
include Mongoid::Document
include Mongoid::Timestamps
field :title, :type => String
field :body, :type => String
field :slug, :type => String
has_many :comments
has_key :title, :unique => true # “Audi IMS” becomes “audiims”
validates_presence_of :title, :body
validates_unqiueness_of :title
before_save :set_slug
def set_slug
self.slug = “#{title.parameterize}-#{body[0..3]}”
end
end
13. Versioning a Mongo Document
class Post
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Versioning
field :title, :type => String
field :body, :type => String
field :slug, :type => String
has_many :comments
has_key :title, :unique => true # “Audi IMS” becomes “audiims”
validates_presence_of :title, :body
validates_unqiueness_of :title
before_save :set_slug
def set_slug
self.slug = “#{title.parameterize}-#{body[0..3]}”
end
end
14. Access related items
class Post
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Versioning
field :title, :type => String
field :body, :type => String
field :slug, :type => String
has_many :comments
belongs_to_related :account
has_many_related :sources
.....
end
database.yml meet database.mongo.yml
15. But does it blend?
Post.all(:conditions => { :title => “Rails 2.3” })
Post.find(:all, ...)
Post.first(...)
Post.find_or_create_by(:title => “Merb is dead”)
Post.find_or_initialize_by(...)
Associations:
@post.comments.all
16. fuck SQL! Criteria is the shit.
Criteria#all - perform exact matches
Post.criteria.all(:title => [ “Rails”, “2.3” ])
Criteria#find - match key/value
Post.criteria.and(:created_at.gt => 2.months.ago)
Criteria#exclude
Post.criteria.exclude(:created_at => Date.today)
Criteria#id - match document id
Post.criteria.id(“4b2fe28ee2dc9b5f7b000029”)
Criteria#in - match any of the values in an array
Post.criteria.in(:title => [“Merb”, “Rails”, “Ruby”]
Criteria#order_by
Post.criteria.order_by([[:created_at, :desc], [:title, :asc] ])
Criteria also has #limit, #not_in, #only, #skip
18. “But what about named scopes dude?!” -Gabe
named_scope :active, criteria.where(:active => true) do
def count
size
end
end
named_scope :inactive, :where => { :active => false }
named_scope :frags_over, lambda { |count| { :where => { :frags.gt => count } } }
named_scope :deaths_under, lambda { |count| criteria.where(:deaths.lt => count) }
19. You can chain any of the Criteria API
Post.in(:title => [“Rails”, “Ruby”]).where(:created_at.gt => 2.months.ago).skip(10)
class Post
include Mongoid::Document
class << self
def ruby_related
criteria.in(:title => [“Ruby”, “Rails”])
end
def in_last_two_months
criteria.where(:created_at.gt => 2.months.ago))
end
end
end
Post.ruby_related.in_last_two_months