Upgrading to use CouchRest 1.1.0.pre3 and new Hash-less design

master v1.1.0.rc
Sam Lown 2011-06-08 18:22:35 +02:00
parent 6e025bb256
commit 7c7ee2c2b1
19 changed files with 197 additions and 137 deletions

View File

@ -1 +1 @@
1.1.0.beta5 1.1.0.rc

View File

@ -23,11 +23,12 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.add_dependency(%q<couchrest>, "1.1.0.pre2") s.add_dependency(%q<couchrest>, "1.1.0.pre3")
s.add_dependency(%q<mime-types>, "~> 1.15") s.add_dependency(%q<mime-types>, "~> 1.15")
s.add_dependency(%q<activemodel>, "~> 3.0") s.add_dependency(%q<activemodel>, "~> 3.0")
s.add_dependency(%q<tzinfo>, "~> 0.3.22") s.add_dependency(%q<tzinfo>, "~> 0.3.22")
s.add_development_dependency(%q<rspec>, ">= 2.0.0") s.add_development_dependency(%q<rspec>, "~> 2.6.0")
s.add_development_dependency(%q<json>, ["~> 1.5.1"])
s.add_development_dependency(%q<rack-test>, ">= 0.5.7") s.add_development_dependency(%q<rack-test>, ">= 0.5.7")
# s.add_development_dependency("jruby-openssl", ">= 0.7.3") # s.add_development_dependency("jruby-openssl", ">= 0.7.3")
end end

View File

@ -1,11 +1,11 @@
# CouchRest Model Change History # CouchRest Model Change History
## 1.1.0 - 2011-05-XX ## 1.1.0.rc - 2011-06-08
* New Features * New Features
* Properties with a nil value are now no longer sent to the database. * Properties with a nil value are now no longer sent to the database.
* Now possible to build new objects via CastedArray#build * Now possible to build new objects via CastedArray#build
* Implement #get! and #find! class methods * Implement #get! and #find! class methods
* Minor fixes * Minor fixes
* #as_json now correctly uses ActiveSupports methods. * #as_json now correctly uses ActiveSupports methods.
@ -18,6 +18,8 @@
* #destroy freezes object instead of removing _id and _rev, better for callbacks (pointer by karmi) * #destroy freezes object instead of removing _id and _rev, better for callbacks (pointer by karmi)
* #destroyed? method now available * #destroyed? method now available
* #reload no longer uses Hash#merge! which was causing issues with dirty tracking on casted models. (pointer by kostia) * #reload no longer uses Hash#merge! which was causing issues with dirty tracking on casted models. (pointer by kostia)
* Non-property mass assignment on #new no longer possible without :directly_set_attributes option.
* Using CouchRest 1.1.0.pre3. (No more Hashes!)
## 1.1.0.beta5 - 2011-04-30 ## 1.1.0.beta5 - 2011-04-30

View File

@ -1,6 +1,6 @@
module CouchRest module CouchRest
module Model module Model
class Base < Document class Base < CouchRest::Document
extend ActiveModel::Naming extend ActiveModel::Naming
@ -51,14 +51,15 @@ module CouchRest
# #
# If a block is provided the new model will be passed into the # If a block is provided the new model will be passed into the
# block so that it can be populated. # block so that it can be populated.
def initialize(doc = {}, options = {}) def initialize(attributes = {}, options = {})
doc = prepare_all_attributes(doc, options) super()
# set the instances database, if provided prepare_all_attributes(attributes, options)
# set the instance's database, if provided
self.database = options[:database] unless options[:database].nil? self.database = options[:database] unless options[:database].nil?
super(doc)
unless self['_id'] && self['_rev'] unless self['_id'] && self['_rev']
self[self.model_type_key] = self.class.to_s self[self.model_type_key] = self.class.to_s
end end
yield self if block_given? yield self if block_given?
after_initialize if respond_to?(:after_initialize) after_initialize if respond_to?(:after_initialize)
@ -79,16 +80,6 @@ module CouchRest
super super
end end
## Compatibility with ActiveSupport and older frameworks
# Hack so that CouchRest::Document, which descends from Hash,
# doesn't appear to Rails routing as a Hash of options
def is_a?(klass)
return false if klass == Hash
super
end
alias :kind_of? :is_a?
def persisted? def persisted?
!new? !new?
end end

View File

@ -1,13 +1,10 @@
module CouchRest module CouchRest
module Model module Model
module DocumentQueries module DocumentQueries
extend ActiveSupport::Concern
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods module ClassMethods
# Load all documents that have the model_type_key's field equal to the # Load all documents that have the model_type_key's field equal to the
# name of the current class. Take the standard set of # name of the current class. Take the standard set of
# CouchRest::Database#view options. # CouchRest::Database#view options.
@ -73,7 +70,7 @@ module CouchRest
end end
end end
alias :find :get alias :find :get
# Load a document from the database by id # Load a document from the database by id
# An exception will be raised if the document isn't found # An exception will be raised if the document isn't found
# #

View File

@ -106,14 +106,17 @@ module CouchRest
module ClassMethods module ClassMethods
# Creates a new instance, bypassing attribute protection # Creates a new instance, bypassing attribute protection and
# uses the type field to determine which model to use to instanatiate
# the new object.
# #
# ==== Returns # ==== Returns
# a document instance # a document instance
# #
def build_from_database(doc = {}) def build_from_database(doc = {}, options = {}, &block)
base = (doc[model_type_key].blank? || doc[model_type_key] == self.to_s) ? self : doc[model_type_key].constantize src = doc[model_type_key]
base.new(doc, :directly_set_attributes => true) base = (src.blank? || src == self.to_s) ? self : src.constantize
base.new(doc, options.merge(:directly_set_attributes => true), &block)
end end
# Defines an instance and save it directly to the database # Defines an instance and save it directly to the database

View File

@ -80,17 +80,18 @@ module CouchRest
self.disable_dirty = dirty self.disable_dirty = dirty
end end
def prepare_all_attributes(doc = {}, options = {}) def prepare_all_attributes(attrs = {}, options = {})
self.disable_dirty = !!options[:directly_set_attributes] self.disable_dirty = !!options[:directly_set_attributes]
apply_all_property_defaults apply_all_property_defaults
if options[:directly_set_attributes] if options[:directly_set_attributes]
directly_set_read_only_attributes(doc) directly_set_read_only_attributes(attrs)
directly_set_attributes(attrs, true)
else else
doc = remove_protected_attributes(doc) attrs = remove_protected_attributes(attrs)
directly_set_attributes(attrs)
end end
res = doc.nil? ? doc : directly_set_attributes(doc)
self.disable_dirty = false self.disable_dirty = false
res self
end end
def find_property!(property) def find_property!(property)
@ -101,16 +102,13 @@ module CouchRest
# Set all the attributes and return a hash with the attributes # Set all the attributes and return a hash with the attributes
# that have not been accepted. # that have not been accepted.
def directly_set_attributes(hash) def directly_set_attributes(hash, mass_assign = false)
hash.reject do |attribute_name, attribute_value| return if hash.nil?
if self.respond_to?("#{attribute_name}=") hash.reject do |key, value|
self.send("#{attribute_name}=", attribute_value) if self.respond_to?("#{key}=")
true self.send("#{key}=", value)
elsif mass_assign_any_attribute # config option elsif mass_assign || mass_assign_any_attribute
self[attribute_name] = attribute_value self[key] = value
true
else
false
end end
end end
end end

View File

@ -26,7 +26,7 @@ module CouchRest::Model
if type.is_a?(Array) if type.is_a?(Array)
if value.nil? if value.nil?
value = [] value = []
elsif [Hash, HashWithIndifferentAccess].include?(value.class) elsif value.is_a?(Hash)
# Assume provided as a Hash where key is index! # Assume provided as a Hash where key is index!
data = value data = value
value = [ ] value = [ ]
@ -39,7 +39,7 @@ module CouchRest::Model
arr = value.collect { |data| cast_value(parent, data) } arr = value.collect { |data| cast_value(parent, data) }
# allow casted_by calls to be passed up chain by wrapping in CastedArray # allow casted_by calls to be passed up chain by wrapping in CastedArray
CastedArray.new(arr, self, parent) CastedArray.new(arr, self, parent)
elsif (type == Object || type == Hash) && (value.class == Hash) elsif (type == Object || type == Hash) && (value.is_a?(Hash))
# allow casted_by calls to be passed up chain by wrapping in CastedHash # allow casted_by calls to be passed up chain by wrapping in CastedHash
CastedHash[value, self, parent] CastedHash[value, self, parent]
elsif !value.nil? elsif !value.nil?

View File

@ -73,12 +73,12 @@ module CouchRest
end end
# Base # Base
def new(*args) def new(attrs = {}, options = {}, &block)
proxy_update(model.new(*args)) proxy_block_update(:new, attrs, options, &block)
end end
def build_from_database(doc = {}) def build_from_database(attrs = {}, options = {}, &block)
proxy_update(model.build_from_database(doc)) proxy_block_update(:build_from_database, attrs, options, &block)
end end
def method_missing(m, *args, &block) def method_missing(m, *args, &block)
@ -170,6 +170,13 @@ module CouchRest
end end
end end
def proxy_block_update(method, *args, &block)
model.send(method, *args) do |doc|
proxy_update(doc)
yield doc if block_given?
end
end
end end
end end
end end

View File

@ -18,7 +18,7 @@ CouchRest::Design.class_eval do
flatten = flatten =
lambda {|r| lambda {|r|
(recurse = lambda {|v| (recurse = lambda {|v|
if v.is_a?(Hash) if v.is_a?(Hash) || v.is_a?(CouchRest::Document)
v.to_a.map{|v| recurse.call(v)}.flatten v.to_a.map{|v| recurse.call(v)}.flatten
elsif v.is_a?(Array) elsif v.is_a?(Array)
v.flatten.map{|v| recurse.call(v)} v.flatten.map{|v| recurse.call(v)}

View File

@ -49,8 +49,34 @@ describe "Model Base" do
@obj.database.should eql('database') @obj.database.should eql('database')
end end
it "should only set defined properties" do
@doc = WithDefaultValues.new(:name => 'test', :foo => 'bar')
@doc['name'].should eql('test')
@doc['foo'].should be_nil
end
it "should set all properties with :directly_set_attributes option" do
@doc = WithDefaultValues.new({:name => 'test', :foo => 'bar'}, :directly_set_attributes => true)
@doc['name'].should eql('test')
@doc['foo'].should eql('bar')
end
it "should set the model type" do
@doc = WithDefaultValues.new()
@doc[WithDefaultValues.model_type_key].should eql('WithDefaultValues')
end
it "should call after_initialize method if available" do
@doc = WithAfterInitializeMethod.new
@doc['some_value'].should eql('value')
end
it "should call after_initialize after block" do
@doc = WithAfterInitializeMethod.new {|d| d.some_value = "foo"}
@doc['some_value'].should eql('foo')
end
end end
describe "ActiveModel compatability Basic" do describe "ActiveModel compatability Basic" do
before(:each) do before(:each) do
@ -109,9 +135,23 @@ describe "Model Base" do
end end
end end
describe "#destroyed?" do
it "should be present" do
@obj.should respond_to(:destroyed?)
end
it "should return false with new object" do
@obj.destroyed?.should be_false
end
it "should return true after destroy" do
@obj.save
@obj.destroy
@obj.destroyed?.should be_true
end
end
end end
describe "update attributes without saving" do describe "update attributes without saving" do
before(:each) do before(:each) do
a = Article.get "big-bad-danger" rescue nil a = Article.get "big-bad-danger" rescue nil
@ -152,7 +192,7 @@ describe "Model Base" do
}.should_not raise_error }.should_not raise_error
@art.slug.should == "big-bad-danger" @art.slug.should == "big-bad-danger"
end end
#it "should not change other attributes if there is an error" do #it "should not change other attributes if there is an error" do
# lambda { # lambda {
# @art.update_attributes_without_saving('slug' => "new-slug", :title => "super danger") # @art.update_attributes_without_saving('slug' => "new-slug", :title => "super danger")
@ -160,7 +200,7 @@ describe "Model Base" do
# @art['title'].should == "big bad danger" # @art['title'].should == "big bad danger"
#end #end
end end
describe "update attributes" do describe "update attributes" do
before(:each) do before(:each) do
a = Article.get "big-bad-danger" rescue nil a = Article.get "big-bad-danger" rescue nil
@ -175,7 +215,7 @@ describe "Model Base" do
loaded['title'].should == "super danger" loaded['title'].should == "super danger"
end end
end end
describe "with default" do describe "with default" do
it "should have the default value set at initalization" do it "should have the default value set at initalization" do
@obj.preset.should == {:right => 10, :top_align => false} @obj.preset.should == {:right => 10, :top_align => false}
@ -232,7 +272,7 @@ describe "Model Base" do
WithTemplateAndUniqueID.all.map{|o| o.destroy} WithTemplateAndUniqueID.all.map{|o| o.destroy}
WithTemplateAndUniqueID.database.bulk_delete WithTemplateAndUniqueID.database.bulk_delete
@tmpl = WithTemplateAndUniqueID.new @tmpl = WithTemplateAndUniqueID.new
@tmpl2 = WithTemplateAndUniqueID.new(:preset => 'not_value', 'important-field' => '1') @tmpl2 = WithTemplateAndUniqueID.new(:preset => 'not_value', 'slug' => '1')
end end
it "should have fields set when new" do it "should have fields set when new" do
@tmpl.preset.should == 'value' @tmpl.preset.should == 'value'
@ -253,10 +293,10 @@ describe "Model Base" do
before(:all) do before(:all) do
WithTemplateAndUniqueID.all.map{|o| o.destroy} WithTemplateAndUniqueID.all.map{|o| o.destroy}
WithTemplateAndUniqueID.database.bulk_delete WithTemplateAndUniqueID.database.bulk_delete
WithTemplateAndUniqueID.new('important-field' => '1').save WithTemplateAndUniqueID.new('slug' => '1').save
WithTemplateAndUniqueID.new('important-field' => '2').save WithTemplateAndUniqueID.new('slug' => '2').save
WithTemplateAndUniqueID.new('important-field' => '3').save WithTemplateAndUniqueID.new('slug' => '3').save
WithTemplateAndUniqueID.new('important-field' => '4').save WithTemplateAndUniqueID.new('slug' => '4').save
end end
it "should find all" do it "should find all" do
rs = WithTemplateAndUniqueID.all rs = WithTemplateAndUniqueID.all
@ -274,9 +314,9 @@ describe "Model Base" do
end end
it ".count should return the number of documents" do it ".count should return the number of documents" do
WithTemplateAndUniqueID.new('important-field' => '1').save WithTemplateAndUniqueID.new('slug' => '1').save
WithTemplateAndUniqueID.new('important-field' => '2').save WithTemplateAndUniqueID.new('slug' => '2').save
WithTemplateAndUniqueID.new('important-field' => '3').save WithTemplateAndUniqueID.new('slug' => '3').save
WithTemplateAndUniqueID.count.should == 3 WithTemplateAndUniqueID.count.should == 3
end end
@ -285,14 +325,14 @@ describe "Model Base" do
describe "finding the first instance of a model" do describe "finding the first instance of a model" do
before(:each) do before(:each) do
@db = reset_test_db! @db = reset_test_db!
WithTemplateAndUniqueID.new('important-field' => '1').save WithTemplateAndUniqueID.new('slug' => '1').save
WithTemplateAndUniqueID.new('important-field' => '2').save WithTemplateAndUniqueID.new('slug' => '2').save
WithTemplateAndUniqueID.new('important-field' => '3').save WithTemplateAndUniqueID.new('slug' => '3').save
WithTemplateAndUniqueID.new('important-field' => '4').save WithTemplateAndUniqueID.new('slug' => '4').save
end end
it "should find first" do it "should find first" do
rs = WithTemplateAndUniqueID.first rs = WithTemplateAndUniqueID.first
rs['important-field'].should == "1" rs['slug'].should == "1"
end end
it "should return nil if no instances are found" do it "should return nil if no instances are found" do
WithTemplateAndUniqueID.all.each {|obj| obj.destroy } WithTemplateAndUniqueID.all.each {|obj| obj.destroy }
@ -370,14 +410,7 @@ describe "Model Base" do
end end
end end
describe "initialization" do describe "recursive validation on a model" do
it "should call after_initialize method if available" do
@doc = WithAfterInitializeMethod.new
@doc['some_value'].should eql('value')
end
end
describe "recursive validation on a model" do
before :each do before :each do
reset_test_db! reset_test_db!
@cat = Cat.new(:name => 'Sockington') @cat = Cat.new(:name => 'Sockington')

View File

@ -202,7 +202,7 @@ describe "Design Documents" do
describe "lazily refreshing the design document" do describe "lazily refreshing the design document" do
before(:all) do before(:all) do
@db = reset_test_db! @db = reset_test_db!
WithTemplateAndUniqueID.new('important-field' => '1').save WithTemplateAndUniqueID.new('slug' => '1').save
end end
it "should not save the design doc twice" do it "should not save the design doc twice" do
WithTemplateAndUniqueID.all WithTemplateAndUniqueID.all

View File

@ -1,40 +1,33 @@
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
begin class PlainParent
require 'rubygems' unless ENV['SKIP_RUBYGEMS'] class_inheritable_accessor :foo
require 'active_support/json' self.foo = :bar
ActiveSupport::JSON.backend = :JSONGem
class PlainParent
class_inheritable_accessor :foo
self.foo = :bar
end
class PlainChild < PlainParent
end
class ExtendedParent < CouchRest::Model::Base
class_inheritable_accessor :foo
self.foo = :bar
end
class ExtendedChild < ExtendedParent
end
describe "Using chained inheritance without CouchRest::Model::Base" do
it "should preserve inheritable attributes" do
PlainParent.foo.should == :bar
PlainChild.foo.should == :bar
end
end
describe "Using chained inheritance with CouchRest::Model::Base" do
it "should preserve inheritable attributes" do
ExtendedParent.foo.should == :bar
ExtendedChild.foo.should == :bar
end
end
rescue LoadError
puts "This spec requires 'active_support/json' to be loaded"
end end
class PlainChild < PlainParent
end
class ExtendedParent < CouchRest::Model::Base
class_inheritable_accessor :foo
self.foo = :bar
end
class ExtendedChild < ExtendedParent
end
describe "Using chained inheritance without CouchRest::Model::Base" do
it "should preserve inheritable attributes" do
PlainParent.foo.should == :bar
PlainChild.foo.should == :bar
end
end
describe "Using chained inheritance with CouchRest::Model::Base" do
it "should preserve inheritable attributes" do
ExtendedParent.foo.should == :bar
ExtendedChild.foo.should == :bar
end
end

View File

@ -35,11 +35,11 @@ describe "Model Persistence" do
describe "basic saving and retrieving" do describe "basic saving and retrieving" do
it "should work fine" do it "should work fine" do
@obj.name = "should be easily saved and retrieved" @obj.name = "should be easily saved and retrieved"
@obj.save @obj.save!
saved_obj = WithDefaultValues.get(@obj.id) saved_obj = WithDefaultValues.get!(@obj.id)
saved_obj.should_not be_nil saved_obj.should_not be_nil
end end
it "should parse the Time attributes automatically" do it "should parse the Time attributes automatically" do
@obj.name = "should parse the Time attributes automatically" @obj.name = "should parse the Time attributes automatically"
@obj.set_by_proc.should be_an_instance_of(Time) @obj.set_by_proc.should be_an_instance_of(Time)
@ -223,34 +223,34 @@ describe "Model Persistence" do
it "should require the field" do it "should require the field" do
lambda{@templated.save}.should raise_error lambda{@templated.save}.should raise_error
@templated['important-field'] = 'very-important' @templated['slug'] = 'very-important'
@templated.save.should be_true @templated.save.should be_true
end end
it "should save with the id" do it "should save with the id" do
@templated['important-field'] = 'very-important' @templated['slug'] = 'very-important'
@templated.save.should be_true @templated.save.should be_true
t = WithTemplateAndUniqueID.get('very-important') t = WithTemplateAndUniqueID.get('very-important')
t.should == @templated t.should == @templated
end end
it "should not change the id on update" do it "should not change the id on update" do
@templated['important-field'] = 'very-important' @templated['slug'] = 'very-important'
@templated.save.should be_true @templated.save.should be_true
@templated['important-field'] = 'not-important' @templated['slug'] = 'not-important'
@templated.save.should be_true @templated.save.should be_true
t = WithTemplateAndUniqueID.get('very-important') t = WithTemplateAndUniqueID.get('very-important')
t.id.should == @templated.id t.id.should == @templated.id
end end
it "should raise an error when the id is taken" do it "should raise an error when the id is taken" do
@templated['important-field'] = 'very-important' @templated['slug'] = 'very-important'
@templated.save.should be_true @templated.save.should be_true
lambda{WithTemplateAndUniqueID.new('important-field' => 'very-important').save}.should raise_error lambda{WithTemplateAndUniqueID.new('slug' => 'very-important').save}.should raise_error
end end
it "should set the id" do it "should set the id" do
@templated['important-field'] = 'very-important' @templated['slug'] = 'very-important'
@templated.save.should be_true @templated.save.should be_true
@templated.id.should == 'very-important' @templated.id.should == 'very-important'
end end

View File

@ -315,6 +315,28 @@ describe "a casted model retrieved from the database" do
end end
end end
describe "nested models (not casted)" do
before(:each) do
reset_test_db!
@cat = ChildCat.new(:name => 'Stimpy')
@cat.mother = {:name => 'Stinky'}
@cat.siblings = [{:name => 'Feather'}, {:name => 'Felix'}]
@cat.save
@cat = ChildCat.get(@cat.id)
end
it "should correctly save single relation" do
@cat.mother.name.should eql('Stinky')
@cat.mother.casted_by.should eql(@cat)
end
it "should correctly save collection" do
@cat.siblings.first.name.should eql("Feather")
@cat.siblings.last.casted_by.should eql(@cat)
end
end
describe "Property Class" do describe "Property Class" do
it "should provide name as string" do it "should provide name as string" do

View File

@ -87,7 +87,7 @@ describe "Proxyable" do
DummyProxyable.proxy_for(:cats) DummyProxyable.proxy_for(:cats)
@obj = DummyProxyable.new @obj = DummyProxyable.new
CouchRest::Model::Proxyable::ModelProxy.should_receive(:new).with(Cat, @obj, 'dummy_proxyable', 'db').and_return(true) CouchRest::Model::Proxyable::ModelProxy.should_receive(:new).with(Cat, @obj, 'dummy_proxyable', 'db').and_return(true)
@obj.should_receive('proxy_database').and_return('db') @obj.should_receive(:proxy_database).and_return('db')
@obj.cats @obj.cats
end end
@ -165,15 +165,13 @@ describe "Proxyable" do
end end
it "should proxy new call" do it "should proxy new call" do
Cat.should_receive(:new).and_return({}) @obj.should_receive(:proxy_block_update).with(:new, 'attrs', 'opts')
@obj.should_receive(:proxy_update).and_return(true) @obj.new('attrs', 'opts')
@obj.new
end end
it "should proxy build_from_database" do it "should proxy build_from_database" do
Cat.should_receive(:build_from_database).and_return({}) @obj.should_receive(:proxy_block_update).with(:build_from_database, 'attrs', 'opts')
@obj.should_receive(:proxy_update).with({}).and_return(true) @obj.build_from_database('attrs', 'opts')
@obj.build_from_database
end end
describe "#method_missing" do describe "#method_missing" do
@ -313,6 +311,15 @@ describe "Proxyable" do
@obj.send(:proxy_update_all, docs) @obj.send(:proxy_update_all, docs)
end end
describe "#proxy_block_update" do
it "should proxy block updates" do
doc = { }
@obj.model.should_receive(:new).and_yield(doc)
@obj.should_receive(:proxy_update).with(doc)
@obj.send(:proxy_block_update, :new)
end
end
end end
end end

View File

@ -86,15 +86,16 @@ end
class WithTemplateAndUniqueID < CouchRest::Model::Base class WithTemplateAndUniqueID < CouchRest::Model::Base
use_database TEST_SERVER.default_database use_database TEST_SERVER.default_database
unique_id do |model| unique_id do |model|
model['important-field'] model.slug
end end
property :slug
property :preset, :default => 'value' property :preset, :default => 'value'
property :has_no_default property :has_no_default
end end
class WithGetterAndSetterMethods < CouchRest::Model::Base class WithGetterAndSetterMethods < CouchRest::Model::Base
use_database TEST_SERVER.default_database use_database TEST_SERVER.default_database
property :other_arg property :other_arg
def arg def arg
other_arg other_arg
@ -107,7 +108,7 @@ end
class WithAfterInitializeMethod < CouchRest::Model::Base class WithAfterInitializeMethod < CouchRest::Model::Base
use_database TEST_SERVER.default_database use_database TEST_SERVER.default_database
property :some_value property :some_value
def after_initialize def after_initialize

View File

@ -22,6 +22,7 @@ class Article < CouchRest::Model::Base
property :date, Date property :date, Date
property :slug, :read_only => true property :slug, :read_only => true
property :user_id
property :title property :title
property :tags, [String] property :tags, [String]

View File

@ -17,3 +17,7 @@ class Cat < CouchRest::Model::Base
property :number property :number
end end
class ChildCat < Cat
property :mother, Cat
property :siblings, [Cat]
end