Tata AIG General Insurance Company - Insurer Innovation Award 2024
MongoDB and Ruby on Rails
1. Using MongoDB with Ruby on Rails
presented by Ryan Fischer, Founder of 20spokes
2. What is covered
• Why we use MongoDB and Ruby on Rails
• Choices made for Object Mapper
• Simple to get started!
3. 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
4. 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.
5. 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
7. 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
8. 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.
9. Getting Started
Include in Gem file
gem "mongoid", "~> 2.3"
gem "bson_ext", "~> 1.4"
Run the install for Mongoid
rails generate mongoid:config
That’s it!
11. 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
12. Fields available for Mongoid
• Array • Range
• BigDecimal (Stored as a String) • String
• Boolean • Symbol
• Date • Time
• DateTime
• Float
• Hash
• Integer
13. 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
14. 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
15. Indexing
class Team
include Mongoid::Document
field :name, type: String
index :name, unique: true
end
Indexing on multiple fields -
index(
[
[ :name, MONGO::ASCENDING ]
[ :city, MONGO::ASCENDING ]
]
)
16. 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
17. 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
18. 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
20. 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
21. Relations in Mongoid - Referenced
Referenced Relations - stores reference to a document in another collection,
typically an id
class Blog
include Mongoid::Document
has_many :posts, dependent: :delete
end
class Post
include Mongoid::Document
belongs_to :blog
end
22. 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
23. Querying
• Queries are of type Criteria, which is a chainable and lazily evaluated wrapper
to a MongoDB dynamic query.
• Chainable queries include:
all_in includes
all_of limit
also_in near
and not_in
any_of only
asc order_by
desc skip
distinct where
excludes without
25. 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
26. 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 } ]
}
28. 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
29. 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