No commit activity in last 3 years
No release in over 3 years
CouchSurfer provides an ORM for CouchDB, as well as supporting association and validation declarations.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

>= 1.1.2
>= 0.8.2
 Project Readme

CouchSurfer - CouchDB ORM


Description

CouchSurfer is an extraction of CouchRest::Model from the excellent CouchRest gem by J. Chris Anderson. In addition, it provides association and validation methods.

Associations

CouchSurfer provides the following 4 association kinds:

  • belongs_to
  • has_many
  • has_many :inline; and
  • has_many :through

All association kinds take an optional :class_name option should you want your association to be named differently to the associated model.

class Page
  …
  belongs_to :owner, :class_name => :user
  …
end

page = Page.create(…)
page.owner # returns an instance of user

The belongs_to associations accept two additional options - :view and query, enabling you to customise your associations to fit your needs. You must explicitly declare the view on the child model for associations to work

Example 1: basic

class User
  …
  has_many :pages
  …
end

class Page
  …
  view_by :user_id
  …
end

user = User.create(…)
10.times {Page.create(…, :user_id => user.id)}
user.pages

Example 2: with options

class Account
  …
  has_many :employees,
      :class_name, :user,
      :view  => :by_account_id_and_email,
      :query => lambda { {:startkey => [account_id, nil], :endkey => [account_id, {}]}   }
  …
end

class User
  …
  view_by :account_id, :email # see validation examples below
  …
end

account = Acccount.create(…)
10.times {User.create(…, :account_id => acount.id)}
account.employees

Example 3: :inline

class User
  …
  has_many :tasks, :inline => true
  …
end

class Task
  …
  view_by :user_id
  …
end

user = User.create(…)
10.times {user.tasks << Task.new(…)}
user.save
user.tasks

Example 4: :through

class Account
  …
  has_many :projects,
      :through => :memberships
  …
end

class Membership
  …
  view_by :account_id
  …
end

class Project
  …
  view_by :account_id, :email # see validation examples below
  …
end

account = Acccount.create(…)
10.times do
  p = Project.create(…)
  Membership.create(…, :account_id => account.id, :project_id => p.id)
end
account.projects

Note on HasManyThrough

With reference to the above example, HasManyThrough works by retrieving all memberships associated with the account, collecting their ids and running a bulk retrieval on the Project.all view, which is implicitly created for all models and, as of 0.0.4, emits it's id (see CHANGELOG).

Caveats

  • Sorting needs to be done client side
  • The results do not contain any extra information that may be present on the ':through' model.

Validations

Validations, with the exception of validates_uniqueness_of, have been implemented using the Validatable gem.

Example

class Employee
  include CouchSurfer::Model
  include CouchSurfer::Associations
  include CouchSurfer::Validations

  key_accessor :email, :account_id
  belongs_to :account

  view_by :account_id, :email
  view_by :name

  validates_presence_of :name
  validates_format_of   :email, 
    :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
  validates_length_of :postcode, :is => 7, :message => "not the correct length"
  
  # Will use the Employee.by_name view with {:key => employee_instance.name}
  validates_uniqueness_of :name
  
  # Uses a custom view and key for uniqueness within a specific scope
  validates_uniqueness_of :email,
      :view => :by_account_id_and_email,
      :query => lambda{ {:key => [account_id, email]} },
      :message => "The email address for this account is taken"

end

Please check out the specs as well :)

Next

  • Error handling
  • association methods with arguments: @account.projects(:limit => 2, :offset => 1)