Skip to content
Browse files

Adding support for defining cast_as on properties as a Class

  • Loading branch information...
1 parent 64d68ec commit dd3df8fb69cf0a0e12290bd8571889abc2e176b7 Sam Lown committed Mar 30, 2010
View
2 lib/couchrest.rb
@@ -156,4 +156,4 @@ def paramify_url url, params = {}
url
end
end # class << self
-end
+end
View
12 lib/couchrest/mixins/properties.rb
@@ -50,24 +50,18 @@ def cast_property(property, assigned=false)
# Don't cast the property unless it has a value
return unless self[key]
if property.type.is_a?(Array)
- klass = ::CouchRest.constantize(property.type[0])
+ klass = property.type[0]
self[key] = [self[key]] unless self[key].is_a?(Array)
arr = self[key].collect do |value|
value = typecast_value(value, klass, property.init_method)
associate_casted_to_parent(value, assigned)
value
end
- # only cast arrays of more complex objects (i.e. not strings)
+ # allow casted_by calls to be passed up chain by wrapping in CastedArray
self[key] = klass != String ? CastedArray.new(arr) : arr
self[key].casted_by = self if self[key].respond_to?(:casted_by)
else
- if property.type.downcase == 'boolean'
- klass = TrueClass
- else
- klass = ::CouchRest.constantize(property.type)
- end
-
- self[key] = typecast_value(self[key], klass, property.init_method)
+ self[key] = typecast_value(self[key], property.type, property.init_method)
associate_casted_to_parent(self[key], assigned)
end
end
View
14 lib/couchrest/more/property.rb
@@ -16,11 +16,19 @@ def initialize(name, type = nil, options = {})
def parse_type(type)
if type.nil?
- @type = 'String'
+ @type = String
elsif type.is_a?(Array) && type.empty?
- @type = ['Object']
+ @type = [Object]
else
- @type = type.is_a?(Array) ? [type.first.to_s] : type.to_s
+ base_type = type.is_a?(Array) ? type.first : type
+ if base_type.is_a?(String)
+ base_type = TrueClass if base_type.downcase == 'boolean'
+ begin
+ base_type = ::CouchRest.constantize(base_type) unless base_type.is_a?(Class)
+ rescue # leave base type as is and convert in more/typecast
+ end
+ end
+ @type = type.is_a?(Array) ? [base_type] : base_type
end
end
View
1 lib/couchrest/more/typecast.rb
@@ -28,6 +28,7 @@ module Typecast
def typecast_value(value, klass, init_method)
return nil if value.nil?
+ klass = ::CouchRest.constantize(klass) unless klass.is_a?(Class)
if value.instance_of?(klass) || klass == Object
value
elsif [String, TrueClass, Integer, Float, BigDecimal, DateTime, Time, Date, Class].include?(klass)
View
2 lib/couchrest/validation/auto_validate.rb
@@ -101,7 +101,7 @@ def auto_generate_validations(property)
end
# length
- if property.type == "String"
+ if property.type == String
# XXX: maybe length should always return a Range, with the min defaulting to 1
# 52 being the max set
len = property.options.fetch(:length, property.options.fetch(:size, 52))
View
18 spec/couchrest/more/casted_extended_doc_spec.rb
@@ -1,34 +1,40 @@
require File.expand_path('../../../spec_helper', __FILE__)
+require File.join(FIXTURE_PATH, 'more', 'cat')
+require File.join(FIXTURE_PATH, 'more', 'person')
require File.join(FIXTURE_PATH, 'more', 'card')
-class Car < CouchRest::ExtendedDocument
+class Driver < CouchRest::ExtendedDocument
use_database TEST_SERVER.default_database
+ # You have to add a casted_by accessor if you want to reach a casted extended doc parent
+ attr_accessor :casted_by
property :name
- property :driver, :cast_as => 'Driver'
end
-class Driver < CouchRest::ExtendedDocument
+class Car < CouchRest::ExtendedDocument
use_database TEST_SERVER.default_database
- # You have to add a casted_by accessor if you want to reach a casted extended doc parent
- attr_accessor :casted_by
property :name
+ property :driver, :cast_as => 'Driver'
+ property :backseat_driver, :cast_as => Driver
end
describe "casting an extended document" do
before(:each) do
@driver = Driver.new(:name => 'Matt')
@car = Car.new(:name => 'Renault 306', :driver => @driver)
+ @car2 = Car.new(:name => 'Renault 306', :backseat_driver => @driver.dup)
end
it "should retain all properties of the casted attribute" do
@car.driver.should == @driver
+ @car2.backseat_driver.should == @driver
end
it "should let the casted document know who casted it" do
@car.driver.casted_by.should == @car
+ @car2.backseat_driver.casted_by.should == @car2
end
end
@@ -70,4 +76,4 @@ class Driver < CouchRest::ExtendedDocument
it "should retain all properties of the casted attribute" do
@new_car.driver.should == @driver
end
-end
+end
View
2 spec/couchrest/more/casted_model_spec.rb
@@ -124,7 +124,7 @@ class NotAHashButWithCastedModelMixin
@obj = DummyModel.new(:keywords => ['couch', 'sofa', 'relax', 'canapé'])
end
- it "should cast the array propery" do
+ it "should cast the array properly" do
@obj.keywords.should be_an_instance_of(Array)
@obj.keywords.first.should == 'couch'
end
View
4 spec/fixtures/more/card.rb
@@ -11,12 +11,12 @@ class Card < CouchRest::ExtendedDocument
property :first_name
property :last_name, :alias => :family_name
property :read_only_value, :read_only => true
- property :cast_alias, :cast_as => 'Person', :alias => :calias
+ property :cast_alias, :cast_as => Person, :alias => :calias
timestamps!
# Validation
validates_presence_of :first_name
-end
+end

0 comments on commit dd3df8f

Please sign in to comment.
Something went wrong with that request. Please try again.