Using MongoDB with Rails

NoSQL databases have gone from being a curiosity to being the backend of enterprise web apps. Likewise, Rails has also matured enough to be adopted by large organizations while still being a startup favorite. Rails grew up with SQL so implementing a NoSQL database may seem to be unconventional. This guide will help any user be able to easily set up one of the most popular NoSQL databases, MongoDB.

First
When you set up your initial Rails project make sure to skip active record.

rails new my_app --skip-active-record

Active record uses migrations to control your database, which won’t be needed with MongoDB.

Next
Use Mongoid. Mongoid is a ODM (object document mapper) framework for Mongo in Ruby. It will make the rest of the process much simpler and will help you manage your database without active record.

Mongoid is wrapped up in a gem which makes installation a breeze.

gem install mongoid

Although for me it worked better to just add the mongoid gem to the gem file.

Finally
You will also need to make sure that you run the config

rails generate mongoid:config

Here is an example of what to expect the config file to look like (minus a big chuck of the comments):

development:
  # Configure available database clients. (required)
  clients:
    # Defines the default client. (required)
    default:
      # Defines the name of the default database that Mongoid can connect to.
      # (required).
      database: my_app_development
      # Provides the hosts the default client can connect to. Must be an array
      # of host:port pairs. (required)
      hosts:
        - localhost:27017
      options:
        # Change the default write concern. (default = { w: 1 })
        # write:
        #   w: 1

        # Change the default read preference. Valid options for mode are: :secondary,
        # :secondary_preferred, :primary, :primary_preferred, :nearest
        # (default: primary)
        # read:
        #   mode: :secondary_preferred
        #   tag_sets:
        #     - use: web
 seconds.
        # (default: 5)
        # connect_timeout: 5

        # The timeout to wait to execute operations on a socket before raising an error.
        # (default: 5)
        # socket_timeout: 5

        # The name of the replica set to connect to. Servers provided as seeds that do
      certifications
  options:
test:
  clients:
    default:
      database: my_app_test
      hosts:
        - localhost:27017
      options:
        read:
          mode: :primary
        max_pool_size: 1

MongoDB Data Modelling
The key point to note here is it not inheriting from ActiveRecord. Documents are the core objects in Mongoid and any object that is to be persisted to the database must include Mongoid::Document which can be seen below:

MongoDB based model

class Person
include Mongoid::Document

field :first_name, type: String
field :last_name, type: String
end

Mongoid by default stores documents in a collection in a pluralized form of the class name. For the above Person class, the collection the document would get stored in would be named people.

Some quick model configurations are

Defining a new field :

field :name, type: String
field :_id, type: String, default: ->{ name }

Localized fields

field :description, localize: true

Indexing

index “description.de” => 1
index “description.en” => 1

Relations

class User
include Mongoid::Document
field :name, type: String
embeds_many :posts
end

class Post
include Mongoid::Document
field :x, type: Integer
field :y, type: Integer
embedded_in :user
end

Once you have MongoDB setup, make sure to reference the docs for everything from how to query, to nested attributes. Blogs like Mongotips are also a great way to grow your knowledge of MongoDB while you are using it with Rails.

 
174
Kudos
 
174
Kudos

Now read this

Achievement AND Fulfillment

Today I was listening to a podcast on my blazing hot ride home (like I always do). In it, Tony Robbins was being interviewed about living life at the top of your game (click the title to hear the interview). He said a phrase that struck... Continue →