<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -28,6 +28,13 @@ require dir / 'support' / 'object'
 module DataMapper
   module Validate
 
+    # Validate the resource before saving
+    #
+    def save(context = :default)
+      return false unless valid?(context)
+      super()
+    end
+
     # Return the ValidationErrors
     #
     def errors
@@ -178,7 +185,14 @@ module DataMapper
   end # module Validate
 
   module Resource
-    include Validate
+    class &lt;&lt; self
+      included = instance_method(:included)
+
+      define_method(:included) do |model|
+        included.bind(self).call(model)
+        model.send(:include, Validate)
+      end
+    end
 
     module ClassMethods
       include Validate::ClassMethods</diff>
      <filename>dm-validations/lib/dm-validations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@ require 'pathname'
 require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
 
 describe DataMapper::Validate do
-  before(:all) do
+  before :all do
     class Yacht
       include DataMapper::Resource
       property :id, Integer, :serial =&gt; true
@@ -12,6 +12,69 @@ describe DataMapper::Validate do
     end
   end
 
+  it 'should respond to save' do
+    Yacht.new.should respond_to(:save)
+  end
+
+  describe '#save' do
+    before do
+      Yacht.auto_migrate!
+      @yacht = Yacht.new :name =&gt; 'The Gertrude'
+    end
+
+    describe 'without context specified' do
+      it 'should validate using the default context' do
+        @yacht.should_receive(:valid?).with(:default)
+        @yacht.save
+      end
+
+      it 'should save if the object is valid for the default context' do
+        @yacht.should be_valid
+        @yacht.save.should be_true
+        @yacht.should_not be_new_record
+      end
+
+      it 'should not save if the object is not valid for the default context' do
+        @yacht.name = 'a'
+        @yacht.should be_valid
+
+        @yacht.name = nil
+        @yacht.should_not be_valid
+        @yacht.save.should be_false
+        @yacht.should be_new_record
+      end
+    end
+
+    describe 'with context specified' do
+      before :all do
+        class Yacht
+          validates_length :name, :min =&gt; 2, :context =&gt; [ :strict_name ]
+        end
+      end
+
+      it 'should validate using the specified context' do
+        @yacht.should_receive(:valid?).with(:strict_name)
+        @yacht.save(:strict_name)
+      end
+
+      it 'should save if the object is valid for the specified context' do
+        @yacht.should be_valid(:strict_name)
+        @yacht.save(:strict_name).should be_true
+        @yacht.should_not be_new_record
+      end
+
+      it 'should not save if the object is not valid for the specified context' do
+        @yacht.name = 'aa'
+        @yacht.should be_valid(:strict_name)
+
+        @yacht.name = 'a'
+        @yacht.should_not be_valid(:strict_name)
+        @yacht.save(:strict_name).should be_false
+        @yacht.should be_new_record
+      end
+    end
+  end
+
   it &quot;should respond to validatable? (for recursing assocations)&quot; do
     Yacht.new.should be_validatable
     Class.new.new.should_not be_validatable
@@ -30,17 +93,16 @@ describe DataMapper::Validate do
     Yacht.validators.should respond_to(:execute)
   end
 
-  it &quot;should place a validator in the :default context if a named context is
-      not provided&quot; do
+  it &quot;should place a validator in the :default context if a named context is not provided&quot; do
     Yacht.validators.context(:default).length.should == 2
   end
 
-
   it &quot;should allow multiple user defined contexts for a validator&quot; do
     class Yacht
       property :port, String, :auto_validation =&gt; false
       validates_present :port, :context =&gt; [:at_sea, :in_harbor]
     end
+
     Yacht.validators.context(:at_sea).length.should == 1
     Yacht.validators.context(:in_harbor).length.should == 1
     Yacht.validators.context(:no_such_context).length.should == 0
@@ -115,83 +177,94 @@ describe DataMapper::Validate do
     sea.errors.full_messages.first.should == 'Year built is a must enter field'
   end
 
-  it &quot;should execute a Proc when provided in an :if clause and run validation
-      if the Proc returns true&quot; do
+  it &quot;should execute a Proc when provided in an :if clause and run validation if the Proc returns true&quot; do
     class Dingy
       include DataMapper::Resource
       property :id, Integer, :serial =&gt; true
       property :owner, String, :auto_validation =&gt; false
       validates_present :owner, :if =&gt; Proc.new{|resource| resource.owned?}
-      def owned?; false; end
+
+      def owned?
+        false
+      end
     end
 
     Dingy.new.valid?.should == true
 
     class Dingy
-      def owned?; true; end
+      def owned?
+        true
+      end
     end
 
     Dingy.new.valid?.should_not == true
   end
 
-  it &quot;should execute a symbol or method name provided in an :if clause and run
-      validation if the method returns true&quot; do
+  it &quot;should execute a symbol or method name provided in an :if clause and run validation if the method returns true&quot; do
     class Dingy
       validators.clear!
       validates_present :owner, :if =&gt; :owned?
 
-      def owned?; false; end
+      def owned?
+        false
+      end
     end
 
     Dingy.new.valid?.should == true
 
     class Dingy
-      def owned?; true; end
+      def owned?
+        true
+      end
     end
 
     Dingy.new.valid?.should_not == true
   end
 
-  it &quot;should execute a Proc when provided in an :unless clause and not run
-      validation if the Proc returns true&quot; do
+  it &quot;should execute a Proc when provided in an :unless clause and not run validation if the Proc returns true&quot; do
     class RowBoat
       include DataMapper::Resource
       property :id, Integer, :serial =&gt; true
       validates_present :salesman, :unless =&gt; Proc.new{|resource| resource.sold?}
 
-      def sold?; false; end
+      def sold?
+        false
+      end
     end
 
     RowBoat.new.valid?.should_not == true
 
     class RowBoat
-      def sold?; true; end
+      def sold?
+        true
+      end
     end
 
     RowBoat.new.valid?.should == true
   end
 
-  it &quot;should execute a symbol or method name provided in an :unless clause and
-      not run validation if the method returns true&quot; do
+  it &quot;should execute a symbol or method name provided in an :unless clause and not run validation if the method returns true&quot; do
     class Dingy
       validators.clear!
       validates_present :salesman, :unless =&gt; :sold?
 
-      def sold?; false; end
+      def sold?
+        false
+      end
     end
 
     Dingy.new.valid?.should_not == true  #not sold and no salesman
 
     class Dingy
-      def sold?; true; end
+      def sold?
+        true
+      end
     end
 
     Dingy.new.valid?.should == true    # sold and no salesman
   end
 
-
-  it &quot;should perform automatic recursive validation #all_valid? checking all
-      instance variables (and ivar.each items if valid)&quot; do
+  it &quot;should perform automatic recursive validation #all_valid? checking all instance variables (and ivar.each items if valid)&quot; do
     class Invoice
       include DataMapper::Resource
       property :id, Integer, :serial =&gt; true
@@ -249,6 +322,5 @@ describe DataMapper::Validate do
     invoice.line_items[1].price = '23.44'
 
     invoice.all_valid?.should == true
-
   end
 end</diff>
      <filename>dm-validations/spec/integration/validation_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>378929eef072c085e3bb81a64d33ade6dff8d530</id>
    </parent>
  </parents>
  <author>
    <name>Dan Kubb</name>
    <email>dan.kubb@autopilotmarketing.com</email>
  </author>
  <url>http://github.com/sam/dm-more/commit/69b9df09621058677f80095d365d4c16f9c247bd</url>
  <id>69b9df09621058677f80095d365d4c16f9c247bd</id>
  <committed-date>2008-05-24T22:29:10-07:00</committed-date>
  <authored-date>2008-05-24T22:29:10-07:00</authored-date>
  <message>Added automatic validations on save

* An optional context argument can be passed into Resource#save that
  will determine which context the object is validated with prior to
  saving.  The context defaults to :default.</message>
  <tree>f6c9fe8f58fdfe12916409a6285adb39a59ea511</tree>
  <committer>
    <name>Dan Kubb</name>
    <email>dan.kubb@autopilotmarketing.com</email>
  </committer>
</commit>
