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:

  protocol: 'http'
  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"


config.use_transactional_fixtures = true


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

Calling Model.by_slug shows you the underlying map function, whereas calling Model.find_by_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?

Hi, I'm Matt.

This blog is an unordered set of thoughts extracted from the mind of a software developer.

About Me PGP key

Archives  Feed  The Photolog!  t: pr0tagon1st