3. AquaA cool, clear drink of Ruby object persistenceGot unemployment?Relax with CouchDBKane BaccigalupiRubyConf 09
4. AquaA cool, clear drink of Ruby object persistenceORMs are great,but normalization is expensive.# DataMapperclass Mammal include DataMapper::Resource property :my_id, Serial has n, :legsend# ActiveRecordclass Bird < ActiveRecord::Base # properties defined by migrationhas_many, :legsendKane BaccigalupiRubyConf 09
6. AquaA cool, clear drink of Ruby object persistenceCouchRest is different from ORMs because:It allows collectionsModels are hashesInstance variables are discardedKane BaccigalupiRubyConf 09
8. AquaA cool, clear drink of Ruby object persistenceDatabase abstractionsfocus on databases# DataMapperclass Mammal include DataMapper::Resource property :my_id, Serial has n, :legsend# ActiveRecordclass Bird < ActiveRecord::Base # properties defined by schemahas_many, :legsend# CouchRestclass Reptile < CouchRest::ExtendedDocumentuse_database MY_DBunique_id :my_id property :legs # a collection!endKane BaccigalupiRubyConf 09
9. AquaA cool, clear drink of Ruby object persistenceAquas goal:Focus on objects object.commit!Kane BaccigalupiRubyConf 09
10. AquaA cool, clear drink of Ruby object persistenceBecause Ruby is awesomeclass Event < Range attr_accessor :nameendrubyconf = Event.new(Date.parse('11/19/2009'), Date.parse('11/21/2009'))rubyconf.name = 'RubyConf 09'rubyconf.include?(Date.parse('11/20/2009')) # true Kane BaccigalupiRubyConf 09
11. AquaA cool, clear drink of Ruby object persistenceHow does Aqua work?Kane BaccigalupiRubyConf 09
13. AquaA cool, clear drink of Ruby object persistenceJust add Aquaclass Useraquatic# ...enduser = User.new# ... More stuff happens to the user# saving an objectuser.commit! # commit without the ! also works but raises no errors.Kane BaccigalupiRubyConf 09
14. AquaA cool, clear drink of Ruby object persistenceBehind the sceneuser.commit!Kane BaccigalupiRubyConf 09
15. AquaA cool, clear drink of Ruby object persistenceBehind the sceneserializationuser.commit!{ "class"=>"User", "ivars"=>{ "@username"=>"kane", "@email"=>"baccigalupi@gmail.com", "@password"=>"secret" }}Kane BaccigalupiRubyConf 09
16. AquaA cool, clear drink of Ruby object persistenceBehind the sceneserializationuser.commit!{ "class"=>"User", "ivars"=>{ "@username"=>"kane", "@email"=>"baccigalupi@gmail.com", "@password"=>"secret" }}data postKane BaccigalupiRubyConf 09
17. AquaA cool, clear drink of Ruby object persistenceObjects ~= Documents,&& Documents ~= Hashes# YAML for a Ruby User object--- &id001 !ruby/object:User email: baccigalupi@gmail.com password: secret username: kane# Aqua Serialization for same object{ "class"=>"User", "ivars"=>{ "@username"=>"kane", "@email"=>"baccigalupi@gmail.com", "@password"=>"secret" }} Kane BaccigalupiRubyConf 09
18. AquaA cool, clear drink of Ruby object persistenceSometimes state should not hang around.There is a method for that. class User aquaticattr_accessor :username, :email, :password hide_attributes :passwordendKane BaccigalupiRubyConf 09
19. AquaA cool, clear drink of Ruby object persistenceGoing deeper with embedded objects class Address# not an aquatic object, just plain rubyattr_accessor :name, :street, :city, :state, :zipend address = Address.new# . . . user = User.newuser.addresses = [ address ]Kane BaccigalupiRubyConf 09
26. AquaA cool, clear drink of Ruby object persistenceStubbed behavioruser.reloadfriend = user.friends.firstfriend.class # Aqua::Stubfriend.username# alex# username was cachedfriend.email# this triggers the database call # for the friend objectKane BaccigalupiRubyConf 09