Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Completed support for :allow_blank property option and enabled suppor…

…t to ignore blank values in associations. This is especially useful for html forms that provide empty values
  • Loading branch information...
commit f7e2f5fa0646006864205186fa3517c80b5bb1e8 1 parent fbfdc0d
@samlown samlown authored
View
1  couchrest_model.gemspec
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
s.add_development_dependency(%q<json>, ["~> 1.5.1"])
s.add_development_dependency(%q<rack-test>, ">= 0.5.7")
s.add_development_dependency("rake", ">= 0.8.0")
+ s.add_development_dependency("debugger", "~> 1.2.0")
# s.add_development_dependency("jruby-openssl", ">= 0.7.3")
end
View
13 lib/couchrest/model/associations.rb
@@ -38,7 +38,7 @@ module ClassMethods
def belongs_to(attrib, *options)
opts = merge_belongs_to_association_options(attrib, options.first)
- property(opts[:foreign_key], opts)
+ property(opts[:foreign_key], String, opts)
create_belongs_to_getter(attrib, opts)
create_belongs_to_setter(attrib, opts)
@@ -88,7 +88,7 @@ def collection_of(attrib, *options)
opts[:foreign_key] = opts[:foreign_key].pluralize
opts[:readonly] = true
- property(opts[:foreign_key], [], opts)
+ property(opts[:foreign_key], [String], opts)
create_collection_of_property_setter(attrib, opts)
create_collection_of_getter(attrib, opts)
@@ -225,6 +225,15 @@ def check_obj(obj)
raise "Object cannot be added to #{casted_by.class.to_s}##{casted_by_property.to_s} collection unless saved" if obj.new?
end
+ # Override CastedArray instantiation_and_cast method for a simpler
+ # version that will not try to cast the model.
+ def instantiate_and_cast(obj, change = true)
+ couchrest_parent_will_change! if change && use_dirty?
+ obj.casted_by = casted_by if obj.respond_to?(:casted_by)
+ obj.casted_by_property = casted_by_property if obj.respond_to?(:casted_by_property)
+ obj
+ end
+
end
end
View
2  lib/couchrest/model/properties.rb
@@ -40,7 +40,7 @@ def read_attribute(property)
# with a property and update dirty status
def write_attribute(property, value)
prop = find_property!(property)
- value = prop.is_a?(String) ? value : prop.cast(self, value)
+ value = prop.cast(self, value)
couchrest_attribute_will_change!(prop.name) if use_dirty? && self[prop.name] != value
self[prop.name] = value
end
View
9 lib/couchrest/model/property.rb
@@ -33,6 +33,7 @@ def cast(parent, value)
raise "Expecting an array or keyed hash for property #{parent.class.name}##{self.name}"
end
arr = value.collect { |data| cast_value(parent, data) }
+ arr.reject!{ |data| data.nil? } unless allow_blank
# allow casted_by calls to be passed up chain by wrapping in CastedArray
CastedArray.new(arr, self, parent)
elsif (type == Object || type == Hash) && (value.is_a?(Hash))
@@ -45,8 +46,12 @@ def cast(parent, value)
# Cast an individual value
def cast_value(parent, value)
- value = typecast_value(parent, self, value)
- associate_casted_value_to_parent(parent, value)
+ if !allow_blank && value.to_s.empty?
+ nil
+ else
+ value = typecast_value(parent, self, value)
+ associate_casted_value_to_parent(parent, value)
+ end
end
def default_value
View
2  lib/couchrest/model/typecast.rb
@@ -3,7 +3,7 @@ module Model
module Typecast
def typecast_value(parent, property, value)
- return nil if value.nil? || (!property.allow_blank && value.to_s.empty?)
+ return nil if value.nil?
klass = property.type_class
if value.instance_of?(klass) || klass == Object
if klass == Time && !value.utc?
View
10 spec/unit/assocations_spec.rb
@@ -70,6 +70,11 @@ def SaleInvoice.merge_assoc_opts(*args)
@invoice.client
end
+ it "should ignore blank ids" do
+ @invoice.client_id = ""
+ @invoice.client_id.should be_nil
+ end
+
it "should allow override of foreign key" do
@invoice.respond_to?(:alternate_client).should be_true
@invoice.respond_to?("alternate_client=").should be_true
@@ -116,6 +121,11 @@ def SaleInvoice.merge_assoc_opts(*args)
@invoice.entries.first.should eql(@entries.first)
end
+ it "should ignore blank ids when set directly" do
+ @invoice.entry_ids = ["", @entries.first.id]
+ @invoice.entry_ids.length.should be(1)
+ end
+
it "should replace collection if ids replaced" do
@invoice.entry_ids = @entries.collect{|i| i.id}
@invoice.entries.length.should eql(3) # load once
View
19 spec/unit/property_spec.rb
@@ -328,7 +328,6 @@
@course.questions.last.class.should eql(Question)
end
-
it "should raise an error if attempting to set single value for array type" do
lambda {
@course.questions = Question.new(:q => 'test1')
@@ -433,7 +432,7 @@
property.allow_blank.should be_true
end
- it "should allow setting of the allow_blank option to false" do
+ it "should allow setting of the allow_blank option to false" do
property = CouchRest::Model::Property.new(:test, String, :allow_blank => false)
property.allow_blank.should be_false
end
@@ -476,6 +475,22 @@
property.cast(parent, ["2010-06-01", "2010-06-02"]).should eql([Date.new(2010, 6, 1), Date.new(2010, 6, 2)])
end
+ context "when allow_blank is false" do
+ let :parent do
+ mock("FooObject")
+ end
+
+ it "should convert blank to nil" do
+ property = CouchRest::Model::Property.new(:test, String, :allow_blank => false)
+ property.cast(parent, "").should be_nil
+ end
+
+ it "should remove blank array entries" do
+ property = CouchRest::Model::Property.new(:test, [String], :allow_blank => false)
+ property.cast(parent, ["", "foo"]).should eql(["foo"])
+ end
+ end
+
it "should set a CastedArray on array of Objects" do
property = CouchRest::Model::Property.new(:test, [Object])
parent = mock("FooObject")
Please sign in to comment.
Something went wrong with that request. Please try again.