Why Use MongoDB with Ruby
Rate this article
Before discovering Ruby and Ruby on Rails, I was a .NET developer. At that time, I'd make ad-hoc changes to my development database, export my table/function/stored procedure/view definitions to text files, and check them into source control with any code changes. Using
diff
functionality, I'd compare the schema changes that the DBAs needed to apply to production and we'd script that out separately.I'm sure better tools existed (and I eventually started using some of RedGate's tools), but I was looking for a change. At that time, the real magic of Ruby on Rails for me was the Active Record Migrations which made working with my database fit with my programming workflow. Schema management became less of a chore and there were
rake
tasks for anything I needed (applying migrations, rolling back changes, seeding a test database).Schema versioning and management with Rails was leaps and bounds better than what I was used to, and I didn't think this could get any better — but then I found MongoDB.
When working with MongoDB, there's no need to
CREATE TABLE foo (id integer, bar varchar(255), ...)
; if a collection (or associated database) doesn't exist, inserting a new document will automatically create it for you. This means Active Record migrations are no longer needed as this level of schema change management was no longer necessary.Having the flexibility to define my data model directly within the code without needing to resort to the intermediary management that Active Record had facilitated just sort of made sense to me. I could now persist object state to my database directly, embed related model details, and easily form queries around these structures to quickly retrieve my data.
Data in MongoDB has a flexible schema as collections do not enforce a strict document structure or schema by default. This flexibility gives you data-modeling choices to match your application and its performance requirements, which aligns perfectly with Ruby's focus on simplicity and productivity.
We can easily demonstrate how to quickly get started using the MongoDB Ruby Driver using the following simple Ruby script that will connect to a cluster, insert a document, and read it back:
1 require 'bundler/inline' 2 3 gemfile do 4 source 'https://rubygems.org' 5 gem 'mongo' 6 end 7 8 client = Mongo::Client.new('mongodb+srv://username:password@mycluster.mongodb.net/test') 9 collection = client[:foo] 10 collection.insert_one({ bar: "baz" }) 11 12 puts collection.find.first 13 # => {"_id"=>BSON::ObjectId('62d83d9dceb023b20aff228a'), "bar"=>"baz"}
When the document above is inserted, an
_id
value of BSON::ObjectId('62d83d9dceb023b20aff228a')
is created. All documents must have an _id
field. However, if not provided, a default _id
of type ObjectId
will be generated. When running the above, you will get a different value for _id
, or you may choose to explicitly set it to any value you like!Feel free to give the above example a spin using your existing MongoDB cluster or MongoDB Atlas cluster. If you don't have a MongoDB Atlas cluster, sign up for an always free tier cluster to get started.
To simplify the example above, we used
bundler/inline
to provide a single-file solution using Bundler. However, the mongo
gem can be just as easily added to an existing Gemfile
or installed via gem install mongo
.Our sample above demonstrated how to quickly create and read a document. Updating and deleting documents are just as painless as shown below:
1 # set a new field 'counter' to 1 2 collection.update_one({ _id: BSON::ObjectId('62d83d9dceb023b20aff228a')}, :"$set" => { counter: 1 }) 3 4 puts collection.find.first 5 # => {"_id"=>BSON::ObjectId('62d83d9dceb023b20aff228a'), "bar"=>"baz", "counter"=>1} 6 7 # increment the field 'counter' by one 8 collection.update_one({ _id: BSON::ObjectId('62d83d9dceb023b20aff228a')}, :"$inc" => { counter: 1 }) 9 10 puts collection.find.first 11 # => {"_id"=>BSON::ObjectId('62d83d9dceb023b20aff228a'), "bar"=>"baz", "counter"=>2} 12 13 # remove the test document 14 collection.delete_one({ _id: BSON::ObjectId('62d83d9dceb023b20aff228a') })
Though all interaction with your Atlas cluster can be done directly using the MongoDB Ruby Driver, most developers prefer a layer of abstraction such as an ORM or ODM. Ruby developers can use the Mongoid ODM to easily model MongoDB collections in their code and simplify interaction using a fluid API akin to Active Record's Query Interface.
The following example adapts the previous example to use Mongoid:
1 require 'bundler/inline' 2 3 gemfile do 4 source 'https://rubygems.org' 5 6 gem 'mongoid' 7 end 8 9 Mongoid.configure do |config| 10 config.clients.default = { uri: "mongodb+srv://username:password@mycluster.mongodb.net/test" } 11 end 12 13 class Foo 14 include Mongoid::Document 15 16 field :bar, type: String 17 field :counter, type: Integer, default: 1 18 end 19 20 # create a new instance of 'Foo', which will assign a default value of 1 to the 'counter' field 21 foo = Foo.create bar: "baz" 22 23 puts foo.inspect 24 # => <Foo _id: 62d84be3ceb023b76a48df90, bar: "baz", counter: 1> 25 26 # interact with the instance variable 'foo' and modify fields programmatically 27 foo.counter += 1 28 29 # save the instance of the model, persisting changes back to MongoDB 30 foo.save! 31 32 puts foo.inspect 33 # => <Foo _id: 62d84be3ceb023b76a48df90, bar: "baz", counter: 2>
Whether you're using Ruby/Rails to build a script/automation tool, a new web application, or even the next Coinbase, MongoDB has you covered with both a Driver that simplifies interaction with your data or an ODM that seamlessly integrates your data model with your application code.
Interacting with your MongoDB data via Ruby — either using the Driver or the ODM — is straightforward, but you can also directly interface with your data from MongoDB Atlas using the built in Data Explorer. Depending on your preferences though, there are options:
- MongoDB for Visual Studio Code allows you to connect to your MongoDB instance and enables you to interact in a way that fits into your native workflow and development tools. You can navigate and browse your MongoDB databases and collections, and prototype queries and aggregations for use in your applications.
- MongoDB Compass is an interactive tool for querying, optimizing, and analyzing your MongoDB data. Get key insights, drag and drop to build pipelines, and more.
- Studio 3T is an extremely easy to use 3rd party GUI for interacting with your MongoDB data.
- MongoDB Atlas Data API lets you read and write data in Atlas with standard HTTPS requests. To use the Data API, all you need is an HTTPS client and a valid API key.
Ruby was recently added as a language export option to both MongoDB Compass and the MongoDB VS Code Extension. Using this integration you can easily convert an aggregation pipeline from either tool into code you can copy/paste into your Ruby application.