<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/core_ext/symbol.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,4 +1,4 @@
 --- 
 :major: 0
 :minor: 2
-:patch: 6
+:patch: 7</diff>
      <filename>VERSION.yml</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 
 Gem::Specification.new do |s|
   s.name = %q{couch_potato}
-  s.version = &quot;0.2.6&quot;
+  s.version = &quot;0.2.7&quot;
 
   s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
   s.authors = [&quot;Alexander Lang&quot;]</diff>
      <filename>couch_potato.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -10,26 +10,26 @@ require 'validatable'
 
 module CouchPotato
   Config = OpenStruct.new
-  
+
   # Returns a database instance which you can then use to create objects and query views. You have to set the CouchPotato::Config.database_name before this works.
   def self.database
     @@__database ||= Database.new(self.couchrest_database)
   end
-  
+
   # Returns the underlying CouchRest database object if you want low level access to your CouchDB. You have to set the CouchPotato::Config.database_name before this works.
   def self.couchrest_database
     @@__couchrest_database ||= CouchRest.database(full_url_to_database)
   end
-  
+
   private
-  
+
   def self.full_url_to_database
-    database_name = CouchPotato::Config.database_name || raise('No Database configured. Set CouchPotato::Config.database_name')
-    url = database_name
-    if url !~ /^http:\/\//
-      url = &quot;http://localhost:5984/#{database_name}&quot;
+    raise('No Database configured. Set CouchPotato::Config.database_name') unless CouchPotato::Config.database_name
+    if CouchPotato::Config.database_server
+      return &quot;#{CouchPotato::Config.database_server}#{CouchPotato::Config.database_name}&quot;
+    else
+      return &quot;http://127.0.0.1:5984/#{CouchPotato::Config.database_name}&quot;
     end
-    url
   end
 end
 
@@ -37,5 +37,6 @@ require File.dirname(__FILE__) + '/core_ext/object'
 require File.dirname(__FILE__) + '/core_ext/time'
 require File.dirname(__FILE__) + '/core_ext/date'
 require File.dirname(__FILE__) + '/core_ext/string'
+require File.dirname(__FILE__) + '/core_ext/symbol'
 require File.dirname(__FILE__) + '/couch_potato/persistence'
 </diff>
      <filename>lib/couch_potato.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,10 +35,10 @@ module CouchPotato
     alias_method :save!, :save_document!
   
     def destroy_document(document)
-      document.run_callbacks :before_destroy, self
+      document.run_callbacks :before_destroy
       document._deleted = true
       database.delete_doc document.to_hash
-      document.run_callbacks :after_destroy, self
+      document.run_callbacks :after_destroy
       document._id = nil
       document._rev = nil
     end
@@ -48,7 +48,9 @@ module CouchPotato
       raise &quot;Can't load a document without an id (got nil)&quot; if id.nil?
       begin
         json = database.get(id)
-        Class.const_get(json['ruby_class']).json_create json
+        instance = Class.const_get(json['ruby_class']).json_create json
+        instance.database = self
+        instance
       rescue(RestClient::ResourceNotFound)
         nil
       end
@@ -62,29 +64,30 @@ module CouchPotato
     private
   
     def create_document(document)
-      document.run_callbacks :before_validation_on_save, self
-      document.run_callbacks :before_validation_on_create, self
+      document.database = self
+      document.run_callbacks :before_validation_on_save
+      document.run_callbacks :before_validation_on_create
       return unless document.valid?
-      document.run_callbacks :before_save, self
-      document.run_callbacks :before_create, self
+      document.run_callbacks :before_save
+      document.run_callbacks :before_create
       res = database.save_doc document.to_hash
       document._rev = res['rev']
       document._id = res['id']
-      document.run_callbacks :after_save, self
-      document.run_callbacks :after_create, self
+      document.run_callbacks :after_save
+      document.run_callbacks :after_create
       true
     end
   
     def update_document(document)
-      document.run_callbacks :before_validation_on_save, self
-      document.run_callbacks :before_validation_on_update, self
+      document.run_callbacks :before_validation_on_save
+      document.run_callbacks :before_validation_on_update
       return unless document.valid?
-      document.run_callbacks :before_save, self
-      document.run_callbacks :before_update, self
+      document.run_callbacks :before_save
+      document.run_callbacks :before_update
       res = database.save_doc document.to_hash
       document._rev = res['rev']
-      document.run_callbacks :after_save, self
-      document.run_callbacks :after_update, self
+      document.run_callbacks :after_save
+      document.run_callbacks :after_update
       true
     end
   </diff>
      <filename>lib/couch_potato/database.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@ module CouchPotato
       base.send :include, DirtyAttributes
       base.send :include, MagicTimestamps
       base.class_eval do
-        attr_accessor :_id, :_rev, :_attachments, :_deleted
+        attr_accessor :_id, :_rev, :_attachments, :_deleted, :database
         alias_method :id, :_id
       end
     end</diff>
      <filename>lib/couch_potato/persistence.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,75 +1,38 @@
 module CouchPotato
   module Persistence
     module Callbacks
-      
-      class Callback #:nodoc:
-        def initialize(model, name, database)
-          @model, @name, @database = model, name, database
-        end
-        
-        def run
-          if @name.is_a?(Symbol)
-            run_method_callback @name
-          elsif @name.is_a?(Proc)
-            run_lambda_callback @name
-          else
-            raise &quot;Don't know how to handle callback of type #{name.class.name}&quot;
-          end
-        end
-        
-        private
-        
-        def run_method_callback(name)
-          if callback_method(name).arity == 0
-            @model.send name
-          elsif callback_method(name).arity == 1
-            @model.send name, @database
-          else
-            raise &quot;Don't know how to handle method callback with #{callback_method(name).arity} arguments&quot;
-          end
-        end
-        
-        def callback_method(name)
-          @model.method(name)
-        end
-
-        def run_lambda_callback(lambda)
-          if lambda.arity == 1
-            lambda.call @model
-          elsif lambda.arity == 2
-            lambda.call @model, @database
-          else raise &quot;Don't know how to handle lambda callback with #{lambda.arity} arguments&quot;
-          end
-        end
-        
-      end
-      
       def self.included(base)
         base.extend ClassMethods
-        
+
         base.class_eval do
           attr_accessor :skip_callbacks
           def self.callbacks
             @callbacks ||= {}
-            @callbacks[self.name] ||= {:before_validation_on_create =&gt; [], 
-              :before_validation_on_update =&gt; [], :before_validation_on_save =&gt; [], :before_create =&gt; [], 
+            @callbacks[self.name] ||= {:before_validation_on_create =&gt; [],
+              :before_validation_on_update =&gt; [], :before_validation_on_save =&gt; [], :before_create =&gt; [],
               :after_create =&gt; [], :before_update =&gt; [], :after_update =&gt; [],
               :before_save =&gt; [], :after_save =&gt; [],
               :before_destroy =&gt; [], :after_destroy =&gt; []}
           end
         end
       end
-      
+
       # Runs all callbacks on a model with the given name, i.g. :after_create.
       # 
       # This method is called by the CouchPotato::Database object when saving/destroying an object 
-      def run_callbacks(name, database)
+      def run_callbacks(name)
         return if skip_callbacks
         self.class.callbacks[name].uniq.each do |callback|
-          Callback.new(self, callback, database).run
+          if callback.is_a?(Symbol)
+            send callback
+          elsif callback.is_a?(Proc)
+            callback.call self
+          else
+            raise &quot;Don't know how to handle callback of type #{name.class.name}&quot;
+          end
         end
       end
-      
+
       module ClassMethods
         [
           :before_validation_on_create,</diff>
      <filename>lib/couch_potato/persistence/callbacks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,7 +13,7 @@ module CouchPotato
           end
         end
       end
-      
+
       module ClassMethods
         # returns all the property names of a model class that have been defined using the #property method
         #
@@ -26,13 +26,13 @@ module CouchPotato
         def property_names
           properties.map(&amp;:name)
         end
-        
+
         def json_create(json) #:nodoc:
           instance = super
           instance.send(:assign_attribute_copies_for_dirty_tracking)
           instance
         end
-        
+
         # Declare a proprty on a model class. properties are not typed by default. You can use any of the basic types by JSON (String, Integer, Fixnum, Array, Hash). If you want a property to be of a custom class you have to define it using the :class option.
         #
         # example:</diff>
      <filename>lib/couch_potato/persistence/properties.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,15 +3,19 @@ module CouchPotato
     class BaseViewSpec
       attr_reader :reduce_function, :design_document, :view_name, :view_parameters, :klass, :options
       private :klass, :options
-      
+
       def initialize(klass, view_name, options, view_parameters)
         @klass = klass
         @design_document = klass.to_s.underscore
         @view_name = view_name
         @options = options
-        @view_parameters = options.select{|key, value| [:group, :include_docs, :descending, :group_level, :limit].include?(key.to_sym)}.merge(view_parameters)
+        @view_parameters = {}
+        [:group, :include_docs, :descending, :group_level, :limit].each do |key|
+          @view_parameters[key] = options[key] if options.include?(key)
+        end
+        @view_parameters.merge!(view_parameters)
       end
-      
+
       def process_results(results)
         results
       end</diff>
      <filename>lib/couch_potato/view/base_view_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,21 +8,28 @@ require File.dirname(__FILE__) + '/raw_view_spec'
 module CouchPotato
   module View
     module CustomViews
-      
+
       def self.included(base)
         base.extend ClassMethods
       end
-      
+
       module ClassMethods
         # Declare a CouchDB view, for examples on how to use see the *ViewSpec classes in CouchPotato::View
+        def views
+          @views ||= {}
+        end
+
+        def execute_view(view_name, view_parameters)
+          view_spec_class(views[view_name][:type]).new(self, view_name, views[view_name], view_parameters)
+        end
+
         def view(view_name, options)
-          self.class.instance_eval do
-            define_method view_name do |view_parameters = {}|
-              view_spec_class(options[:type]).new self, view_name, options, view_parameters
-            end
-          end
+          view_name = view_name.to_s
+          views[view_name] = options
+          method_str = &quot;def #{view_name}(view_parameters = {}); execute_view(\&quot;#{view_name}\&quot;, view_parameters); end&quot;
+          self.instance_eval(method_str)
         end
-        
+
         def view_spec_class(type)
           if type &amp;&amp; type.is_a?(Class)
             type</diff>
      <filename>lib/couch_potato/view/custom_views.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,18 +9,18 @@ module CouchPotato
         @map_function = map_function
         @reduce_function = reduce_function
       end
-      
+
       def query_view!(parameters = {})
         begin
           query_view parameters
-        rescue RestClient::ResourceNotFound =&gt; e
+        rescue RestClient::ResourceNotFound# =&gt; e
           create_view
           retry
         end
       end
-      
+
       private
-      
+
       def create_view
         design_doc = @database.get &quot;_design/#{@design_document_name}&quot; rescue nil
         design_doc ||= {'views' =&gt; {}, &quot;_id&quot; =&gt; &quot;_design/#{@design_document_name}&quot;}
@@ -30,11 +30,11 @@ module CouchPotato
         }
         @database.save_doc(design_doc)
       end
-      
+
       def query_view(parameters)
         @database.view view_url, parameters
       end
-      
+
       def view_url
         &quot;#{@design_document_name}/#{@view_name}&quot;
       end</diff>
      <filename>lib/couch_potato/view/view_query.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,8 +24,6 @@ class CallbackRecorder
   
   attr_accessor :lambda_works
   before_create lambda {|model| model.lambda_works = true }
-  after_create lambda {|model, db| db.view CallbackRecorder.all}
-  before_update :method_callback_with_argument
   
   def callbacks
     @callbacks ||= []
@@ -246,26 +244,10 @@ describe &quot;destroy callbacks&quot; do
   end
 end
 
-describe &quot;method callbacks&quot; do
-  it &quot;should pass the database to a method with arity 1&quot; do
-    recorder = CallbackRecorder.new
-    db = stub 'db'
-    db.should_receive(:view)
-    recorder.run_callbacks :before_update, db
-  end
-end
-
 describe &quot;lambda callbacks&quot; do
   it &quot;should run the lambda&quot; do
     recorder = CallbackRecorder.new
-    recorder.run_callbacks :before_create, stub('db')
+    recorder.run_callbacks :before_create
     recorder.lambda_works.should be_true
   end
-  
-  it &quot;should pass the database to a lambda with arity 2&quot; do
-    recorder = CallbackRecorder.new
-    db = stub 'db'
-    db.should_receive(:view)
-    recorder.run_callbacks :after_create, db
-  end
 end
\ No newline at end of file</diff>
      <filename>spec/callbacks_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,10 +2,10 @@ require File.dirname(__FILE__) + '/spec_helper'
 
 class Build
   include CouchPotato::Persistence
-  
+
   property :state
   property :time
-  
+
   view :timeline, :key =&gt; :time
   view :count, :key =&gt; :time, :reduce =&gt; true
   view :minimal_timeline, :key =&gt; :time, :properties =&gt; [:state], :type =&gt; :properties
@@ -21,50 +21,51 @@ describe 'view' do
   before(:each) do
     recreate_db
   end
-  
+
   it &quot;should return instances of the class&quot; do
     CouchPotato.database.save_document Build.new(:state =&gt; 'success', :time =&gt; '2008-01-01')
-    CouchPotato.database.view(Build.timeline).map(&amp;:class).should == [Build]
+    results = CouchPotato.database.view(Build.timeline)
+    results.map(&amp;:class).should == [Build]
   end
-  
-  it &quot;should pass the view options to the viw query&quot; do
+
+  it &quot;should pass the view options to the view query&quot; do
     query = mock 'query'
     CouchPotato::View::ViewQuery.stub!(:new).and_return(query)
     query.should_receive(:query_view!).with(hash_including(:key =&gt; 1)).and_return('rows' =&gt; [])
     CouchPotato.database.view Build.timeline(:key =&gt; 1)
   end
-  
+
   it &quot;should not return documents that don't have a matching ruby_class&quot; do
     CouchPotato.couchrest_database.save_doc({:time =&gt; 'x'})
     CouchPotato.database.view(Build.timeline).should == []
   end
-  
+
   it &quot;should count documents&quot; do
     CouchPotato.database.save_document Build.new(:state =&gt; 'success', :time =&gt; '2008-01-01')
     CouchPotato.database.view(Build.count(:reduce =&gt; true)).should == 1
   end
-  
+
   it &quot;should count zero documents&quot; do
     CouchPotato.database.view(Build.count(:reduce =&gt; true)).should == 0
   end
-  
+
   describe &quot;properties defined&quot; do
     it &quot;should assign the configured properties&quot; do
       CouchPotato.couchrest_database.save_doc(:state =&gt; 'success', :time =&gt; '2008-01-01', :ruby_class =&gt; 'Build')
       CouchPotato.database.view(Build.minimal_timeline).first.state.should == 'success'
     end
-    
+
     it &quot;should not assign the properties not configured&quot; do
       CouchPotato.couchrest_database.save_doc(:state =&gt; 'success', :time =&gt; '2008-01-01', :ruby_class =&gt; 'Build')
       CouchPotato.database.view(Build.minimal_timeline).first.time.should be_nil
     end
-    
+
     it &quot;should assign the id even if it is not configured&quot; do
       id = CouchPotato.couchrest_database.save_doc(:state =&gt; 'success', :time =&gt; '2008-01-01', :ruby_class =&gt; 'Build')['id']
       CouchPotato.database.view(Build.minimal_timeline).first._id.should == id
     end
   end
-  
+
   describe &quot;no properties defined&quot; do
     it &quot;should assign all properties to the objects by default&quot; do
       id = CouchPotato.couchrest_database.save_doc({:state =&gt; 'success', :time =&gt; '2008-01-01', :ruby_class =&gt; 'Build'})['id']
@@ -74,60 +75,60 @@ describe 'view' do
       result._id.should == id
     end
   end
-  
+
   describe &quot;map function given&quot; do
     it &quot;should still return instances of the class&quot; do
       CouchPotato.couchrest_database.save_doc({:state =&gt; 'success', :time =&gt; '2008-01-01'})
       CouchPotato.database.view(Build.custom_timeline).map(&amp;:class).should == [Build]
     end
-    
+
     it &quot;should assign the properties from the value&quot; do
       CouchPotato.couchrest_database.save_doc({:state =&gt; 'success', :time =&gt; '2008-01-01'})
       CouchPotato.database.view(Build.custom_timeline).map(&amp;:state).should == ['custom_success']
     end
-    
+
     it &quot;should leave the other properties blank&quot; do
       CouchPotato.couchrest_database.save_doc({:state =&gt; 'success', :time =&gt; '2008-01-01'})
       CouchPotato.database.view(Build.custom_timeline).map(&amp;:time).should == [nil]
     end
-    
+
     describe &quot;that returns null documents&quot; do
       it &quot;should return instances of the class&quot; do
         CouchPotato.couchrest_database.save_doc({:state =&gt; 'success', :time =&gt; '2008-01-01'})
         CouchPotato.database.view(Build.custom_timeline_returns_docs).map(&amp;:class).should == [Build]
       end
-      
+
       it &quot;should assign the properties from the value&quot; do
         CouchPotato.couchrest_database.save_doc({:state =&gt; 'success', :time =&gt; '2008-01-01'})
         CouchPotato.database.view(Build.custom_timeline_returns_docs).map(&amp;:state).should == ['success']
       end
     end
   end
-  
+
   describe &quot;with array as key&quot; do
     it &quot;should create a map function with the composite key&quot; do
       CouchPotato::View::ViewQuery.should_receive(:new).with(anything, anything, anything, string_matching(/emit\(\[doc\['time'\], doc\['state'\]\]/), anything).and_return(stub('view query').as_null_object)
       CouchPotato.database.view Build.key_array_timeline
     end
   end
-  
+
   describe &quot;raw view&quot; do
     it &quot;should return the raw data&quot; do
       CouchPotato.database.save_document Build.new(:state =&gt; 'success', :time =&gt; '2008-01-01')
       CouchPotato.database.view(Build.raw)['rows'][0]['value'].should == 'success'
     end
-    
+
     it &quot;should return filtred raw data&quot; do
       CouchPotato.database.save_document Build.new(:state =&gt; 'success', :time =&gt; '2008-01-01')
       CouchPotato.database.view(Build.filtered_raw).should == ['success']
     end
-    
+
     it &quot;should pass view options declared in the view declaration to the query&quot; do
-     view_query = mock 'view_query'   
+     view_query = mock 'view_query'
      CouchPotato::View::ViewQuery.stub!(:new).and_return(view_query)
      view_query.should_receive(:query_view!).with(hash_including(:group =&gt; true)).and_return({'rows' =&gt; []})
      CouchPotato.database.view(Build.with_view_options)
     end
   end
-  
+
 end
\ No newline at end of file</diff>
      <filename>spec/custom_view_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,13 +6,14 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
 require 'couch_potato'
 
 CouchPotato::Config.database_name = 'couch_potato_test'
+CouchPotato::Config.database_server = 'http://127.0.0.1:5984/'
 
 
 class Comment
   include CouchPotato::Persistence
-  
+
   validates_presence_of :title
-  
+
   property :title
   belongs_to :commenter
 end</diff>
      <filename>spec/spec_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,8 @@
 require File.dirname(__FILE__) + '/../spec_helper'
 
+class DbTestUser
+end
+
 describe CouchPotato::Database, 'new' do
   it &quot;should raise an exception if the database doesn't exist&quot; do
     lambda {
@@ -15,4 +18,21 @@ describe CouchPotato::Database, 'load' do
       db.load nil
     }.should raise_error(&quot;Can't load a document without an id (got nil)&quot;)
   end
+  
+  it &quot;should set itself on the model&quot; do
+    user = mock 'user'
+    DbTestUser.stub!(:new).and_return(user)
+    db = CouchPotato::Database.new(stub('couchrest db', :info =&gt; nil, :get =&gt; {'ruby_class' =&gt; 'DbTestUser'}))
+    user.should_receive(:database=).with(db)
+    db.load '1'
+  end
+end
+
+describe CouchPotato::Database, 'save_document' do
+  it &quot;should set itself on the model for a new object before doing anything else&quot; do
+    db = CouchPotato::Database.new(stub('couchrest db', :info =&gt; nil))
+    user = stub('user', :new? =&gt; true, :valid? =&gt; false).as_null_object
+    user.should_receive(:database=).with(db)
+    db.save_document user
+  end
 end
\ No newline at end of file</diff>
      <filename>spec/unit/database_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>79c5ccdddf9f854782fc040e9d2caab39c89cfd7</id>
    </parent>
    <parent>
      <id>83ccc15742dfc5b5e01675a224485a4c1f0a5249</id>
    </parent>
  </parents>
  <author>
    <name>Peter Gumeson</name>
    <email>gumeson@gmail.com</email>
  </author>
  <url>http://github.com/langalex/couch_potato/commit/5a1c23e5afcd3079173a786801e3be7b0c8714f3</url>
  <id>5a1c23e5afcd3079173a786801e3be7b0c8714f3</id>
  <committed-date>2009-06-05T15:28:55-07:00</committed-date>
  <authored-date>2009-06-05T15:28:55-07:00</authored-date>
  <message>Merge commit 'langalex/master'</message>
  <tree>a0875e1a76c23865a4120ba6f0dc4da282efe6ab</tree>
  <committer>
    <name>Peter Gumeson</name>
    <email>gumeson@gmail.com</email>
  </committer>
</commit>
