Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using MongoDB with Ruby on Rails - Ryan Fischer, 20spokes

mongodb
November 04, 2011

Using MongoDB with Ruby on Rails - Ryan Fischer, 20spokes

This talk will go through using MongoDB and Ruby on Rails to build a web application. It will introduce using Mongoid an Object Document Mapper(ODM)... that provides a similar API to Active Record while utilizing MongoDB's schemaless and performant document-based design. The talk will cover model design and relations with MongoDB, querying using Mongoid's API, and testing the application with MongoDB and Mongoid.

mongodb

November 04, 2011
Tweet

More Decks by mongodb

Other Decks in Technology

Transcript

  1. What is covered • Why we use MongoDB and Ruby

    on Rails • Choices made for Object Mapper • Simple to get started!
  2. 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
  3. 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.
  4. 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
  5. 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
  6. 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.
  7. 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!
  8. mongoid.yml development: 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
  9. 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
  10. Fields available for Mongoid • Array • BigDecimal (Stored as

    a String) • Boolean • Date • DateTime • Float • Hash • Integer • Range • String • Symbol • Time
  11. 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
  12. 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
  13. Indexing class Team include Mongoid::Document field :name, type: String index

    :name, unique: true end index( [ [ :name, MONGO::ASCENDING ] [ :city, MONGO::ASCENDING ] ] ) Indexing on multiple fields -
  14. 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
  15. 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
  16. Relations in Mongoid - Embedded • Embedded Relations - stored

    inside other documents in the database. class Blog include Mongoid::Document embeds_many :posts end class Post include Mongoid::Document embedded_in :blog end
  17. Embedded Posts { "_id" : ObjectId("4e9ba47fcdffba523f000004"), "name" : "Geekbusters Blog",

    "posts" : [ {"content" : "Slimer is right behind you.", _id" : ObjectId("4e9ba47fcdffba523f000005")} ] }
  18. Polymorphic Behavior class Image include Mongoid::Document embeds_many :comments, as: :commentable

    end class Document include Mongoid::Document embeds_many :comments, as: :commentable end class Comment include Mongoid::Document embedded_in :commentable, polymorphic: true end
  19. Relations in Mongoid - Referenced class Blog include Mongoid::Document has_many

    :posts, dependent: :delete end class Post include Mongoid::Document belongs_to :blog end Referenced Relations - stores reference to a document in another collection, typically an id
  20. Many to Many Relationship class Tag include Mongoid::Document has_and_belongs_to_many :posts

    end class Post include Mongoid::Document has_and_belongs_to_many :tags end
  21. 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_of also_in and any_of asc desc distinct excludes includes limit near not_in only order_by skip where without
  22. 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
  23. 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 } ] }
  24. 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
  25. 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