diff --git a/lib/couchrest.rb b/lib/couchrest.rb index 31185e9..5cc6c6d 100644 --- a/lib/couchrest.rb +++ b/lib/couchrest.rb @@ -26,6 +26,7 @@ require 'couchrest/monkeypatches' module CouchRest autoload :Server, 'couchrest/core/server' autoload :Database, 'couchrest/core/database' + autoload :Model, 'couchrest/core/model' autoload :Pager, 'couchrest/helper/pager' autoload :FileManager, 'couchrest/helper/file_manager' autoload :Streamer, 'couchrest/helper/streamer' diff --git a/lib/couchrest/core/model.rb b/lib/couchrest/core/model.rb new file mode 100644 index 0000000..e3823df --- /dev/null +++ b/lib/couchrest/core/model.rb @@ -0,0 +1,73 @@ +module CouchRest + module Model + class << self + attr_accessor :default_database + end + + # instance methods on the model classes + module InstanceMethods + attr_accessor :doc + + def initialize doc = {} + self.doc = doc + unless doc['_id'] && doc['_rev'] + init_doc + end + end + + def database + self.class.database + end + + def id + doc['_id'] + end + + def rev + doc['_rev'] + end + + def save + result = database.save doc + if result['ok'] + doc['_id'] = result['id'] + doc['_rev'] = result['rev'] + end + result['ok'] + end + + private + + def init_doc + doc['type'] = self.class.to_s + end + end # module InstanceMethods + + # these show up as class methods on models that include CouchRest::Model + module ClassMethods + def use_database db + @database = db + end + + def database + @database || CouchRest::Model.default_database + end + + def uniq_id method + before_create do |model| + model.doc['_id'] = model.send(method) + end + end + end # module ClassMethods + + # bookkeeping section + + # load the code into the model class + def self.included(klass) + klass.extend ClassMethods + klass.send(:include, InstanceMethods) + end + + + end # module Model +end # module CouchRest \ No newline at end of file diff --git a/spec/couchrest/core/model_spec.rb b/spec/couchrest/core/model_spec.rb new file mode 100644 index 0000000..8603e9e --- /dev/null +++ b/spec/couchrest/core/model_spec.rb @@ -0,0 +1,67 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +class Basic + include CouchRest::Model +end + +class Article + include CouchRest::Model + use_database CouchRest.database!('http://localhost:5984/couchrest-model-test') + uniq_id :slug +end + +describe CouchRest::Model do + before(:all) do + @cr = CouchRest.new(COUCHHOST) + @db = @cr.database(TESTDB) + @db.delete! rescue nil + @db = @cr.create_db(TESTDB) rescue nil + CouchRest::Model.default_database = CouchRest.database!('http://localhost:5984/couchrest-test') + end + + it "should use the default database" do + Basic.database.info['db_name'].should == 'couchrest-test' + end + + it "should override the default db" do + Article.database.info['db_name'].should == 'couchrest-model-test' + end + + describe "saving a model" do + before(:all) do + @obj = Basic.new + @obj.save.should == true + end + + it "should save the doc" do + doc = @obj.database.get @obj.id + doc['_id'].should == @obj.id + end + + it "should be set for resaving" do + rev = @obj.rev + @obj.doc['another-key'] = "some value" + @obj.save + @obj.rev.should_not == rev + end + + it "should set the id" do + @obj.id.should be_an_instance_of String + end + + it "should set the type" do + @obj.doc['type'].should == 'Basic' + end + end + + describe "saving a model with a uniq_id configured" do + before(:all) do + @art = Article.new + end + it "should require the slug" do + lambda{@art.save}.should raise_error + @art.slug = 'this-becomes-the-id' + @art.save.should == true + end + end +end \ No newline at end of file