Getting CouchDB to work with CouchRest in Rails 4

Published: 2013-10-08
Tagged: rails ruby

I'm trying to contribute a little bit to Discourse by refactoring some of the code. The user model has > 600 lines of code. While setting up my dev env, I checked out how they're using Redis, which made me read up a bit about NoSQL and give it a go in my own little side project.

Enter CouchDB

I was looking for something to store non-related documents, that would accumulate. Out of the many NoSQL solutions, CouchDB seemed like the best fit, so I set out to replace MySQL with Couch.

I won't go into detail about installing or using CouchDB, but here are some links to help with that: Installing, Using.

Getting Rails on the Couch

I went with CouchRest to get Rails to connect to the database itself and I also added CouchRest_Model to make working with models a little more pleasant.

I set up my connection by creating a `config/couchdb.yml' containing this:

development:
  protocol: 'http'
  host: 127.0.0.1
  port: 5984
  prefix: project
  suffix: mayhem
  username: robert
  password: paulson

...and I ran into the first obstacle that's not mentioned anywhere - Rails was trying to uses database.yml to connect to a good 'ol MySQL database, which I really didn't want it to do. I found a solution by modifying application.rb in the following fashion:

# require 'rails/all'

require "action_controller/railtie"
require "action_mailer/railtie"
require "rails/test_unit/railtie"
require "sprockets/railtie"

This disable ActiveRecord. Alternatively, if you're just generating a new rails project, you can use rails new project -O to create a rails project without ActiveRecord.

I also had to comment out the config.active_record.migration_error = :page_load line from config/environments/development.rb file for rails to run smoothly.

Edit 10/09/2013

In order to get Rspec and CouchRest working nicely together, you have to comment out two lines from spec_helper.rb:

config.fixture_path = "#{::Rails.root}/spec/fixtures"

and:

config.use_transactional_fixtures = true

Relax

From that point on it was smooth sailing. You can use ActiveModel validators such as validates_presence_of as well as callbacks, which makes working with these objects much easier.

One other thing that caught me at first was using the design function, which I haven't really figured out yet, but basically it allows you to create custom views. I'm hoping I can get more complicated map/reduce functions to work in there, I just gotta dig a little deeper into the code because the docs are a little sparse.

So far I've only had to create a finding view that looks like this:

design do
    view :by_slug
end

Calling Model.byslug shows you the underlying map function, whereas calling Model.findby_slug("slug") actually returns a document or nil.

Wrapping up

I'm really excited to be able to work with NoSQL a bit. I know it isn't a miracle pill that solves all problems, but it appears to be the perfect fit for a small project I'm working on that expects a pretty big amount of very simple writes and an equal amount of simple queries without any relations.

I've yet to figure out more complex views as well setting up a secure CouchDB in production, but it can't be too hard, can it?

Back to Top
Back to Blog

Hi, I'm Matt.

Notes on programming and life. Often both.

All views expressed are my own.