default values and lambda unique_ids

This commit is contained in:
Chris Anderson 2008-10-02 14:11:04 -07:00
parent 0b0ac14b19
commit 8ac6b78170
2 changed files with 86 additions and 3 deletions

View file

@ -50,6 +50,11 @@ module CouchRest
# instantiates the hash by converting all the keys to strings. # instantiates the hash by converting all the keys to strings.
def initialize keys = {} def initialize keys = {}
super() super()
if self.class.default
self.class.default.each do |k,v|
self[k.to_s] = v
end
end
keys.each do |k,v| keys.each do |k,v|
self[k.to_s] = v self[k.to_s] = v
end end
@ -62,6 +67,7 @@ module CouchRest
# this is the CouchRest::Database that model classes will use unless # this is the CouchRest::Database that model classes will use unless
# they override it with <tt>use_database</tt> # they override it with <tt>use_database</tt>
attr_accessor :default_database attr_accessor :default_database
attr_accessor :template
# override the CouchRest::Model-wide default_database # override the CouchRest::Model-wide default_database
def use_database db def use_database db
@ -108,6 +114,14 @@ module CouchRest
end end
end end
def default
@default
end
def set_default hash
@default = hash
end
# Automatically set <tt>updated_at</tt> and <tt>created_at</tt> fields # Automatically set <tt>updated_at</tt> and <tt>created_at</tt> fields
# on the document whenever saving occurs. CouchRest uses a pretty # on the document whenever saving occurs. CouchRest uses a pretty
# decent time format by default. See Time#to_json # decent time format by default. See Time#to_json
@ -127,10 +141,18 @@ module CouchRest
# must be globally unique across all document types which share a # must be globally unique across all document types which share a
# database, so if you'd like to scope uniqueness to this class, you # database, so if you'd like to scope uniqueness to this class, you
# should use the class name as part of the unique id. # should use the class name as part of the unique id.
def unique_id method def unique_id method = nil, &block
if method
define_method :set_unique_id do define_method :set_unique_id do
self['_id'] ||= self.send(method) self['_id'] ||= self.send(method)
end 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 end
# Define a CouchDB view. The name of the view will be the concatenation # Define a CouchDB view. The name of the view will be the concatenation

View file

@ -1,7 +1,17 @@
require File.dirname(__FILE__) + '/../../spec_helper' require File.dirname(__FILE__) + '/../../spec_helper'
class Basic < CouchRest::Model 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 end
class Article < CouchRest::Model class Article < CouchRest::Model
@ -105,6 +115,15 @@ describe CouchRest::Model do
end end
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 describe "getting a model" do
before(:all) do before(:all) do
@art = Article.new(:title => 'All About Getting') @art = Article.new(:title => 'All About Getting')
@ -184,6 +203,48 @@ describe CouchRest::Model do
end end
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 describe "a model with timestamps" do
before(:all) do before(:all) do
@art = Article.new(:title => "Saving this") @art = Article.new(:title => "Saving this")