SlideShare a Scribd company logo
1 of 32
Aqua A cool, clear drink of  Ruby object persistence Kane Baccigalupi RubyConf 09
Aqua A cool, clear drink of Ruby object persistence Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Got unemployment? Relax with CouchDB Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence ORMs are great, but normalization is expensive. # DataMapper class Mammal   include DataMapper::Resource   property :my_id, Serial   has n, :legs end # ActiveRecord class Bird < ActiveRecord::Base   # properties defined by migration has_many, :legs end Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence CouchDB + Ruby  ~=  CouchRest # CouchRest class Reptile < CouchRest::ExtendedDocument use_database MY_DB unique_id :my_id   property  :legs # a collection! end Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence CouchRest is different from ORMs because: It allows collections Models are hashes Instance variables are discarded Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence What defines Ruby object state? Instance variables  @my_variable Fundamental data  	Hash key-values, Array values, etc. Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Database abstractions focus on databases # DataMapper class Mammal   include DataMapper::Resource   property :my_id,    Serial   has n, :legs end # ActiveRecord class Bird < ActiveRecord::Base   # properties defined by schema has_many, :legs end # CouchRest class Reptile < CouchRest::ExtendedDocument use_database MY_DB unique_id :my_id   property  :legs # a collection! end Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Aqua’s goal: Focus on objects  object.commit! Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Because Ruby is awesome class Event < Range  attr_accessor :name end rubyconf = 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 Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence How does Aqua work? Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Just add Aqua class User aquatic # ... end Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Just add Aqua class User aquatic # ... end user = User.new # ... More stuff happens to the user # saving an object user.commit! # commit without the ! also works but raises no errors. Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Behind the scene user.commit! Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Behind the scene serialization user.commit! {   "class"=>"User",    "ivars"=>{     "@username"=>"kane",      "@email"=>"baccigalupi@gmail.com",      "@password"=>"secret"    } } Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Behind the scene serialization user.commit! {   "class"=>"User",    "ivars"=>{     "@username"=>"kane",      "@email"=>"baccigalupi@gmail.com",      "@password"=>"secret"    } } data post Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Objects ~= 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 Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Sometimes state  should not hang around. There is a method for that.  class User   aquatic attr_accessor :username, :email, :password  hide_attributes :password end Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Going deeper with embedded objects … class Address # not an aquatic object, just plain ruby attr_accessor :name, :street, :city, :state, :zip end   address  = Address.new # . . .  user = User.new user.addresses = [ address ] Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Ordinary objects get serialized inside aquatic objects {   "class"=>"User",    "ivars"=>{ "@addresses"=>{       "class"=>"Array",        "init"=>[{         "class"=>"Address",          "ivars"=>{           "@city"=>"San Francisco",            "@name"=>"work",            "@street"=>"P0 Box 58",            "@state"=>"94102"         }       }]      },      "@username"=>"kane",      "@email"=>"baccigalupi@gmail.com"   } }  Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Embedded aquatic objects are  saved by reference. {   "class"=>"User",    "ivars"=>{     # ...     "@friends"=>{       "class"=>"Array",        "init"=>[{         "class"=>"Aqua::Stub",          "init"=>{"class"=>"User", "id"=>"32"}        }]     }   } } class User aquatic # ... def friends    @friends ||= []   end end user.friends << alex # where alex is another user object Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Aqua::Stub~= Lazy Delegate ,[object Object]
 Triggered by #method_missing
 Stubs/caches methods{   "class"=>"User",    "ivars"=>{     # ...     "@friends"=>{       "class"=>"Array",        "init"=>[{         "class"=>"Aqua::Stub",          "init"=>{"class"=>"User", "id"=>"32"}        }]     }   } } Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Stubbing methods in Aqua::Stub {   "class"=>"User",    "ivars"=>{     # ...     "@friends"=>{       "class"=>"Array",        "init"=>[{         "class"=>"Aqua::Stub",          "init"=>{           "class"=>"User",           "id"=>"32”, "methods"=>{"username"=>"alex"},          }        }]     }   } } class User aquatic :embed => { :stub => :username }  # ... end Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Stubbed behavior user.reload friend = user.friends.first friend.class # Aqua::Stub friend.username# ‘alex’ # username was cached friend.email # this triggers the database call  # for the friend object Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Got Files? {   "class"=>"User",    "ivars"=>{     # ... "@avatar"=>{ 	 "class"=>"Aqua::FileStub”       "init"=>{        "methods"=>{          "content_type"=>"image/png",          "content_length"=>{            "class"=>"Fixnum", "init"=>"26551”          }        } "id"=>"image_attach.png"       },      }   } } class User aquatic   # ... attr_accessor :avatar end user.avatar = my_pic Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Getting Objects: The basics User.load( some_id ) user.reload Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence Indexed Searches class User aquatic   # ... index_on :username end " // javascript map function function(doc) {     if( doc['class'] == 'User' && doc['ivars'] && doc['ivars']['@username'] ){       emit( doc['ivars']['@username'], 1 );      }   } " User.query(:username, ’kane') # returns an array of all users named kane Kane Baccigalupi RubyConf ‘09
Aqua A cool, clear drink of Ruby object persistence What’s next? More querying ease ,[object Object]
 Criteria pattern ???
 Custom dsl ???

More Related Content

Similar to A cool, clear drink of Ruby object persistence

Rupy2012 ArangoDB Workshop Part2
Rupy2012 ArangoDB Workshop Part2Rupy2012 ArangoDB Workshop Part2
Rupy2012 ArangoDB Workshop Part2
ArangoDB Database
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
railsconf
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-Tuesday
Eddie Kao
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
Socket applications
Socket applicationsSocket applications
Socket applications
João Moura
 

Similar to A cool, clear drink of Ruby object persistence (20)

Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
Sphinx on Rails
Sphinx on RailsSphinx on Rails
Sphinx on Rails
 
Rupy2012 ArangoDB Workshop Part2
Rupy2012 ArangoDB Workshop Part2Rupy2012 ArangoDB Workshop Part2
Rupy2012 ArangoDB Workshop Part2
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
Smalltalk on rubinius
Smalltalk on rubiniusSmalltalk on rubinius
Smalltalk on rubinius
 
Reasons To Love Ruby
Reasons To Love RubyReasons To Love Ruby
Reasons To Love Ruby
 
Leave end-to-end testing to Capybara
Leave end-to-end testing to CapybaraLeave end-to-end testing to Capybara
Leave end-to-end testing to Capybara
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Cucumber Ru09 Web
Cucumber Ru09 WebCucumber Ru09 Web
Cucumber Ru09 Web
 
Freebasing for Fun and Enhancement
Freebasing for Fun and EnhancementFreebasing for Fun and Enhancement
Freebasing for Fun and Enhancement
 
Cucumbered
CucumberedCucumbered
Cucumbered
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-Tuesday
 
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
Rails Sojourn: One Man's Journey - Wicked Good Ruby Conference 2013
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud Castles
 
AddressBook.swift
AddressBook.swiftAddressBook.swift
AddressBook.swift
 
Building Better Web APIs with Rails
Building Better Web APIs with RailsBuilding Better Web APIs with Rails
Building Better Web APIs with Rails
 
CPANTS: Kwalitative website and its tools
CPANTS: Kwalitative website and its toolsCPANTS: Kwalitative website and its tools
CPANTS: Kwalitative website and its tools
 
Socket applications
Socket applicationsSocket applications
Socket applications
 

More from baccigalupi (6)

What the C?
What the C?What the C?
What the C?
 
Long Live the Rubyist
Long Live the RubyistLong Live the Rubyist
Long Live the Rubyist
 
Going Evergreen, RubyConf 2014
Going Evergreen, RubyConf 2014Going Evergreen, RubyConf 2014
Going Evergreen, RubyConf 2014
 
Diversity? Why? What? How?
Diversity? Why? What? How?Diversity? Why? What? How?
Diversity? Why? What? How?
 
Why you should build your own JS Frontend Framework
Why you should build your own JS Frontend FrameworkWhy you should build your own JS Frontend Framework
Why you should build your own JS Frontend Framework
 
Wheel.js
Wheel.jsWheel.js
Wheel.js
 

Recently uploaded

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 

A cool, clear drink of Ruby object persistence

  • 1. Aqua A cool, clear drink of Ruby object persistence Kane Baccigalupi RubyConf 09
  • 2. Aqua A cool, clear drink of Ruby object persistence Kane Baccigalupi RubyConf ‘09
  • 3. Aqua A cool, clear drink of Ruby object persistence Got unemployment? Relax with CouchDB Kane Baccigalupi RubyConf ‘09
  • 4. Aqua A cool, clear drink of Ruby object persistence ORMs are great, but normalization is expensive. # DataMapper class Mammal include DataMapper::Resource property :my_id, Serial has n, :legs end # ActiveRecord class Bird < ActiveRecord::Base # properties defined by migration has_many, :legs end Kane Baccigalupi RubyConf ‘09
  • 5. Aqua A cool, clear drink of Ruby object persistence CouchDB + Ruby ~= CouchRest # CouchRest class Reptile < CouchRest::ExtendedDocument use_database MY_DB unique_id :my_id property :legs # a collection! end Kane Baccigalupi RubyConf ‘09
  • 6. Aqua A cool, clear drink of Ruby object persistence CouchRest is different from ORMs because: It allows collections Models are hashes Instance variables are discarded Kane Baccigalupi RubyConf ‘09
  • 7. Aqua A cool, clear drink of Ruby object persistence What defines Ruby object state? Instance variables @my_variable Fundamental data Hash key-values, Array values, etc. Kane Baccigalupi RubyConf ‘09
  • 8. Aqua A cool, clear drink of Ruby object persistence Database abstractions focus on databases # DataMapper class Mammal include DataMapper::Resource property :my_id, Serial has n, :legs end # ActiveRecord class Bird < ActiveRecord::Base # properties defined by schema has_many, :legs end # CouchRest class Reptile < CouchRest::ExtendedDocument use_database MY_DB unique_id :my_id property :legs # a collection! end Kane Baccigalupi RubyConf ‘09
  • 9. Aqua A cool, clear drink of Ruby object persistence Aqua’s goal: Focus on objects object.commit! Kane Baccigalupi RubyConf ‘09
  • 10. Aqua A cool, clear drink of Ruby object persistence Because Ruby is awesome class Event < Range attr_accessor :name end rubyconf = 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 Baccigalupi RubyConf ‘09
  • 11. Aqua A cool, clear drink of Ruby object persistence How does Aqua work? Kane Baccigalupi RubyConf ‘09
  • 12. Aqua A cool, clear drink of Ruby object persistence Just add Aqua class User aquatic # ... end Kane Baccigalupi RubyConf ‘09
  • 13. Aqua A cool, clear drink of Ruby object persistence Just add Aqua class User aquatic # ... end user = User.new # ... More stuff happens to the user # saving an object user.commit! # commit without the ! also works but raises no errors. Kane Baccigalupi RubyConf ‘09
  • 14. Aqua A cool, clear drink of Ruby object persistence Behind the scene user.commit! Kane Baccigalupi RubyConf ‘09
  • 15. Aqua A cool, clear drink of Ruby object persistence Behind the scene serialization user.commit! { "class"=>"User", "ivars"=>{ "@username"=>"kane", "@email"=>"baccigalupi@gmail.com", "@password"=>"secret" } } Kane Baccigalupi RubyConf ‘09
  • 16. Aqua A cool, clear drink of Ruby object persistence Behind the scene serialization user.commit! { "class"=>"User", "ivars"=>{ "@username"=>"kane", "@email"=>"baccigalupi@gmail.com", "@password"=>"secret" } } data post Kane Baccigalupi RubyConf ‘09
  • 17. Aqua A cool, clear drink of Ruby object persistence Objects ~= 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 Baccigalupi RubyConf ‘09
  • 18. Aqua A cool, clear drink of Ruby object persistence Sometimes state should not hang around. There is a method for that. class User aquatic attr_accessor :username, :email, :password hide_attributes :password end Kane Baccigalupi RubyConf ‘09
  • 19. Aqua A cool, clear drink of Ruby object persistence Going deeper with embedded objects … class Address # not an aquatic object, just plain ruby attr_accessor :name, :street, :city, :state, :zip end address = Address.new # . . . user = User.new user.addresses = [ address ] Kane Baccigalupi RubyConf ‘09
  • 20. Aqua A cool, clear drink of Ruby object persistence Ordinary objects get serialized inside aquatic objects { "class"=>"User", "ivars"=>{ "@addresses"=>{ "class"=>"Array", "init"=>[{ "class"=>"Address", "ivars"=>{ "@city"=>"San Francisco", "@name"=>"work", "@street"=>"P0 Box 58", "@state"=>"94102" } }] }, "@username"=>"kane", "@email"=>"baccigalupi@gmail.com" } } Kane Baccigalupi RubyConf ‘09
  • 21. Aqua A cool, clear drink of Ruby object persistence Embedded aquatic objects are saved by reference. { "class"=>"User", "ivars"=>{ # ... "@friends"=>{ "class"=>"Array", "init"=>[{ "class"=>"Aqua::Stub", "init"=>{"class"=>"User", "id"=>"32"} }] } } } class User aquatic # ... def friends @friends ||= [] end end user.friends << alex # where alex is another user object Kane Baccigalupi RubyConf ‘09
  • 22.
  • 23. Triggered by #method_missing
  • 24. Stubs/caches methods{ "class"=>"User", "ivars"=>{ # ... "@friends"=>{ "class"=>"Array", "init"=>[{ "class"=>"Aqua::Stub", "init"=>{"class"=>"User", "id"=>"32"} }] } } } Kane Baccigalupi RubyConf ‘09
  • 25. Aqua A cool, clear drink of Ruby object persistence Stubbing methods in Aqua::Stub { "class"=>"User", "ivars"=>{ # ... "@friends"=>{ "class"=>"Array", "init"=>[{ "class"=>"Aqua::Stub", "init"=>{ "class"=>"User", "id"=>"32”, "methods"=>{"username"=>"alex"}, } }] } } } class User aquatic :embed => { :stub => :username } # ... end Kane Baccigalupi RubyConf ‘09
  • 26. Aqua A cool, clear drink of Ruby object persistence Stubbed behavior user.reload friend = user.friends.first friend.class # Aqua::Stub friend.username# ‘alex’ # username was cached friend.email # this triggers the database call # for the friend object Kane Baccigalupi RubyConf ‘09
  • 27. Aqua A cool, clear drink of Ruby object persistence Got Files? { "class"=>"User", "ivars"=>{ # ... "@avatar"=>{ "class"=>"Aqua::FileStub” "init"=>{ "methods"=>{ "content_type"=>"image/png", "content_length"=>{ "class"=>"Fixnum", "init"=>"26551” } } "id"=>"image_attach.png" }, } } } class User aquatic # ... attr_accessor :avatar end user.avatar = my_pic Kane Baccigalupi RubyConf ‘09
  • 28. Aqua A cool, clear drink of Ruby object persistence Getting Objects: The basics User.load( some_id ) user.reload Kane Baccigalupi RubyConf ‘09
  • 29. Aqua A cool, clear drink of Ruby object persistence Indexed Searches class User aquatic # ... index_on :username end " // javascript map function function(doc) { if( doc['class'] == 'User' && doc['ivars'] && doc['ivars']['@username'] ){ emit( doc['ivars']['@username'], 1 ); } } " User.query(:username, ’kane') # returns an array of all users named kane Kane Baccigalupi RubyConf ‘09
  • 30.
  • 33. Much coding loveKane Baccigalupi RubyConf ‘09
  • 34.
  • 35. Attribute constraints for class, size, etc.
  • 36. Collections & relationships
  • 37. ActiveRecord conversion ???Kane Baccigalupi RubyConf ‘09
  • 38.
  • 40. Classes (are objects too)Kane Baccigalupi RubyConf ‘09
  • 41.
  • 42. Stores objects, not serializations
  • 43. commits objects as neededKane Baccigalupi RubyConf ‘09
  • 44. Aqua A cool, clear drink of Ruby object persistence More Info Rdocs: ruby-aqua.org Get the gem: sudo gem install aqua Explore the code: github.com/baccigalupi/aqua Kane Baccigalupi RubyConf ‘09