diff --git a/lib/couchrest/core/model.rb b/lib/couchrest/core/model.rb
index f9151e4..811d0fd 100644
--- a/lib/couchrest/core/model.rb
+++ b/lib/couchrest/core/model.rb
@@ -50,6 +50,11 @@ module CouchRest
# instantiates the hash by converting all the keys to strings.
def initialize keys = {}
super()
+ if self.class.default
+ self.class.default.each do |k,v|
+ self[k.to_s] = v
+ end
+ end
keys.each do |k,v|
self[k.to_s] = v
end
@@ -62,6 +67,7 @@ module CouchRest
# this is the CouchRest::Database that model classes will use unless
# they override it with use_database
attr_accessor :default_database
+ attr_accessor :template
# override the CouchRest::Model-wide default_database
def use_database db
@@ -107,6 +113,14 @@ module CouchRest
end
end
end
+
+ def default
+ @default
+ end
+
+ def set_default hash
+ @default = hash
+ end
# Automatically set updated_at and created_at fields
# on the document whenever saving occurs. CouchRest uses a pretty
@@ -127,9 +141,17 @@ module CouchRest
# must be globally unique across all document types which share a
# database, so if you'd like to scope uniqueness to this class, you
# should use the class name as part of the unique id.
- def unique_id method
- define_method :set_unique_id do
- self['_id'] ||= self.send(method)
+ def unique_id method = nil, &block
+ if method
+ define_method :set_unique_id do
+ self['_id'] ||= self.send(method)
+ end
+ elsif block
+ define_method :set_unique_id do
+ uniqid = block.call(self)
+ raise ArgumentError, "unique_id block must not return nil" if uniqid.nil?
+ self['_id'] ||= uniqid
+ end
end
end
diff --git a/spec/couchrest/core/model_spec.rb b/spec/couchrest/core/model_spec.rb
index 91ac358..42b8f3c 100644
--- a/spec/couchrest/core/model_spec.rb
+++ b/spec/couchrest/core/model_spec.rb
@@ -1,7 +1,17 @@
require File.dirname(__FILE__) + '/../../spec_helper'
class Basic < CouchRest::Model
+end
+class WithTemplate < CouchRest::Model
+ unique_id do |model|
+ model['important-field']
+ end
+ set_default({
+ :preset => 'value',
+ 'more-template' => [1,2,3]
+ })
+ key_accessor :preset
end
class Article < CouchRest::Model
@@ -105,6 +115,15 @@ describe CouchRest::Model do
end
end
+ describe "a model with template values" do
+ before(:all) do
+ @tmpl = WithTemplate.new
+ end
+ it "should have fields set when new" do
+ @tmpl.preset.should == 'value'
+ end
+ end
+
describe "getting a model" do
before(:all) do
@art = Article.new(:title => 'All About Getting')
@@ -184,6 +203,48 @@ describe CouchRest::Model do
end
end
+ describe "saving a model with a unique_id lambda" do
+ before(:each) do
+ @templated = WithTemplate.new
+ @old = WithTemplate.get('very-important') rescue nil
+ @old.destroy if @old
+ end
+
+ it "should require the field" do
+ lambda{@templated.save}.should raise_error
+ @templated['important-field'] = 'very-important'
+ @templated.save.should == true
+ end
+
+ it "should save with the id" do
+ @templated['important-field'] = 'very-important'
+ @templated.save.should == true
+ t = WithTemplate.get('very-important')
+ t.should == @templated
+ end
+
+ it "should not change the id on update" do
+ @templated['important-field'] = 'very-important'
+ @templated.save.should == true
+ @templated['important-field'] = 'not-important'
+ @templated.save.should == true
+ t = WithTemplate.get('very-important')
+ t.should == @templated
+ end
+
+ it "should raise an error when the id is taken" do
+ @templated['important-field'] = 'very-important'
+ @templated.save.should == true
+ lambda{WithTemplate.new('important-field' => 'very-important').save}.should raise_error
+ end
+
+ it "should set the id" do
+ @templated['important-field'] = 'very-important'
+ @templated.save.should == true
+ @templated.id.should == 'very-important'
+ end
+ end
+
describe "a model with timestamps" do
before(:all) do
@art = Article.new(:title => "Saving this")