fixed some serious issues but left some for tomorrow (validations aren't working right)
This commit is contained in:
parent
bc47e72ae0
commit
e448112ff6
|
@ -48,6 +48,19 @@ module CouchRest
|
||||||
module Validation
|
module Validation
|
||||||
|
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
|
base.cattr_accessor(:auto_validation)
|
||||||
|
base.class_eval <<-EOS, __FILE__, __LINE__
|
||||||
|
# Turn off auto validation by default
|
||||||
|
@@auto_validation = false
|
||||||
|
|
||||||
|
# Force the auto validation for the class properties
|
||||||
|
# This feature is still not fully ported over,
|
||||||
|
# test are lacking, so please use with caution
|
||||||
|
def self.auto_validate!
|
||||||
|
self.auto_validation = true
|
||||||
|
end
|
||||||
|
EOS
|
||||||
|
|
||||||
base.extend(ClassMethods)
|
base.extend(ClassMethods)
|
||||||
base.class_eval <<-EOS, __FILE__, __LINE__
|
base.class_eval <<-EOS, __FILE__, __LINE__
|
||||||
if method_defined?(:_run_save_callbacks)
|
if method_defined?(:_run_save_callbacks)
|
||||||
|
@ -164,7 +177,7 @@ module CouchRest
|
||||||
context = opts.delete(:when) if opts.has_key?(:when)
|
context = opts.delete(:when) if opts.has_key?(:when)
|
||||||
context = opts.delete(:group) if opts.has_key?(:group)
|
context = opts.delete(:group) if opts.has_key?(:group)
|
||||||
opts[:context] = context
|
opts[:context] = context
|
||||||
opts.mergs!(defaults) unless defaults.nil?
|
opts.merge!(defaults) unless defaults.nil?
|
||||||
opts
|
opts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -197,7 +210,7 @@ module CouchRest
|
||||||
#
|
#
|
||||||
def add_validator_to_context(opts, fields, klazz)
|
def add_validator_to_context(opts, fields, klazz)
|
||||||
fields.each do |field|
|
fields.each do |field|
|
||||||
validator = klazz.new(field, opts)
|
validator = klazz.new(field.to_sym, opts)
|
||||||
if opts[:context].is_a?(Symbol)
|
if opts[:context].is_a?(Symbol)
|
||||||
unless validators.context(opts[:context]).include?(validator)
|
unless validators.context(opts[:context]).include?(validator)
|
||||||
validators.context(opts[:context]) << validator
|
validators.context(opts[:context]) << validator
|
||||||
|
|
|
@ -14,11 +14,14 @@ module CouchRest
|
||||||
# Same as CouchRest::Document but with properties and validations
|
# Same as CouchRest::Document but with properties and validations
|
||||||
class ExtendedDocument < Document
|
class ExtendedDocument < Document
|
||||||
include CouchRest::Callbacks
|
include CouchRest::Callbacks
|
||||||
include CouchRest::Mixins::DocumentQueries
|
include CouchRest::Mixins::DocumentQueries
|
||||||
include CouchRest::Mixins::Properties
|
|
||||||
include CouchRest::Mixins::Views
|
include CouchRest::Mixins::Views
|
||||||
include CouchRest::Mixins::DesignDoc
|
include CouchRest::Mixins::DesignDoc
|
||||||
|
|
||||||
|
def self.inherited(subklass)
|
||||||
|
subklass.send(:include, CouchRest::Mixins::Properties)
|
||||||
|
end
|
||||||
|
|
||||||
# Callbacks
|
# Callbacks
|
||||||
define_callbacks :save
|
define_callbacks :save
|
||||||
define_callbacks :destroy
|
define_callbacks :destroy
|
||||||
|
@ -38,8 +41,8 @@ module CouchRest
|
||||||
# decent time format by default. See Time#to_json
|
# decent time format by default. See Time#to_json
|
||||||
def self.timestamps!
|
def self.timestamps!
|
||||||
class_eval <<-EOS, __FILE__, __LINE__
|
class_eval <<-EOS, __FILE__, __LINE__
|
||||||
property(:updated_at, :read_only => true, :cast_as => 'Time')
|
property(:updated_at, :read_only => true, :cast_as => 'Time', :auto_validation => false)
|
||||||
property(:created_at, :read_only => true, :cast_as => 'Time')
|
property(:created_at, :read_only => true, :cast_as => 'Time', :auto_validation => false)
|
||||||
|
|
||||||
save_callback :before do |object|
|
save_callback :before do |object|
|
||||||
object['updated_at'] = Time.now
|
object['updated_at'] = Time.now
|
||||||
|
@ -115,7 +118,7 @@ module CouchRest
|
||||||
# Overridden to set the unique ID.
|
# Overridden to set the unique ID.
|
||||||
# Returns a boolean value
|
# Returns a boolean value
|
||||||
def save_without_callbacks(bulk = false)
|
def save_without_callbacks(bulk = false)
|
||||||
raise ArgumentError, "a document requires database to be saved to" unless database
|
raise ArgumentError, "a document requires a database to be saved to" unless database
|
||||||
set_unique_id if new_document? && self.respond_to?(:set_unique_id)
|
set_unique_id if new_document? && self.respond_to?(:set_unique_id)
|
||||||
result = database.save_doc(self, bulk)
|
result = database.save_doc(self, bulk)
|
||||||
result["ok"] == true
|
result["ok"] == true
|
||||||
|
|
|
@ -6,22 +6,20 @@ module CouchRest
|
||||||
class Property
|
class Property
|
||||||
# flag letting us know if we already checked the autovalidation settings
|
# flag letting us know if we already checked the autovalidation settings
|
||||||
attr_accessor :autovalidation_check
|
attr_accessor :autovalidation_check
|
||||||
|
@@autovalidation_check = false
|
||||||
end
|
end
|
||||||
|
|
||||||
module Validation
|
module Validation
|
||||||
module AutoValidate
|
module AutoValidate
|
||||||
|
|
||||||
# Turn off auto validation by default
|
# # Force the auto validation for the class properties
|
||||||
def auto_validation
|
# # This feature is still not fully ported over,
|
||||||
@@auto_validation ||= false
|
# # test are lacking, so please use with caution
|
||||||
end
|
# def auto_validate!
|
||||||
|
# require 'ruby-debug'
|
||||||
# Force the auto validation for the class properties
|
# debugger
|
||||||
# This feature is still not fully ported over,
|
# auto_validation = true
|
||||||
# test are lacking, so please use with caution
|
# end
|
||||||
def auto_validate!
|
|
||||||
@@auto_validation = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# adds message for validator
|
# adds message for validator
|
||||||
def options_with_message(base_options, property, validator_name)
|
def options_with_message(base_options, property, validator_name)
|
||||||
|
@ -93,9 +91,7 @@ module CouchRest
|
||||||
# It is just shortcut if only one validation option is set
|
# It is just shortcut if only one validation option is set
|
||||||
#
|
#
|
||||||
def auto_generate_validations(property)
|
def auto_generate_validations(property)
|
||||||
return unless property.options
|
return unless (property.autovalidation_check && self.auto_validation && (property.options && property.options.has_key?(:auto_validation) && property.options[:auto_validation]))
|
||||||
return unless property.autovalidation_check || auto_validation || (property.options && property.options.has_key?(:auto_validation) && property.options[:auto_validation])
|
|
||||||
|
|
||||||
# value is set by the storage system
|
# value is set by the storage system
|
||||||
opts = {}
|
opts = {}
|
||||||
opts[:context] = property.options[:validates] if property.options.has_key?(:validates)
|
opts[:context] = property.options[:validates] if property.options.has_key?(:validates)
|
||||||
|
|
|
@ -40,7 +40,7 @@ module CouchRest
|
||||||
value = target.send(field_name)
|
value = target.send(field_name)
|
||||||
return true if @options[:allow_nil] && value.nil?
|
return true if @options[:allow_nil] && value.nil?
|
||||||
|
|
||||||
value = value.kind_of?(BigDecimal) ? value.to_s('F') : value.to_s
|
value = value.kind_of?(Float) ? value.to_s('F') : value.to_s
|
||||||
|
|
||||||
error_message = @options[:message]
|
error_message = @options[:message]
|
||||||
precision = @options[:precision]
|
precision = @options[:precision]
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
||||||
require File.join(FIXTURE_PATH, 'more', 'card')
|
require File.join(FIXTURE_PATH, 'more', 'card')
|
||||||
|
|
||||||
|
class WithCastedModelMixin < Hash
|
||||||
|
include CouchRest::CastedModel
|
||||||
|
property :name
|
||||||
|
end
|
||||||
|
|
||||||
|
class DummyModel < CouchRest::ExtendedDocument
|
||||||
|
use_database TEST_SERVER.default_database
|
||||||
|
raise "Default DB not set" if TEST_SERVER.default_database.nil?
|
||||||
|
property :casted_attribute, :cast_as => 'WithCastedModelMixin'
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
describe CouchRest::CastedModel do
|
describe CouchRest::CastedModel do
|
||||||
|
|
||||||
class WithCastedModelMixin < Hash
|
|
||||||
include CouchRest::CastedModel
|
|
||||||
property :name
|
|
||||||
end
|
|
||||||
|
|
||||||
class DummyModel < CouchRest::ExtendedDocument
|
|
||||||
property :casted_attribute, :cast_as => 'WithCastedModelMixin'
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "A non hash class including CastedModel" do
|
describe "A non hash class including CastedModel" do
|
||||||
|
|
||||||
it "should fail raising and include error" do
|
it "should fail raising and include error" do
|
||||||
lambda do
|
lambda do
|
||||||
class NotAHashButWithCastedModelMixin
|
class NotAHashButWithCastedModelMixin
|
||||||
|
@ -23,7 +25,6 @@ describe CouchRest::CastedModel do
|
||||||
|
|
||||||
end.should raise_error
|
end.should raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "isolated" do
|
describe "isolated" do
|
||||||
|
@ -37,7 +38,6 @@ describe CouchRest::CastedModel do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "casted as attribute" do
|
describe "casted as attribute" do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
|
@obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
|
||||||
@casted_obj = @obj.casted_attribute
|
@casted_obj = @obj.casted_attribute
|
||||||
|
@ -54,6 +54,30 @@ describe CouchRest::CastedModel do
|
||||||
it "should know who casted it" do
|
it "should know who casted it" do
|
||||||
@casted_obj.casted_by.should == @obj
|
@casted_obj.casted_by.should == @obj
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "saved document with casted models" do
|
||||||
|
before(:each) do
|
||||||
|
@obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
|
||||||
|
@obj.save
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be able to load with the casted models" do
|
||||||
|
casted_obj = @obj.casted_attribute
|
||||||
|
casted_obj.should_not be_nil
|
||||||
|
casted_obj.should be_an_instance_of(WithCastedModelMixin)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should have defined getters for the casted model" do
|
||||||
|
casted_obj = @obj.casted_attribute
|
||||||
|
casted_obj.name.should == "whatever"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should have defined setters for the casted model" do
|
||||||
|
casted_obj = @obj.casted_attribute
|
||||||
|
casted_obj.name = "test"
|
||||||
|
casted_obj.name.should == "test"
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||||
|
|
||||||
class WithDefaultValues < CouchRest::ExtendedDocument
|
|
||||||
use_database TEST_SERVER.default_database
|
|
||||||
property :preset, :default => {:right => 10, :top_align => false}
|
|
||||||
property :set_by_proc, :default => Proc.new{Time.now}, :cast_as => 'Time'
|
|
||||||
property :name
|
|
||||||
timestamps!
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "ExtendedDocument" do
|
describe "ExtendedDocument" do
|
||||||
|
|
||||||
|
class WithDefaultValues < CouchRest::ExtendedDocument
|
||||||
|
use_database TEST_SERVER.default_database
|
||||||
|
property :preset, :default => {:right => 10, :top_align => false}
|
||||||
|
property :set_by_proc, :default => Proc.new{Time.now}, :cast_as => 'Time'
|
||||||
|
property :name
|
||||||
|
timestamps!
|
||||||
|
end
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@obj = WithDefaultValues.new
|
@obj = WithDefaultValues.new
|
||||||
end
|
end
|
||||||
|
@ -32,6 +32,7 @@ describe "ExtendedDocument" do
|
||||||
it "should define the updated_at and created_at getters and set the values" do
|
it "should define the updated_at and created_at getters and set the values" do
|
||||||
@obj.save
|
@obj.save
|
||||||
obj = WithDefaultValues.get(@obj.id)
|
obj = WithDefaultValues.get(@obj.id)
|
||||||
|
obj.should be_an_instance_of(WithDefaultValues)
|
||||||
obj.created_at.should be_an_instance_of(Time)
|
obj.created_at.should be_an_instance_of(Time)
|
||||||
obj.updated_at.should be_an_instance_of(Time)
|
obj.updated_at.should be_an_instance_of(Time)
|
||||||
obj.created_at.to_s.should == @obj.updated_at.to_s
|
obj.created_at.to_s.should == @obj.updated_at.to_s
|
||||||
|
|
|
@ -39,7 +39,8 @@ describe "ExtendedDocument properties" do
|
||||||
@card.updated_at.should be_nil
|
@card.updated_at.should be_nil
|
||||||
# :emo: hack for autospec
|
# :emo: hack for autospec
|
||||||
Card.use_database(TEST_SERVER.default_database) if @card.database.nil?
|
Card.use_database(TEST_SERVER.default_database) if @card.database.nil?
|
||||||
@card.save
|
@card.save #.should be_true
|
||||||
|
p @card.errors
|
||||||
@card.created_at.should_not be_nil
|
@card.created_at.should_not be_nil
|
||||||
@card.updated_at.should_not be_nil
|
@card.updated_at.should_not be_nil
|
||||||
end
|
end
|
||||||
|
@ -65,14 +66,17 @@ describe "ExtendedDocument properties" do
|
||||||
@invoice.clear
|
@invoice.clear
|
||||||
@invoice.should_not be_valid
|
@invoice.should_not be_valid
|
||||||
@invoice.errors.should_not be_empty
|
@invoice.errors.should_not be_empty
|
||||||
@invoice.errors.on(:client_name).should == ["Client name must not be blank"]
|
@invoice.errors.on(:client_name).first.should == "Client name must not be blank"
|
||||||
@invoice.errors.on(:employee_name).should_not be_empty
|
@invoice.errors.on(:employee_name).should_not be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should let you set an error message" do
|
it "should let you set an error message" do
|
||||||
@invoice.location = nil
|
@invoice.location = nil
|
||||||
@invoice.valid?
|
@invoice.valid?
|
||||||
@invoice.errors.on(:location).first.should == "Hey stupid!, you forgot the location"
|
# require 'ruby-debug'
|
||||||
|
# debugger
|
||||||
|
# p @invoice.class.validators.map{|v| v.message}.inspect
|
||||||
|
@invoice.errors.on(:location).should == ["Hey stupid!, you forgot the location"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should validate before saving" do
|
it "should validate before saving" do
|
||||||
|
|
4
spec/fixtures/more/card.rb
vendored
4
spec/fixtures/more/card.rb
vendored
|
@ -1,6 +1,8 @@
|
||||||
class Card < CouchRest::ExtendedDocument
|
class Card < CouchRest::ExtendedDocument
|
||||||
# Include the validation module to get access to the validation methods
|
# Include the validation module to get access to the validation methods
|
||||||
include CouchRest::Validation
|
include CouchRest::Validation
|
||||||
|
# set the auto_validation before defining the properties
|
||||||
|
auto_validate!
|
||||||
|
|
||||||
# Set the default database to use
|
# Set the default database to use
|
||||||
use_database TEST_SERVER.default_database
|
use_database TEST_SERVER.default_database
|
||||||
|
@ -15,6 +17,4 @@ class Card < CouchRest::ExtendedDocument
|
||||||
# Validation
|
# Validation
|
||||||
validates_present :first_name
|
validates_present :first_name
|
||||||
|
|
||||||
auto_validate!
|
|
||||||
|
|
||||||
end
|
end
|
Loading…
Reference in a new issue