Docs Menu

Docs HomeMongoid

Getting Started (Rails 6)

On this page

  • New Application
  • Install rails
  • Create New Application
  • Create Git Repo
  • Add Mongoid
  • Run MongoDB Locally
  • Use MongoDB Atlas
  • Other Rails Dependencies
  • Run Application
  • Add Posts
  • Add Comments
  • Existing Application
  • Dependencies
  • Loaded Frameworks
  • ActiveRecord Configuration
  • Stop Spring
  • Mongoid Configuration
  • Adjust Models
  • Data Migration
  • Rails API

Note

This tutorial is for Ruby on Rails 6. If this is not the version you're using choose the appropriate tutorial for your Rails version from the navigation menu.

This section shows how to create a new Ruby on Rails application using Mongoid for data access. The application will be similar to the blog application described in the Ruby on Rails Getting Started guide, however using Mongoid instead of ActiveRecord as the database adapter.

The complete source code for this application can be found in the mongoid-demo GitHub repository.

Note

This guide assumes basic familiarity with Ruby on Rails. To learn more about Ruby on Rails, please refer to its Getting Started guide or other Rails guides.

We will use a Rails generator to create the application skeleton. In order to do so, the first step is to install the rails gem:

gem install rails -v '~> 6.0.0'

Use the rails command to create the application skeleton, as follows:

rails new blog --skip-active-record --skip-bundle
cd blog

Note

You may receive a warning like this:

Could not find gem 'puma (~> 3.11)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.

Disregard it as we will be taking care of gem installation in a moment.

We pass --skip-active-record to request that ActiveRecord is not added as a dependency, because we will be using Mongoid instead. Additionally we pass --skip-bundle because we'll be modifying the Gemfile to add the mongoid dependency.

If you intend to test your application with RSpec, you can instruct the generator to omit default Rails test setup by passing --skip-test and --skip-system-test options:

rails new blog --skip-bundle --skip-active-record --skip-test --skip-system-test
cd blog

While not required, we recommend creating a Git repository for your application:

git init .
git add .
git commit

Commit your changes as you are following this tutorial.

1. Modify the Gemfile to add a reference to the mongoid gem:

Gemfile
gem 'mongoid', '~> 7.0.5'

Note

Mongoid 7.0.5 or higher is required to use Rails 6.0.

  1. Install gem dependencies:

bundle install
  1. Generate the default Mongoid configuration:

bin/rails g mongoid:config

This generator will create the config/mongoid.yml configuration file, which is used to configure the connection to the MongoDB deployment. Note that as we are not using ActiveRecord we will not have a database.yml file.

The configuration created in the previous step is suitable when a MongoDB server is running locally. If you do not already have a local MongoDB server, download and install MongoDB.

While the generated mongoid.yml will work without modifications, we recommend reducing the server selection timeout for development. With this change, the uncommented lines of mongoid.yml should look like this:

development:
clients:
default:
database: blog_development
hosts:
- localhost:27017
options:
server_selection_timeout: 1

Instead of downloading, installing and running MongoDB locally, you can create a free MongoDB Atlas account and create a free MongoDB cluster in Atlas. Once the cluster is created, follow the instructions in connect to the cluster page to obtain the URI. Use the Ruby driver 2.5 or later format.

Paste the URI into the config/mongoid.yml file, and comment out the hosts that are defined. We recommend setting the server selection timeout to 5 seconds for development environment when using Atlas.

The uncommented contents of config/mongoid.yml should look like this:

development:
clients:
default:
uri: mongodb+srv://user:pass@yourcluster.mongodb.net/blog_development?retryWrites=true&w=majority
options:
server_selection_timeout: 5

If this is the first Rails application you are creating, you may need to install Node.js on your computer. This can be done via your operating system packages or by downloading a binary.

Next, if you do not have Yarn installed, follow its installation instructions.

Finally, install webpacker:

rails webpacker:install

You can now start the application server by running:

rails s

Access the application by navigating to localhost:3000.

Using the standard Rails scaffolding, Mongoid can generate the necessary model, controller and view files for our blog so that we can quickly begin creating blog posts:

bin/rails g scaffold Post title:string body:text

Navigate to localhost:3000/posts to create posts and see the posts that have already been created.

Screenshot of the new blog

To make our application more interactive, let's add the ability for users to add comments to our posts.

Create the Comment model:

bin/rails g scaffold Comment name:string message:string post:belongs_to

Open the Post model file, app/models/post.rb, and add a has_many association for the comments:

app/models/post.rb
class Post
include Mongoid::Document
field :title, type: String
field :body, type: String
has_many :comments, dependent: :destroy
end

Note

The following is only required if using a version of Mongoid < 7.0.8 or 7.1.2 (see MONGOID-4885 for details)

Open the Comment model file, app/models/comment.rb, and change the generated embedded_in association to belongs_to:

app/models/comment.rb
class Comment
include Mongoid::Document
field :name, type: String
field :message, type: String
belongs_to :post
end

Open the post show view file, app/views/posts/show.html.erb, and add a section rendering existing comments and prompting to leave a new comment:

app/views/posts/show.html.erb
<section class="section comments">
<div class="container">
<h2 class="subtitle is-5">
<strong><%= @post.comments.count %></strong> Comments
</h2>
<%= render @post.comments %>
<div class="comment-form">
<hr />
<h3 class="subtitle is-3">Leave a reply</h3>
<%= render partial: 'comments/form', locals: { comment: @post.comments.build } %>
</div>
</div>
</section>

Open the comment form file and change the type of field for :message from text_field to text_area, as well as the type of field for :post_id from text_field to hidden_field. The result should look like this:

app/views/comments/_form.html.erb
<%= form_with(model: comment, local: true) do |form| %>
<% if comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :message %>
<%= form.text_area :message %>
</div>
<div class="field">
<%= form.hidden_field :post_id %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>

Create a partial for the comment view, app/views/comments/_comment.html.erb with the following contents:

app/views/comments/_comment.html.erb
<p>
<strong><%= comment.name %>:</strong>
<%= comment.message %>
<br>
<%= link_to 'Delete', [comment],
method: :delete,
class: "button is-danger",
data: { confirm: 'Are you sure?' } %>
</p>

You should now be able to leave comments for the posts:

Screenshot of the blog with a new comment being added

Follow these steps to switch an existing Ruby on Rails application to use Mongoid instead of ActiveRecord.

Remove or comment out any RDBMS libraries like sqlite, pg etc. mentioned in Gemfile, and add mongoid:

Gemfile
gem 'mongoid', '~> 7.0.5'

Note

Mongoid 7.0.5 or higher is required to use Rails 6.0.

Install gem dependencies:

bundle install

Examine config/application.rb. If it is requiring all components of Rails via require 'rails/all', change it to require individual frameworks:

config/application.rb
# Remove or comment out
#require "rails/all"
# Add this require instead of "rails/all":
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
# require "action_mailbox/engine"
# require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
require "rails/test_unit/railtie"
# Remove or comment out ActiveRecord and ActiveStorage:
# require "active_record/railtie"
# require "active_storage/engine"

Note

At this time ActiveStorage requires ActiveRecord and is not usable with Mongoid.

Review all configuration files (config/application.rb, config/environments/{development,production.test}.rb) and remove or comment out any references to config.active_record and config.active_storage.

If your application is using Spring, which is the default on Rails 6, Spring must be stopped after changing dependencies or configuration.

./bin/spring stop

Note

Sometimes running ./bin/spring stop claims to stop Spring, but does not. Verify that all Spring processes are terminated before proceeding.

Note

Sometimes Spring tries to load ActiveRecord even when the application contains no ActiveRecord references. If this happens, add an ActiveRecord adapter dependency such as sqlite3 to your Gemfile so that ActiveRecord may be completely loaded or remove Spring from your application.

Generate the default Mongoid configuration:

bin/rails g mongoid:config

This generator will create the config/mongoid.yml configuration file, which is used to configure the connection to the MongoDB deployment.

Review the sections Run MongoDB Locally and Use MongoDB Atlas to decide how you would like to deploy MongoDB, and adjust Mongoid configuration (config/mongoid.yml) to match.

If your application already has models, these will need to be changed when migrating from ActiveRecord to Mongoid.

ActiveRecord models derive from ApplicationRecord and do not have column definitions. Mongoid models generally have no superclass but must include Mongoid::Document, and usually define the fields explicitly (but dynamic fields may also be used instead of explicit field definitions).

For example, a bare-bones Post model may look like this in ActiveRecord:

app/models/post.rb
class Post < ApplicationRecord
has_many :comments, dependent: :destroy
end

The same model may look like this in Mongoid:

app/models/post.rb
class Post
include Mongoid::Document
field :title, type: String
field :body, type: String
has_many :comments, dependent: :destroy
end

Or like this with dynamic fields:

app/models/post.rb
class Post
include Mongoid::Document
include Mongoid::Attributes::Dynamic
has_many :comments, dependent: :destroy
end

Mongoid does not utilize ActiveRecord migrations, since MongoDB does not require a schema to be defined prior to storing data.

If you already have data in a relational database that you would like to transfer to MongoDB, you will need to perform a data migration. As noted above, no schema migration is necessary because MongoDB does not require a predefined schema to store the data.

The migration tools are often specific to the data being migrated because, even though Mongoid supports a superset of ActiveRecord associations, the way that model references are stored in collections differs between Mongoid and ActiveRecord. With that said, MongoDB has some resources on migrating from an RDBMS to MongoDB such as the RDBMS to MongoDB Migration Guide and Modernization Guide.

The process for creating a Rails API application with Mongoid is the same as when creating a regular application, with the only change being the --api parameter to rails new. Migrating a Rails API application to Mongoid follows the same process described above for regular Rails applications.

A complete Rails API application similar to the one described in this tutorial can be found in the mongoid-demo GitHub repository.

←  Getting Started (Rails 7)Documents →