SlideShare uma empresa Scribd logo
1 de 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 ???

Mais conteúdo relacionado

Semelhante a A cool, clear drink of Ruby object persistence

Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientAdam Wiggins
 
Rupy2012 ArangoDB Workshop Part2
Rupy2012 ArangoDB Workshop Part2Rupy2012 ArangoDB Workshop Part2
Rupy2012 ArangoDB Workshop Part2ArangoDB Database
 
Reasons To Love Ruby
Reasons To Love RubyReasons To Love Ruby
Reasons To Love RubyBen Scheirman
 
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 CapybaraHiroshi SHIBATA
 
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 Amfrailsconf
 
Cucumber Ru09 Web
Cucumber Ru09 WebCucumber Ru09 Web
Cucumber Ru09 WebJoseph Wilk
 
Freebasing for Fun and Enhancement
Freebasing for Fun and EnhancementFreebasing for Fun and Enhancement
Freebasing for Fun and EnhancementMrDys
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayEddie Kao
 
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 2013Mike Desjardins
 
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 JasminePaulo Ragonha
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud CastlesBen Scofield
 
Building Better Web APIs with Rails
Building Better Web APIs with RailsBuilding Better Web APIs with Rails
Building Better Web APIs with RailsAll Things Open
 
CPANTS: Kwalitative website and its tools
CPANTS: Kwalitative website and its toolsCPANTS: Kwalitative website and its tools
CPANTS: Kwalitative website and its toolscharsbar
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 

Semelhante a 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
 

Mais de baccigalupi

Long Live the Rubyist
Long Live the RubyistLong Live the Rubyist
Long Live the Rubyistbaccigalupi
 
Going Evergreen, RubyConf 2014
Going Evergreen, RubyConf 2014Going Evergreen, RubyConf 2014
Going Evergreen, RubyConf 2014baccigalupi
 
Diversity? Why? What? How?
Diversity? Why? What? How?Diversity? Why? What? How?
Diversity? Why? What? How?baccigalupi
 
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 Frameworkbaccigalupi
 

Mais de 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
 

Último

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 

Último (20)

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 

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