Cloudant+ActiveResource

nosqlgogoに行ってきた!

そこでCouchDBについて初めて聴き、RESTful APIを持っているならActiveResourceで接続できるんじゃないか?と思い、Cloudantの2GB無料アカウントをもらったのでブログでも作ってみようと試してみた。

で、現在挫折中。残骸はgithubにあげてある。 実際はCouchRest Modelが使えそう(教えてくれた@d6rkaizさんありがとう!)。

一応作業のメモ。これでfind, firstは使えるようになる。

class Cloudant < ActiveResource::Base
  self.site = "https://#{CLOUDANT_USER}.cloudant.com/"
  self.user     = CLOUDANT_USER
  self.password = CLOUDANT_PASS
  self.format   = :json

  # primary_key is for each model by default,
  # so override them by one class variable
  cattr_accessor :primary_key
  self.primary_key = "_id"

  def id_from_response(response)
    return nil if response.body.empty?

    ::JSON.parse(response.body)["id"].to_i
  end

  class << self
    def collection_path(prefix_options = {}, query_options = nil)
      prefix_options, query_options = split_options(prefix_options) if query_options.nil?
      "#{prefix(prefix_options)}#{collection_name}/_all_docs#{query_string(query_options)}"
    end

    def element_path(id, prefix_options = {}, query_options = nil)
      prefix_options, query_options = split_options(prefix_options) if query_options.nil?
      "#{prefix(prefix_options)}#{collection_name}/#{URI.escape id.to_s}#{query_string(query_options)}"
    end

    def new_element_path(prefix_options = {})
      "#{prefix(prefix_options)}#{collection_name}/new"
    end

    # in cloudant response collections are wrapped in a hash, so we have to peal them
    def instantiate_collection_with_cloudant(collection, prefix_options = {})
      if collection.is_a?(Hash) && collection["rows"].present?
        rows = collection["rows"].map { |row| { "_id" => row["id"] } }
        instantiate_collection_without_cloudant(rows, prefix_options)
       else
         instantiate_collection_without_cloudant(collection, prefix_options)
      end
    end
    alias_method_chain :instantiate_collection, :cloudant
  end
end