README.md in addywaddy-couch_surfer-0.0.2 vs README.md in addywaddy-couch_surfer-0.0.4
- old
+ new
@@ -1,52 +1,117 @@
-CouchSurfer
-===========
-
+CouchSurfer - CouchDB ORM
+=========================
+---
Description
-----------
-CouchSurfer is an extraction of CouchRest::Model from the excellent [CouchRest](http://github.com/jchris/couchrest/ "CouchRest") gem by J. Chris Anderson.
+CouchSurfer is an extraction of CouchRest::Model from the excellent [CouchRest](http://github.com/jchris/couchrest/ "CouchRest") gem by J. Chris Anderson. In addition, it provides association and validation methods.
-Features
---------
-- ORM (Extracted from CouchRest::Model)
-- Associations
- - `has_ many`
- - `belongs_to`
+Associations
+------------
+CouchSurfer provides the following 4 association kinds:
-- Validations
- - All validations from the [Validatable](http://github.com/jrun/validatable/ "Validatable") gem
- - `validates_uniqueness_of`
+ - `belongs_to`
+ - `has_many`
+ - `has_many :inline`; and
+ - `has_many :through`
-Examples
---------
+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
- include CouchSurfer::Model
- include CouchSurfer::Associations
-
- key_accessor :name
-
- # Will use the Project.by_account_id view with {:key => account_instance.id}
- has_many :projects
-
- # Uses a custom view and key
- has_many :employees, :view => {:name => :by_account_id_and_email,
- :query => lambda{ {:startkey => [id, nil], :endkey => [id, {}]} }}
+ …
+ 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
- class Project
- include CouchSurfer::Model
- include CouchSurfer::Associations
-
- key_accessor :name, :account_id
-
- belongs_to :account
-
+ account = Acccount.create(…)
+ 10.times {User.create(…, :account_id => acount.id)}
+ account.employees
+
+**Example 2: :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](http://wiki.apache.org/couchdb/HTTP_view_API "Query Options") 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](http://github.com/jrun/validatable/ "Validatable") gem.
+
+**Example**
+
class Employee
include CouchSurfer::Model
include CouchSurfer::Associations
include CouchSurfer::Validations
@@ -60,14 +125,23 @@
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, :message => "No two Beatles have the same name"
+ validates_uniqueness_of :name
- # Uses a custom view and key
- validates_uniqueness_of :email, :view => {:name => :by_account_id_and_email,
- :query => lambda{ {:key => [account_id, email]} }}, :message => "Already taken!"
+ # 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 :)
\ No newline at end of file
+
+
+Please check out the specs as well :)
+
+Next
+----
+ - Error handling
+ - association methods with arguments:
+ `@account.projects(:limit => 2, :offset => 1)`