Mongoid in the real world

58
Mongoid in the Real World Kevin Faustino @kfaustino http://adventuresincoding.com Toronto Ruby Brigade December 14, 2010

description

 

Transcript of Mongoid in the real world

Page 1: Mongoid in the real world

Mongoid in the Real World

Kevin Faustino@kfaustino

http://adventuresincoding.com

Toronto Ruby BrigadeDecember 14, 2010

Page 2: Mongoid in the real world

Thanks to our sponsors

Page 3: Mongoid in the real world

What is Mongoid?

Page 4: Mongoid in the real world

Object Document Mapper

Page 5: Mongoid in the real world
Page 6: Mongoid in the real world

Using MongoidEveryday Mongoid

Integrations

Page 7: Mongoid in the real world

class Postend

Page 8: Mongoid in the real world

class Post include Mongoid::Documentend

Page 9: Mongoid in the real world

Types

Page 10: Mongoid in the real world

class Post include Mongoid::Document include Mongoid::Timestamps

field :title field :content field :published_on, :type => DateTime field :slugend

Page 11: Mongoid in the real world

Valid Types

Array, BigDecimal, Boolean, Date, DateTime, Float, Hash, Integer, String, Symbol, Time

Page 12: Mongoid in the real world

Associations

Page 13: Mongoid in the real world

class Person include Mongoid::Document field :first_name field :last_name embeds_one :addressend

class Address include Mongoid::Document field :street field :city embedded_in :person, :inverse_of => :addressend

Page 14: Mongoid in the real world

{ "_id" : ObjectId("4d06eaa46c50a1031a000001"), "address" : { "_id" : ObjectId("4d06eade6c50a1031a000002"), "street" : "123 Liberty St.", "city" : "Toronto" }, "first_name" : "Kevin", "last_name" : "Faustino"}

Page 15: Mongoid in the real world

class Blog include Mongoid::Document

references_many :postsend

class Post include Mongoid::Document referenced_in :blogend

Page 16: Mongoid in the real world

{ "_id" : ObjectId("4c9f54866c50a10a75000003"), "blog_id" : ObjectId("4ca531c46c50a12d1b000002"), "content" : "What is Faraday? ...", "featured_image_filename" : "faraday.jpg", "slug" : "building-modular-http-client-code-with-faraday", "title" : "Building modular HTTP client code with Faraday",}

Page 17: Mongoid in the real world

Validations

Page 18: Mongoid in the real world

validates_acceptance_ofvalidates_associatedvalidates_confirmation_ofvalidates_exclusion_ofvalidates_format_ofvalidates_inclusion_ofvalidates_length_ofvalidates_numericality_ofvalidates_presence_ofvalidates_uniqueness_of

ActiveModel Validators + More

Page 19: Mongoid in the real world

Indexing

Page 20: Mongoid in the real world

Defining Indexes

# uniqueindex :ssn, :unique => true

# Compound indexesindex([ [ :first_name, Mongo::ASCENDING ], [ :last_name, Mongo::ASCENDING ]])

# Foreign Key indexesreferenced_in :post, :inverse_of => :comments, :index => true

Page 21: Mongoid in the real world

Using MongoidEveryday Mongoid

Integrations

Page 22: Mongoid in the real world

Document Limit

Page 23: Mongoid in the real world

4 MB

Page 24: Mongoid in the real world
Page 25: Mongoid in the real world

Testing

Page 26: Mongoid in the real world

RSpec Integration

# in spec/spec_helper.rbRSpec.configure do |config|

config.mock_with :rspec

config.before :each do Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop) end

end

Page 27: Mongoid in the real world

Shoulda Matchers?

Page 28: Mongoid in the real world

Use Remarkable

# in spec/spec_helper.rbrequire 'remarkable/active_model'require 'remarkable/mongoid'

Page 29: Mongoid in the real world

Mongoid Matchers

have_fieldreference_onereference_manybe_referenced_inembed_oneembed_manybe_embedded_invalidate_uniqueness_ofvalidate_associationAll ActiveModel validations from Remarkable::ActiveModel

Page 30: Mongoid in the real world

Cucumber Integration

# features/support/hooks.rbBefore do |scenario| Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)end

Page 31: Mongoid in the real world

Factory Girl

Page 32: Mongoid in the real world

FactoryGirl.define do

factory :post do title 'My first blog post' author 'Kevin Faustino' content 'Hello World' end

end

Works out of the box

Page 33: Mongoid in the real world

Factories with Cucumber

# features/support/env.rbrequire 'factory_girl'require 'factory_girl/step_definitions'

Page 34: Mongoid in the real world

Monkey Patched Step Definition

# features/step_definitions/mongoid_steps.rbGiven /^an? (.+) exists with an? (.+) of "([^"]*)"$/ do |model, field, value| factory_name = model.gsub(' ', '_') Factory factory_name, field => valueend

Page 35: Mongoid in the real world

Example Feature Usage

Given the following posts exist: | title | excerpt | | 10 greatest Batman Villians | We countdown ... | | The Death of Batman | Batman falls ... |

Page 36: Mongoid in the real world

Caching in Rails

Page 37: Mongoid in the real world

Create a Cache-Key

module Cacheable def cache_key if new_record? "#{collection_name}/#{id}/new" elsif respond_to?(:updated_at) "#{collection_name}/#{id}-#{updated_at.to_i}" else "#{collection_name}/#{id}" end end end

Page 38: Mongoid in the real world

Safe Operations

Page 39: Mongoid in the real world

post = Post.safely(:w => 2).create( :title => 'We will receive verification')post.safely(:w => 2).destroy

Page 40: Mongoid in the real world

:w - A client can block until a write operation has been replicated to N servers

:fsync - force the database to fsync all files before returning

Safely Options

Page 41: Mongoid in the real world

Enslave

Page 42: Mongoid in the real world

# Query specificPost.where(:title => 'Toronto Ruby').enslave

# Document specificclass Post include Mongoid::Document enslaveend

Query from your Slaves

Page 43: Mongoid in the real world

Dropping Down

Page 44: Mongoid in the real world

When you need more performance, drop down

to the driver

Page 45: Mongoid in the real world

# Add a post id only if it does not already exist on # the setcollection.update({'_id' => id}, {'$addToSet' => {'post_ids' => post.id}})

collection = mongo-ruby-driver

Page 46: Mongoid in the real world

Using MongoidEveryday Mongoid

Integrations

Page 47: Mongoid in the real world

Full Text-Search

Page 48: Mongoid in the real world

@solr = RSolr.connect :url => "http://127.0.0.1:8983/solr"@solr.add( { :id => post.id, :text => post.content, :published_on => post.published_on.strftime("%Y-%m-%dT%H:%M:00Z") }, { :add_attributes => { :commitWithin => 10000 } })

Use Solr

Page 49: Mongoid in the real world

Photo Uploads

Page 50: Mongoid in the real world

Not with paperclip!

X

Page 51: Mongoid in the real world
Page 52: Mongoid in the real world

Agnostic

Page 53: Mongoid in the real world

class Post include Mongoid::Document include Mongoid::Timestamps

field :title field :author field :content field :slug referenced_in :blog mount_uploader :featured_image, ImageUploaderend

Document Example

Page 54: Mongoid in the real world

Authentication

Page 55: Mongoid in the real world

class User include Mongoid::Document devise :database_authenticatable, :rememberable, :trackable, :validatable

end

Use Devise

Page 56: Mongoid in the real world

Coming Soon

Page 57: Mongoid in the real world

Many to Many support without dropping down

to the driver

Page 58: Mongoid in the real world

Thank you!