/cambric

Opinionated management and usage of CouchDB from your Ruby apps.

Primary LanguageRubyMIT LicenseMIT

Cambric

Mildly opinionated management and usage of CouchDB from your Ruby apps.

Cambric supports applications that wish to use multiple CouchDB databases/hosts, in a manner that wont muck up your application code. Moreover, it encourages you to use one design document per database used by the application.

BTW, there’s nothing specific to Rails in how this works. (^_-)

Usage

1) Configure the Cambric instances:

Cambric.configure do |config|
  config.design_doc_name = 'twitter-clone'
  config.environment = ENV['RAILS_ENV']

  config.databases = {
    :users => {
      :development => 'http://127.0.0.1:5984/users-development',
      :test => 'http://127.0.0.1:5984/users-test',
      :production => 'http://prod.server:5984/users'
    },
    :tweets => {
      :development => 'http://127.0.0.1:5984/tweets-development',
      :test => 'http://127.0.0.1:5984/tweets-test',
      :production => 'http://prod.server:5984/tweets'
    }
  }
end

2) Use one of the following methods:

Cambric.prepare_database  # Creates databases for the configured environment
                          # and pushes up their design docs.

Cambric.prepare_database! # Or, the bang method forcibly recreates your
                          # databases for the configured environment.

3) Interact with CouchRest::Database instances:

tweet_db = Cambric[:tweets]

# Just like normal...
tweet_db.save_doc :author => 'marbles',
                  :message => 'Is this pork or beef, @Randy?',
                  :followers => ['randy','zdzolton','trevorturk'],
                  :created_at => Time.now

# Except, you do NOT need to re-specify the design doc name when
# calling CouchRest::Database#view —since you're only using one!
tweet_db.view 'by_follower_and_created_at', :limit => 1

# Also, we can auto-cast doc from map-only views for you!
tweet_db.get_docs_from_view :by_follower_and_created_at, :cast_as => 'type'
# Or:
tweet_db.get_docs_from_view :by_follower_and_created_at, :cast_as => Tweet

4) Write unit tests for your JavaScript map-reduce functions:

class CambricViewTest < ActiveSupport::TestCase
  include Cambric::TestHelpers

  test "should map a user to be keyed by who he follows" do
    kv_pairs = execute_map :users,                                               # Database name
                           :followers,                                           # View name
                           '_id' => 'poddle', 'following' => ['jack', 'russel']  # Document attributes

    assert_equal 2, kv_pairs.size
    assert_equal 'jack',   kv_pairs[0]['key']
    assert_equal 'poddle', kv_pairs[0]['value']
    assert_equal 'russel', kv_pairs[1]['key']
    assert_equal 'poddle', kv_pairs[1]['value']
  end

  test "should reduce to a count of followers for a user" do
    count = execute_reduce :users,                         # Database name
                           :followers,                     # View name
                           :values => ['poddle', 'larry']  # :keys don't matter for this reduce
    assert_equal 2, count
  end

  test "should re-reduce counts of followers for a user" do
    count = execute_reduce :users,                # Database name
                           :followers,            # View name
                           :values => [2, 5, 1], 
                           :rereduce => true      # defaults to false
    assert_equal 8, count
  end

end

5) Push view/design doc changes to CouchDB:

Cambric.push_design_docs

# Alternatively, you can just call this, since it wont create
# your database, if they already exist:
Cambric.prepare_database

# Now for the real trick! This invocation will block until
# your changed design docs have primed their views:
Cambric.prime_view_changes_in_temp

Installation

  • Install couchapp:

    (Assuming you have Python) $ sudo easy_install -U couchapp

  • Install gems:

    $ sudo gem install rest-client couchrest-couchrest zdzolton-cambric

  • Configure Rails:

    • create a config/initializers/cambric.rb file as follows:

      Cambric.configure do |config|
        config.design_doc_name = 'YOUR_APP_NAME'
        config.environment = RAILS_ENV
      
        config.databases = {
          :YOUR_DB_NAME => {
            :development => "http://localhost:5984/YOUR_DB_NAME-development",
            :test => "http://localhost:5984/YOUR_DB_NAME-test"
          },
          :YOUR_OTHER_DB => {
            :development => "http://localhost:5984/YOUR_OTHER_DB-development",
            :test => "http://localhost:5984/YOUR_OTHER_DB-test"
          }
        }
      end
      
      ActionController::Dispatcher.to_prepare(:cambric) do
        case RAILS_ENV
        when 'test'
          Cambric.prepare_databases!
        when 'production'
          # Let's not automagically do anything!
        else
          Cambric.prepare_databases
        end
      end
      
    • create a couchdb directory within your project:

      $ cd /your/app/root
      $ mkdir -p ./couchdb/your_db/views/some_view_name

Copyright © 2009 Zachary Zolton. See LICENSE for details.