From b4e2250668f6124fdd0040a921e1524bbf1324c5 Mon Sep 17 00:00:00 2001 From: Peter Gumeson Date: Thu, 4 Jun 2009 19:49:10 -0700 Subject: [PATCH] Added validation callbacks to extended documents and casted models --- README.md | 9 ++++-- lib/couchrest/mixins/validation.rb | 8 ++++- lib/couchrest/more/casted_model.rb | 1 + spec/couchrest/more/casted_model_spec.rb | 41 ++++++++++++++++++++++++ spec/couchrest/more/extended_doc_spec.rb | 22 +++++++++++++ 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2e6f9bf..b9ed345 100644 --- a/README.md +++ b/README.md @@ -68,10 +68,13 @@ CouchRest::Model has been deprecated and replaced by CouchRest::ExtendedDocument ### Callbacks -`CouchRest::ExtendedDocuments` instances have 2 callbacks already defined for you: - `create_callback`, `save_callback`, `update_callback` and `destroy_callback` +`CouchRest::ExtendedDocuments` instances have 4 callbacks already defined for you: + `validate_callback`, `create_callback`, `save_callback`, `update_callback` and `destroy_callback` -In your document inherits from `CouchRest::ExtendedDocument`, define your callback as follows: +`CouchRest::CastedModel` instances have 1 callback already defined for you: + `validate_callback` + +Define your callback as follows: save_callback :before, :generate_slug_from_name diff --git a/lib/couchrest/mixins/validation.rb b/lib/couchrest/mixins/validation.rb index dda708e..467e143 100644 --- a/lib/couchrest/mixins/validation.rb +++ b/lib/couchrest/mixins/validation.rb @@ -51,6 +51,9 @@ module CouchRest def self.included(base) base.extlib_inheritable_accessor(:auto_validation) base.class_eval <<-EOS, __FILE__, __LINE__ + # Callbacks + define_callbacks :validate + # Turn off auto validation by default self.auto_validation ||= false @@ -72,6 +75,7 @@ module CouchRest base.extend(ClassMethods) base.class_eval <<-EOS, __FILE__, __LINE__ + define_callbacks :validate if method_defined?(:_run_save_callbacks) save_callback :before, :check_validations end @@ -147,7 +151,9 @@ module CouchRest valid = recursive_valid?(prop, context, valid) && valid end end - target.class.validators.execute(context, target) && valid + target._run_validate_callbacks do + target.class.validators.execute(context, target) && valid + end end diff --git a/lib/couchrest/more/casted_model.rb b/lib/couchrest/more/casted_model.rb index e2c5522..25e9031 100644 --- a/lib/couchrest/more/casted_model.rb +++ b/lib/couchrest/more/casted_model.rb @@ -4,6 +4,7 @@ module CouchRest module CastedModel def self.included(base) + base.send(:include, CouchRest::Callbacks) base.send(:include, CouchRest::Mixins::Properties) base.send(:attr_accessor, :casted_by) base.send(:attr_accessor, :document_saved) diff --git a/spec/couchrest/more/casted_model_spec.rb b/spec/couchrest/more/casted_model_spec.rb index 9a22fee..678c81f 100644 --- a/spec/couchrest/more/casted_model_spec.rb +++ b/spec/couchrest/more/casted_model_spec.rb @@ -23,6 +23,26 @@ class DummyModel < CouchRest::ExtendedDocument property :keywords, :cast_as => ["String"] end +class CastedCallbackDoc < CouchRest::ExtendedDocument + use_database TEST_SERVER.default_database + raise "Default DB not set" if TEST_SERVER.default_database.nil? + property :callback_model, :cast_as => 'WithCastedCallBackModel' +end +class WithCastedCallBackModel < Hash + include CouchRest::CastedModel + include CouchRest::Validation + property :name + property :run_before_validate + property :run_after_validate + + validate_callback :before do |object| + object.run_before_validate = true + end + validate_callback :after do |object| + object.run_after_validate = true + end +end + describe CouchRest::CastedModel do describe "A non hash class including CastedModel" do @@ -354,4 +374,25 @@ describe CouchRest::CastedModel do lambda{@toy.base_doc.save!}.should_not raise_error end end + + describe "callbacks" do + before(:each) do + @doc = CastedCallbackDoc.new + @model = WithCastedCallBackModel.new + @doc.callback_model = @model + end + + describe "validate" do + it "should run before_validate before validating" do + @model.run_before_validate.should be_nil + @model.should be_valid + @model.run_before_validate.should be_true + end + it "should run after_validate after validating" do + @model.run_after_validate.should be_nil + @model.should be_valid + @model.run_after_validate.should be_true + end + end + end end diff --git a/spec/couchrest/more/extended_doc_spec.rb b/spec/couchrest/more/extended_doc_spec.rb index dcec051..dd02a91 100644 --- a/spec/couchrest/more/extended_doc_spec.rb +++ b/spec/couchrest/more/extended_doc_spec.rb @@ -17,8 +17,11 @@ describe "ExtendedDocument" do end class WithCallBacks < CouchRest::ExtendedDocument + include ::CouchRest::Validation use_database TEST_SERVER.default_database property :name + property :run_before_validate + property :run_after_validate property :run_before_save property :run_after_save property :run_before_create @@ -26,6 +29,12 @@ describe "ExtendedDocument" do property :run_before_update property :run_after_update + validate_callback :before do |object| + object.run_before_validate = true + end + validate_callback :after do |object| + object.run_after_validate = true + end save_callback :before do |object| object.run_before_save = true end @@ -504,6 +513,19 @@ describe "ExtendedDocument" do @doc = WithCallBacks.new end + + describe "validate" do + it "should run before_validate before validating" do + @doc.run_before_validate.should be_nil + @doc.should be_valid + @doc.run_before_validate.should be_true + end + it "should run after_validate after validating" do + @doc.run_after_validate.should be_nil + @doc.should be_valid + @doc.run_after_validate.should be_true + end + end describe "save" do it "should run the after filter after saving" do @doc.run_after_save.should be_nil