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)`