subobject casting
This commit is contained in:
parent
03f4169350
commit
9858f85c19
2 changed files with 50 additions and 2 deletions
|
@ -54,6 +54,7 @@ module CouchRest
|
|||
keys.each do |k,v|
|
||||
self[k.to_s] = v
|
||||
end
|
||||
cast_keys
|
||||
unless self['_id'] && self['_rev']
|
||||
self['couchrest-type'] = self.class.to_s
|
||||
end
|
||||
|
@ -81,11 +82,20 @@ module CouchRest
|
|||
new(doc)
|
||||
end
|
||||
|
||||
# Cast a field as another class. The class must be happy to have the
|
||||
# field's primitive type as the argument to it's constucture. Classes
|
||||
# which inherit from CouchRest::Model are happy to act as sub-objects
|
||||
# for any fields that are stored in JSON as object (and therefore are
|
||||
# parsed from the JSON as Ruby Hashes).
|
||||
def cast field, opts = {}
|
||||
@casts ||= {}
|
||||
@casts[field.to_s] = opts
|
||||
end
|
||||
|
||||
def casts
|
||||
@casts
|
||||
end
|
||||
|
||||
# Defines methods for reading and writing from fields in the document.
|
||||
# Uses key_writer and key_reader internally.
|
||||
def key_accessor *keys
|
||||
|
@ -396,6 +406,23 @@ module CouchRest
|
|||
end
|
||||
end
|
||||
|
||||
def cast_keys
|
||||
return unless self.class.casts
|
||||
self.class.casts.each do |k,v|
|
||||
next unless self[k]
|
||||
target = v[:as]
|
||||
if target.is_a?(Array) && target[0].is_a?(Class)
|
||||
self[k] = self[k].collect do |value|
|
||||
target[0].new(value)
|
||||
end
|
||||
elsif target.is_a?(Class)
|
||||
self[k] = target.new(self[k])
|
||||
else
|
||||
raise ArgumentError, ":as => MyClass, :as => [MyClass]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include ::Extlib::Hook
|
||||
register_instance_hooks :save, :create, :update, :destroy
|
||||
|
||||
|
|
|
@ -18,9 +18,17 @@ class Question < CouchRest::Model
|
|||
key_accessor :q, :a
|
||||
end
|
||||
|
||||
class Person < CouchRest::Model
|
||||
key_accessor :name
|
||||
def last_name
|
||||
name.last
|
||||
end
|
||||
end
|
||||
|
||||
class Course < CouchRest::Model
|
||||
key_accessor :title
|
||||
cast :questions, :as => [Question]
|
||||
cast :professor, :as => Person
|
||||
end
|
||||
|
||||
class Article < CouchRest::Model
|
||||
|
@ -170,8 +178,21 @@ describe CouchRest::Model do
|
|||
end
|
||||
|
||||
describe "getting a model with a subobject field" do
|
||||
it "should instantiate it as such" do
|
||||
|
||||
before(:all) do
|
||||
course_doc = {
|
||||
"title" => "Metaphysics 410",
|
||||
"professor" => {
|
||||
"name" => ["Mark", "Hinchliff"]
|
||||
}
|
||||
}
|
||||
r = Course.database.save course_doc
|
||||
@course = Course.get r['id']
|
||||
end
|
||||
it "should load the course" do
|
||||
@course["professor"]["name"][1].should == "Hinchliff"
|
||||
end
|
||||
it "should instantiate the professor as a person" do
|
||||
@course['professor'].last_name.should == "Hinchliff"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue