It’s easy to use RethinkDB with Ruby on Rails. This guide assumes some familiarity with Rails and ActiveRecord. We’ll be using NoBrainer—a RethinkDB ORM, which is an almost drop-in replacement for ActiveRecord.
Before you start
First, generate a new Rails application using NoBrainer:
$ rails new nb_app
$ cd nb_app
$ echo "gem 'nobrainer'" >> Gemfile
$ bundle install
$ rails g nobrainer:install
You can now generate models individually or use the scaffolding mechanism. For example, here’s a scaffold for an Article resource:
$ rails g scaffold Article title:string text:string tags:array
This yields the following model in app/models/article.rb
:
class Article
include NoBrainer::Document
include NoBrainer::Document::Timestamps
field :title, :type => String
field :text, :type => String
field :tags, :type => Array
end
You’re now up and running with RethinkDB and Rails!
Unlike a relational database, RethinkDB doesn’t enforce types, so
NoBrainer’s type annotations on the field are validators that are run
just before a document is saved to the database. If you don’t want to
specify the type for a field, you can use the dummy type object
:
$ rails g model User name:string:index user_data:object
This allows the user_data
field to contain any legal JSON value,
while name
must still be a valid string.
class User
include NoBrainer::Document
include NoBrainer::Document::Timestamps
field :name, :type => String, :index => true
field :custom_data
end
The NoBrainer generator automatically includes the
TimeStamps mixin that adds the
fields created_on
and updated_on
. You’ll also notice this created
a simple secondary index on the name
field. In order to add the index to the database, you can use the
Rake task:
$ rake nobrainer:sync_schema
You can specify associations between models in the generator:
$ rails g model Comment body:string liked:boolean \
user:belongs_to article:belongs_to
This will create the following model for comments:
class Comment
include NoBrainer::Document
include NoBrainer::Document::Timestamps
field :body, :type => String
field :liked, :type => Boolean
belongs_to :user
belongs_to :article
end
If we go back into the Article
model and add the has_many
side of
the association, it’s important to note that has_many
associations
in NoBrainer are read-only. The server doesn’t support transactions,
so saving the members of the association is up to the developer.
We can also specify more in-depth validation on fields. We can modify the
Article
model in a few ways to ensure the data has the properties we
expect:
class Article
include NoBrainer::Document
include NoBrainer::Document::Timestamps
has_many :comments # read only!
field :title, :type => String
field :text, :type => String, :required => true
field :tags, :type => Array, :default => []
validates :title, :length => { minimum: 5 }
end
NoBrainer runs the validations only when saving, but not when retrieving a document. This means you can always retrieve your data, but an invalid model won’t be saved to the database.
Read about validation in NoBrainer for more details.
Since NoBrainer’s has_many
associations are read-only, handling
nested resources changes a little bit. For example, if Comments
are
nested in Articles
, the comment form in the Article view would look
like this:
<%= form_for([@article, Comment.new(:article => @article)]) do |f| %>
<b>Make a comment:</b><br>
<%= f.label "I liked this article" %> <%= f.check_box :liked %><br>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
This just creates a new Comment
and associates it with the current
Article
, rather than using the build
method.
NoBrainer adds a light wrapper around ReQL queries. Here are some examples:
# Find a specific document by its primary key
Article.find "2FrYybOfzezVpT"
# Find a comment from a user with 'bob' in its name sorted by the name.
# Note: NoBrainer will use the :name index from User by default
User.where(:name => /bob/).order_by(:name => :desc).to_a
# Get two random comments that did not like the article
Comment.where(:liked => false).sample(2)
There is very comprehensive documentation of NoBrainer’s query language, and its capabilities. NoBrainer’s language is built on top of ReQL, so if you know how to do something in ReQL, it should be straightforward to translate it.
You’re on your way with Ruby on Rails and RethinkDB! Be sure to check out additional resources for more information.