Adding property build support to enable CastedArray#build

This commit is contained in:
Sam Lown 2011-05-21 14:16:39 +02:00
parent d56179aa6b
commit fcd9e2ba8e
5 changed files with 57 additions and 3 deletions

View file

@ -2,9 +2,12 @@
## 1.1.0 - 2011-05-XX ## 1.1.0 - 2011-05-XX
* New Features
* Properties with a nil value are now no longer sent to the database.
* Now possible to build new objects via CastedArray#build
* Minor fixes * Minor fixes
* #as_json now correctly uses ActiveSupports methods. * #as_json now correctly uses ActiveSupports methods.
* nil properties are now no longer sent in the document body.
* Rails 3.1 support (Peter Williams) * Rails 3.1 support (Peter Williams)
* Initialization blocks when creating new models (Peter Williams) * Initialization blocks when creating new models (Peter Williams)
* Removed railties dependency (DAddYE) * Removed railties dependency (DAddYE)

View file

@ -50,6 +50,12 @@ module CouchRest::Model
super super
end end
def build(*args)
obj = casted_by_property.build(*args)
self.push(obj)
obj
end
protected protected
def instantiate_and_cast(obj, change = true) def instantiate_and_cast(obj, change = true)

View file

@ -64,6 +64,18 @@ module CouchRest::Model
end end
end end
# Initialize a new instance of a property's type ready to be
# used. If a proc is defined for the init method, it will be used instead of
# a normal call to the class.
def build(*args)
raise StandardError, "Cannot build property without a class" if @type_class.nil?
if @init_method.is_a?(Proc)
@init_method.call(*args)
else
@type_class.send(@init_method, *args)
end
end
private private
def associate_casted_value_to_parent(parent, value) def associate_casted_value_to_parent(parent, value)

View file

@ -14,8 +14,7 @@ module CouchRest
elsif [String, TrueClass, Integer, Float, BigDecimal, DateTime, Time, Date, Class].include?(klass) elsif [String, TrueClass, Integer, Float, BigDecimal, DateTime, Time, Date, Class].include?(klass)
send('typecast_to_'+klass.to_s.downcase, value) send('typecast_to_'+klass.to_s.downcase, value)
else else
# Allow the init_method to be defined as a Proc for advanced conversion property.build(value)
property.init_method.is_a?(Proc) ? property.init_method.call(value) : klass.send(property.init_method, value)
end end
end end

View file

@ -358,6 +358,28 @@ describe "Property Class" do
property.init_method.should eql('parse') property.init_method.should eql('parse')
end end
describe "#build" do
it "should allow instantiation of new object" do
property = CouchRest::Model::Property.new(:test, Date)
obj = property.build(2011, 05, 21)
obj.should eql(Date.new(2011, 05, 21))
end
it "should use init_method if provided" do
property = CouchRest::Model::Property.new(:test, Date, :init_method => 'parse')
obj = property.build("2011-05-21")
obj.should eql(Date.new(2011, 05, 21))
end
it "should use init_method Proc if provided" do
property = CouchRest::Model::Property.new(:test, Date, :init_method => Proc.new{|v| Date.parse(v)})
obj = property.build("2011-05-21")
obj.should eql(Date.new(2011, 05, 21))
end
it "should raise error if no class" do
property = CouchRest::Model::Property.new(:test)
lambda { property.build }.should raise_error(StandardError, /Cannot build/)
end
end
## Property Casting method. More thoroughly tested in typecast_spec. ## Property Casting method. More thoroughly tested in typecast_spec.
describe "casting" do describe "casting" do
@ -386,6 +408,18 @@ describe "Property Class" do
property.cast(parent, ["2010-06-01", "2010-06-02"]).class.should eql(CouchRest::Model::CastedArray) property.cast(parent, ["2010-06-01", "2010-06-02"]).class.should eql(CouchRest::Model::CastedArray)
end end
it "should allow instantion of model via CastedArray#build" do
property = CouchRest::Model::Property.new(:dates, [Date])
parent = Article.new
ary = property.cast(parent, [])
obj = ary.build(2011, 05, 21)
ary.length.should eql(1)
ary.first.should eql(Date.new(2011, 05, 21))
obj = ary.build(2011, 05, 22)
ary.length.should eql(2)
ary.last.should eql(Date.new(2011, 05, 22))
end
it "should raise and error if value is array when type is not" do it "should raise and error if value is array when type is not" do
property = CouchRest::Model::Property.new(:test, Date) property = CouchRest::Model::Property.new(:test, Date)
parent = mock("FooClass") parent = mock("FooClass")