30
Using MongoDB with Ruby on Rails presented by Ryan Fischer, Founder of 20spokes

MongoDB and Ruby on Rails

Embed Size (px)

Citation preview

Page 1: MongoDB and Ruby on Rails

Using MongoDB with Ruby on Rails

presented by Ryan Fischer, Founder of 20spokes

Page 2: MongoDB and Ruby on Rails

What is covered

• Why we use MongoDB and Ruby on Rails

• Choices made for Object Mapper

• Simple to get started!

Page 3: MongoDB and Ruby on Rails

Using MongoDB with Ruby on Rails

• Fast in-place updates with atomic modifiers

• Ruby on Rails is productive!

• Object Mappers available for MongoDB

• Mongo Ruby Driver

Page 4: MongoDB and Ruby on Rails

Mobile / Web

• Ruby on Rails makes REST easy, making APIs easier.

• Render responses as text, JSON, or XML

• Geospatial indexing for location based queries.

• Location-centric websites and mobile applications.

Page 5: MongoDB and Ruby on Rails

Why we chose MongoDB

• Cowrite - collaborative writing web application

• Versioning needed

• Originally using GridFS

• Travel720 - Gift registry web site

• Self contained relations can take advantage of embedding documents

Page 6: MongoDB and Ruby on Rails

Mongo Object Mappers for Ruby

• MongoMapper

• Mongoid

• Mongo ODM

• MongoModel

Page 7: MongoDB and Ruby on Rails

Why we chose Mongoid

• Excellent documentation

• Active community

• Compatibility with other projects/gems

• Similar API to ActiveRecord

• Uses ActiveValidation

• Mongoid Extras: Caching, Paranoid Documents, Versioning, Timestamping, Composite Keys

Page 8: MongoDB and Ruby on Rails

Compatible Gems with Mongoid

• Devise - Authentication solution for Rails based on Warden. Supports Mongoid out of box.

• Carrierwave - simple and flexible way to upload files from Ruby Applications. Supports grid_fs.

• Geocoder - complete geocoding solution for Rails. Adds geocoding by street or IP address, reverse geocoding, and distance queries.

• Mongoid-rspec - RSpec matchers and macros for Mongoid.

Page 9: MongoDB and Ruby on Rails

Getting Started

gem "mongoid", "~> 2.3"gem "bson_ext", "~> 1.4"

Include in Gem file

Run the install for Mongoid

rails generate mongoid:config

That’s it!

Page 10: MongoDB and Ruby on Rails

mongoid.ymldevelopment: host: localhost database: geekbusters_development

test: host: localhost database: geekbusters_test

production: host: <%= ENV['MONGOID_HOST'] %> port: <%= ENV['MONGOID_PORT'] %> username: <%= ENV['MONGOID_USERNAME'] %> password: <%= ENV['MONGOID_PASSWORD'] %> database: <%= ENV['MONGOID_DATABASE'] %> # slaves: # - host: slave1.local # port: 27018 # - host: slave2.local # port: 27019

Page 11: MongoDB and Ruby on Rails

Developing with MongoDB/Mongoid

• Generating models is the same using the console as with ActiveRecord.

• rails generate model Team name:string city:string location:array

• No migrations needed!

• Take advantage of embedded documents in models where applicable for increased performance.

• Store large files using GridFS

Page 12: MongoDB and Ruby on Rails

Fields available for Mongoid

• Array

• BigDecimal (Stored as a String)

• Boolean

• Date

• DateTime

• Float

• Hash

• Integer

• Range

• String

• Symbol

• Time

Page 13: MongoDB and Ruby on Rails

Mongoid Document

class Team include Mongoid::Document include Mongoid::Timestamps field :name, type: String field :city, type: String field :location, :type => Array validates :name, :city, :presence => true end

Page 14: MongoDB and Ruby on Rails

Persisting in the Controller

def create Team.create(:city => "New York", :name => "Giants")end

def update @team = Team.find(params[:id]) @team = Team.update_attributes(params[:team])end

Page 15: MongoDB and Ruby on Rails

Indexing

class Team include Mongoid::Document field :name, type: String index :name, unique: trueend

index( [ [ :name, MONGO::ASCENDING ] [ :city, MONGO::ASCENDING ] ] )

Indexing on multiple fields -

Page 16: MongoDB and Ruby on Rails

Indexing

To create indexes in the database use the rake task

rake db:mongoid:create_indexes

Or configure to autocreate in mongoid.yml (not recommended)

defaults: &defaults autocreate_indexes: true

Page 17: MongoDB and Ruby on Rails

Relations in Models

• Associations between models can be embedded or referenced

• NO JOINS!

• Objects that are referenced involve a separate query

• Embedded documents can be very efficient with reducing queries to one while managing the size of the document

• One to One, One to Many, and Many to Many relations available

Page 18: MongoDB and Ruby on Rails

Relations in Mongoid - Embedded

• Embedded Relations - stored inside other documents in the database.class Blog include Mongoid::Document embeds_many :postsend

class Post include Mongoid::Document embedded_in :blogend

Page 19: MongoDB and Ruby on Rails

Embedded Posts

{ "_id" : ObjectId("4e9ba47fcdffba523f000004"), "name" : "Geekbusters Blog", "posts" : [ {"content" : "Slimer is right behind you.", _id" : ObjectId("4e9ba47fcdffba523f000005")} ]}

Page 20: MongoDB and Ruby on Rails

Polymorphic Behaviorclass Image include Mongoid::Document embeds_many :comments, as: :commentableend

class Document include Mongoid::Document embeds_many :comments, as: :commentableend

class Comment include Mongoid::Document embedded_in :commentable, polymorphic: trueend

Page 21: MongoDB and Ruby on Rails

Relations in Mongoid - Referenced

class Blog include Mongoid::Document has_many :posts, dependent: :deleteend

class Post include Mongoid::Document belongs_to :blogend

Referenced Relations - stores reference to a document in another collection, typically an id

Page 22: MongoDB and Ruby on Rails

Many to Many Relationship

class Tag include Mongoid::Document has_and_belongs_to_many :postsend

class Post include Mongoid::Document has_and_belongs_to_many :tagsend

Page 23: MongoDB and Ruby on Rails

Querying

• Queries are of type Criteria, which is a chainable and lazily evaluated wrapper to a MongoDB dynamic query.

• Chainable queries include:all_in all_ofalso_in and any_ofascdescdistinctexcludes

includeslimitnearnot_inonlyorder_byskipwherewithout

Page 24: MongoDB and Ruby on Rails

Query Examples

Team.near(location: [20.70, 38.15]).limit(20)

Team.any_in(names: ["Giants", "Bears", "Lions"])

Team.find_or_create_by(name: "Giants")

Team.where(name: "Cowboys").destroy_all

Page 25: MongoDB and Ruby on Rails

Versioning with Mongoid

• Embeds a version of the object on each save.

• Can skip versioning and also set the max versions.

• Add to model -

include Mongoid::Versioning

Page 26: MongoDB and Ruby on Rails

Versioning Example{"_id" : ObjectId("4e9ba7fdcdffba52d6000004"), "content" : "Impossible. I am too loud to fall asleep to.", "created_at" : ISODate("2011-10-17T03:58:53Z"), "title" : "Impossible to sleep to - this guy.", "updated_at" : ISODate("2011-10-17T03:58:53Z"), "version" : 3, "versions" : [ {"title" : "Who is asleep?", "content" : "Wake up the guy next to you if they are asleep. Thanks.", "version" : 1, "created_at" : ISODate("2011-10-17T03:58:53Z")}, {"title" : "Who is asleep?", "content" : "Impossible. I am too loud to fall asleep to.", "created_at" : ISODate("2011-10-17T03:58:53Z"), "version" : 2 } ]}

Page 27: MongoDB and Ruby on Rails

And More

• Identity Map

• Callbacks

• Scopes

• Dirty Tracking

Page 28: MongoDB and Ruby on Rails

Testing Rails with MongoDB

• RSpec-Mongoid provides test matchers

• RSpec does not refresh the database with each test run.

• Database Cleaner to the rescue. It be setup to truncate a database before running tests. Add below after installing the DatabaseCleaner Gem.

config.before(:suite) do DatabaseCleaner.strategy = :truncation DatabaseCleaner.orm = "mongoid" end

Page 29: MongoDB and Ruby on Rails

Hosting Options

• Heroku is a widely used cloud hosting for Ruby on Rails

• MongoHQ and MongoLab both have add on options

• Options and pricing are similar

Page 30: MongoDB and Ruby on Rails

Thanks!!

Email: [email protected]

Twitter: @ryanfischer20

Check out Geekbusters on Github