SlideShare a Scribd company logo
Ohm
Object hash map   Christopher Spring
A little
background
info first...
Ohm runs on redis
Ohm runs on redis
Remote dictionary server
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Atomic operations & transactions
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Atomic operations & transactions
Key expiry
Ohm runs on redis
Remote dictionary server
Store multiple data-structure types
  Lists, Sets, Sorted Sets, Strings, Hashes
In memory datastore with persistence strategies
Super fast & easy to scale
Atomic operations & transactions
Key expiry
redis-rb
What is Ohm?
Ancient syllable
Ancient syllable
Aaa-ooo-mmm
Ancient syllable
Aaa-ooo-mmm
The beginning, duration and
dissolution of the universe
Ancient syllable
Aaa-ooo-mmm
The beginning, duration and
dissolution of the universe
Brahma, Vishnu & Shiva
or...
symbol = {
  :name => 'Ohm',
  :description =>   'Ancient syllable',
  :phonemes => [
    {
      :sound   =>   'aaa',
      :meaning =>   'beginning of the universe',
      :god     =>   'Brahma'
    }, {
      :sound   =>   'ooo',
      :meaning =>   'duration of the universe',
      :god     =>   'Vishnu'
    }, {
      :sound   =>   'mmm',
      :meaning =>   'dissolution of the universe',
      :god     =>   'Shiva'
    }
  ]
}
Let’s store that in
redis...
require 'redis'

db = Redis.new
# make a bunch of phonemes
# HMSET key field value [field value ...]

phos = %w(pho1 pho2 pho3)

db.hmset phos[1], 'sound', 'aaa',
                  'meaning', 'beginning',
                  'god', 'Brahma'

db.hmset phos[2], 'sound', 'ooo',
                  'meaning', 'duration',
                  'god', 'Vishnu'

db.hmset phos[3], 'sound', 'mmm',
                  'meaning', 'dissolution',
                  'god', 'Shiva'
# ... and create the symbol

db.hmset 'symbol',
         'name', 'Ohm'
         'description', 'Ancient syllable',
         'phonemes', phos.to_json
require 'redis'

db = Redis.new

phos = %w(pho1 pho2 pho3)
db.hmset phos[1], 'sound', 'aaa', 'meaning', 'beginning',
'god', 'Brahma'

db.hmset phos[2], 'sound', 'ooo', 'meaning', 'duration',
'god', 'Vishnu'

db.hmset phos[3], 'sound', 'mmm', 'meaning', 'dissolution',
'god', 'Shiva'

db.hmset 'symbol',
  'name', 'Ohm'
  'description', 'Ancient syllable',
  'alternatives', 'alternatives',
  'phenomes', phos.to_json
Awesome?
I want lot’s of Symbols
I want lot’s of Symbols

      db.hmset 'symbol',
        'name', 'Ohm'
        'description', 'Ancient syllable',
        'alternatives', 'alternatives',
        'phenomes', phos.to_json
I want lot’s of Symbols
I want lot’s of Symbols
I want lot’s of Symbols

 Require a key strategy
I want lot’s of Symbols

 Require a key strategy
 Store the key in redis
I want lot’s of Symbols

 Require a key strategy
 Store the key in redis
 Auto-increment
# "symbol:1", "symbol:2" ... "symbol:n"
def get_symbol_pk
  pk = db.incr 'symbol:pk'
  "symbol:#{pk}"
end

# ...

db.hmset get_symbol_pk, ...
Ok, but...
I wanna find symbols by
name!
I wanna find symbols by
name!
Requires an extra index
I wanna find symbols by
name!
Requires an extra index
Store index in a hash or a set
I wanna find symbols by
name!
Requires an extra index
Store index in a hash or a set
We need an index key strategy
I wanna find symbols by
name!
Requires an extra index
Store index in a hash or a set
We need an index key strategy
...
SYMBOL_NAME_INDEX = 'symbol:index:name'

def store_name_index symbol_key, name
  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key
end

def find_symbol_by_name name
  db.get "#{SYMBOL_NAME_INDEX}:#{name}"
end

# Transaction...
db.multi do
  symbol_key = get_symbol_pk

  db.hmset get_symbol_pk,
    'name', symbol_name,
    ...

  store_name_index symbol_key, symbol_name
end
SYMBOL_NAME_INDEX = 'symbol:index:name'

def store_name_index symbol_key, name
  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key
end

def find_symbol_by_name name
  db.get "#{SYMBOL_NAME_INDEX}:#{name}"
end

# Transaction...
db.multi do
  symbol_key = get_symbol_pk

  db.hmset get_symbol_pk,
    'name', symbol_name,
    ...

  store_name_index symbol_key, symbol_name
end
SYMBOL_NAME_INDEX = 'symbol:index:name'

def store_name_index symbol_key, name
  db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key
end

def find_symbol_by_name name
  db.get "#{SYMBOL_NAME_INDEX}:#{name}"
end

# Transaction...
db.multi do
  symbol_key = get_symbol_pk

  db.hmset get_symbol_pk,
    'name', symbol_name,
    ...

  store_name_index symbol_key, symbol_name
end
Fine, but now i want...
Fine, but now i want...

 Validation
Fine, but now i want...

 Validation
 To use this in project X
Fine, but now i want...

 Validation
 To use this in project X
 To be able to find the symbol of a phoneme
Fine, but now i want...

 Validation
 To use this in project X
 To be able to find the symbol of a phoneme
 ... shoot me?
This sucks!!
 Not OO at all
 Validation?
 Referencing containing object
 What other pitfalls have we missed?
 Project/implementation specific
 ...
Let’s build our own object
mapping on top of redis!
or...
Ohm: Object hash map
symbol = {
  :name => 'Ohm',
  :description =>   'Ancient syllable',
  :phonemes => [
    {
      :sound   =>   'aaa',
      :meaning =>   'beginning of the universe',
      :god     =>   'Brahma'
    }, {
      :sound   =>   'ooo',
      :meaning =>   'duration of the universe',
      :god     =>   'Vishnu'
    }, {
      :sound   =>   'mmm',
      :meaning =>   'dissolution of the universe',
      :god     =>   'Shiva'
    }
  ]
}
require 'rubygems'
require 'ohm'

class AncientSymbol < Ohm::Model

  attribute :name
  attribute :description

  index :name

  collection :phonemes, Phoneme

  def validate
    assert_present :name
  end

end
class Phoneme < Ohm::Model

  attribute :sound
  attribute :meaning
  attribute :god

  index :sound
  index :god

  reference :ancient_symbol, AncientSymbol

  def validate
    assert_present :sound
  end

end
Ohm.connect

symbol = AncientSymbol.create

p symbol.valid? # false

p symbol.errors # [[:name, :not_present]]
error_messages = symbol.errors.present do |e|
  e.on [:name, :not_present] do
    "Symbols must have a name."
  end
end
symbol = AncientSymbol.new :name => 'Ohm'

if symbol.save
  symbol.phonemes << Phoneme.create(
      :sound   => 'aaa',
      :meaning => 'beginnging of universe',
      :god     => 'Brahma',
      :ancient_symbol => symbol )

  # ...

end
Cool, so how do find stuff?
Phoneme.all
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
# <AncientSymbol:1 name="Ohm" description=nil>
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
# <AncientSymbol:1 name="Ohm" description=nil>


symbol.phonemes
Phoneme.all
# <Set (Phoneme): ["3", "1", "2"]>


Phoneme.all.except :sound => 'ooo'
# <Set (Phoneme): ["3", "1"]>


Phoneme.find :sound => 'aaa'
# <Set (Phoneme): ["1"]>


pho = Phoneme[1]
# <Phoneme:1 ancient_symbol_id="1" sound="aaa"
meaning="beginnging of universe" god="Brahma">


pho.ancient_symbol
# <AncientSymbol:1 name="Ohm" description=nil>


symbol.phonemes
# <Set (Phoneme): ["3", "1", "2"]>
We also get sorting...
symbol.phonemes.sort
# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]
symbol.phonemes.sort
# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]




symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' )
# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]
symbol.phonemes.sort
# [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>]




symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' )
# [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]




symbol.phonemes.sort_by( :sound, :get => :god )
# ["Shiva", "Brahma", "Vishnu"]
What else can we do?
Attribute types

 attribute
 set
 list
 counter
 reference
 collection
Available validation

 assert_present
 assert_format
 assert_numeric
 assert_unique
ohm-contrib
Boundaries

Callbacks

Timestamping

ToHash

WebValidations

NumberValidations

ExtraValidations

Typecast

Locking
Awesome?
Questions?
Links


www.christopherspring.com
http://ohm.keyvalue.org/
http://www.redis.io/

More Related Content

What's hot

Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)
garux
 
F# delight
F# delightF# delight
F# delight
priort
 
Good Code
Good CodeGood Code
Good Code
Kevlin Henney
 
Use cases in the code with AOP
Use cases in the code with AOPUse cases in the code with AOP
Use cases in the code with AOP
Andrzej Krzywda
 
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
David Koelle
 
Clojure入門
Clojure入門Clojure入門
Clojure入門
Naoyuki Kakuda
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
Ígor Bonadio
 
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
David Koelle
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
takeoutweight
 
Python basic
Python basic Python basic
Python basic
sewoo lee
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
Daniel Blyth
 
FPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixirFPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixir
Functional Programming Brno
 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorialkizzx2
 
PubNative Tracker
PubNative TrackerPubNative Tracker
PubNative Tracker
Andrew Djoga
 
CouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conferenceCouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conference
leinweber
 
PHP 5.4
PHP 5.4PHP 5.4
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Functional Pattern Matching on Python
Functional Pattern Matching on PythonFunctional Pattern Matching on Python
Functional Pattern Matching on PythonDaker Fernandes
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to GroovyAnton Arhipov
 

What's hot (20)

Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)
 
F# delight
F# delightF# delight
F# delight
 
Good Code
Good CodeGood Code
Good Code
 
Use cases in the code with AOP
Use cases in the code with AOPUse cases in the code with AOP
Use cases in the code with AOP
 
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
The Art, Joy, and Power of Creating Musical Programs (JFugue at SXSW Interact...
 
Clojure入門
Clojure入門Clojure入門
Clojure入門
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
 
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
JFugue, Music, and the Future of Java [JavaOne 2016, CON1851]
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
 
Python basic
Python basic Python basic
Python basic
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
FPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixirFPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixir
 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorial
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
 
PubNative Tracker
PubNative TrackerPubNative Tracker
PubNative Tracker
 
CouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conferenceCouchDB @ red dirt ruby conference
CouchDB @ red dirt ruby conference
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Functional Pattern Matching on Python
Functional Pattern Matching on PythonFunctional Pattern Matching on Python
Functional Pattern Matching on Python
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 

Similar to Ohm

Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)
Pamela Fox
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 
第二讲 预备-Python基礎
第二讲 预备-Python基礎第二讲 预备-Python基礎
第二讲 预备-Python基礎
anzhong70
 
第二讲 Python基礎
第二讲 Python基礎第二讲 Python基礎
第二讲 Python基礎
juzihua1102
 
Ruby 101
Ruby 101Ruby 101
Ruby 101
Harisankar P S
 
Poetic APIs
Poetic APIsPoetic APIs
Poetic APIs
Erik Rose
 
Python tutorial
Python tutorialPython tutorial
Python tutorialRajiv Risi
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
Sean Cribbs
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
Murray Steele
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then How
sfarmer10
 
1 the ruby way
1   the ruby way1   the ruby way
1 the ruby way
Luis Doubrava
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
gsterndale
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
Prof. Wim Van Criekinge
 
Strings and Symbols
Strings and SymbolsStrings and Symbols
Strings and Symbols
Blazing Cloud
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
David Black
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
Jordan Baker
 
Class 6: Lists & dictionaries
Class 6: Lists & dictionariesClass 6: Lists & dictionaries
Class 6: Lists & dictionaries
Marc Gouw
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
nazzf
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
Shani729
 

Similar to Ohm (20)

Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
第二讲 预备-Python基礎
第二讲 预备-Python基礎第二讲 预备-Python基礎
第二讲 预备-Python基礎
 
第二讲 Python基礎
第二讲 Python基礎第二讲 Python基礎
第二讲 Python基礎
 
Ruby 101
Ruby 101Ruby 101
Ruby 101
 
Poetic APIs
Poetic APIsPoetic APIs
Poetic APIs
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then How
 
1 the ruby way
1   the ruby way1   the ruby way
1 the ruby way
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Strings and Symbols
Strings and SymbolsStrings and Symbols
Strings and Symbols
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Class 6: Lists & dictionaries
Class 6: Lists & dictionariesClass 6: Lists & dictionaries
Class 6: Lists & dictionaries
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 
Python tutorial
Python tutorialPython tutorial
Python tutorial
 

More from Christopher Spring

Steady with ruby
Steady with rubySteady with ruby
Steady with ruby
Christopher Spring
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
Christopher Spring
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012
Christopher Spring
 
Ruby Concurrency and EventMachine
Ruby Concurrency and EventMachineRuby Concurrency and EventMachine
Ruby Concurrency and EventMachine
Christopher Spring
 
Redis overview for Software Architecture Forum
Redis overview for Software Architecture ForumRedis overview for Software Architecture Forum
Redis overview for Software Architecture Forum
Christopher Spring
 
Redis, Resque & Friends
Redis, Resque & FriendsRedis, Resque & Friends
Redis, Resque & Friends
Christopher Spring
 

More from Christopher Spring (7)

Steady with ruby
Steady with rubySteady with ruby
Steady with ruby
 
jRuby and TorqueBox
jRuby and TorqueBoxjRuby and TorqueBox
jRuby and TorqueBox
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012
 
Ruby Concurrency and EventMachine
Ruby Concurrency and EventMachineRuby Concurrency and EventMachine
Ruby Concurrency and EventMachine
 
Redis overview for Software Architecture Forum
Redis overview for Software Architecture ForumRedis overview for Software Architecture Forum
Redis overview for Software Architecture Forum
 
Redis, Resque & Friends
Redis, Resque & FriendsRedis, Resque & Friends
Redis, Resque & Friends
 

Recently uploaded

Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 

Recently uploaded (20)

Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 

Ohm

  • 1. Ohm Object hash map Christopher Spring
  • 3. Ohm runs on redis
  • 4. Ohm runs on redis Remote dictionary server
  • 5. Ohm runs on redis Remote dictionary server Store multiple data-structure types
  • 6. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes
  • 7. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies
  • 8. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale
  • 9. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale Atomic operations & transactions
  • 10. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale Atomic operations & transactions Key expiry
  • 11. Ohm runs on redis Remote dictionary server Store multiple data-structure types Lists, Sets, Sorted Sets, Strings, Hashes In memory datastore with persistence strategies Super fast & easy to scale Atomic operations & transactions Key expiry redis-rb
  • 13.
  • 16. Ancient syllable Aaa-ooo-mmm The beginning, duration and dissolution of the universe
  • 17. Ancient syllable Aaa-ooo-mmm The beginning, duration and dissolution of the universe Brahma, Vishnu & Shiva
  • 18. or...
  • 19. symbol = { :name => 'Ohm', :description => 'Ancient syllable', :phonemes => [ { :sound => 'aaa', :meaning => 'beginning of the universe', :god => 'Brahma' }, { :sound => 'ooo', :meaning => 'duration of the universe', :god => 'Vishnu' }, { :sound => 'mmm', :meaning => 'dissolution of the universe', :god => 'Shiva' } ] }
  • 20. Let’s store that in redis...
  • 21. require 'redis' db = Redis.new
  • 22. # make a bunch of phonemes # HMSET key field value [field value ...] phos = %w(pho1 pho2 pho3) db.hmset phos[1], 'sound', 'aaa', 'meaning', 'beginning', 'god', 'Brahma' db.hmset phos[2], 'sound', 'ooo', 'meaning', 'duration', 'god', 'Vishnu' db.hmset phos[3], 'sound', 'mmm', 'meaning', 'dissolution', 'god', 'Shiva'
  • 23. # ... and create the symbol db.hmset 'symbol', 'name', 'Ohm' 'description', 'Ancient syllable', 'phonemes', phos.to_json
  • 24. require 'redis' db = Redis.new phos = %w(pho1 pho2 pho3) db.hmset phos[1], 'sound', 'aaa', 'meaning', 'beginning', 'god', 'Brahma' db.hmset phos[2], 'sound', 'ooo', 'meaning', 'duration', 'god', 'Vishnu' db.hmset phos[3], 'sound', 'mmm', 'meaning', 'dissolution', 'god', 'Shiva' db.hmset 'symbol', 'name', 'Ohm' 'description', 'Ancient syllable', 'alternatives', 'alternatives', 'phenomes', phos.to_json
  • 26. I want lot’s of Symbols
  • 27. I want lot’s of Symbols db.hmset 'symbol', 'name', 'Ohm' 'description', 'Ancient syllable', 'alternatives', 'alternatives', 'phenomes', phos.to_json
  • 28. I want lot’s of Symbols
  • 29. I want lot’s of Symbols
  • 30. I want lot’s of Symbols Require a key strategy
  • 31. I want lot’s of Symbols Require a key strategy Store the key in redis
  • 32. I want lot’s of Symbols Require a key strategy Store the key in redis Auto-increment
  • 33. # "symbol:1", "symbol:2" ... "symbol:n" def get_symbol_pk pk = db.incr 'symbol:pk' "symbol:#{pk}" end # ... db.hmset get_symbol_pk, ...
  • 35. I wanna find symbols by name!
  • 36. I wanna find symbols by name! Requires an extra index
  • 37. I wanna find symbols by name! Requires an extra index Store index in a hash or a set
  • 38. I wanna find symbols by name! Requires an extra index Store index in a hash or a set We need an index key strategy
  • 39. I wanna find symbols by name! Requires an extra index Store index in a hash or a set We need an index key strategy ...
  • 40. SYMBOL_NAME_INDEX = 'symbol:index:name' def store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key end def find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}" end # Transaction... db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, 'name', symbol_name, ... store_name_index symbol_key, symbol_name end
  • 41. SYMBOL_NAME_INDEX = 'symbol:index:name' def store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key end def find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}" end # Transaction... db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, 'name', symbol_name, ... store_name_index symbol_key, symbol_name end
  • 42. SYMBOL_NAME_INDEX = 'symbol:index:name' def store_name_index symbol_key, name db.sadd "#{SYMBOL_NAME_INDEX}:#{name}", symbol_key end def find_symbol_by_name name db.get "#{SYMBOL_NAME_INDEX}:#{name}" end # Transaction... db.multi do symbol_key = get_symbol_pk db.hmset get_symbol_pk, 'name', symbol_name, ... store_name_index symbol_key, symbol_name end
  • 43. Fine, but now i want...
  • 44. Fine, but now i want... Validation
  • 45. Fine, but now i want... Validation To use this in project X
  • 46. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme
  • 47. Fine, but now i want... Validation To use this in project X To be able to find the symbol of a phoneme ... shoot me?
  • 48. This sucks!! Not OO at all Validation? Referencing containing object What other pitfalls have we missed? Project/implementation specific ...
  • 49. Let’s build our own object mapping on top of redis!
  • 50. or...
  • 52. symbol = { :name => 'Ohm', :description => 'Ancient syllable', :phonemes => [ { :sound => 'aaa', :meaning => 'beginning of the universe', :god => 'Brahma' }, { :sound => 'ooo', :meaning => 'duration of the universe', :god => 'Vishnu' }, { :sound => 'mmm', :meaning => 'dissolution of the universe', :god => 'Shiva' } ] }
  • 53. require 'rubygems' require 'ohm' class AncientSymbol < Ohm::Model attribute :name attribute :description index :name collection :phonemes, Phoneme def validate assert_present :name end end
  • 54. class Phoneme < Ohm::Model attribute :sound attribute :meaning attribute :god index :sound index :god reference :ancient_symbol, AncientSymbol def validate assert_present :sound end end
  • 55. Ohm.connect symbol = AncientSymbol.create p symbol.valid? # false p symbol.errors # [[:name, :not_present]]
  • 56. error_messages = symbol.errors.present do |e| e.on [:name, :not_present] do "Symbols must have a name." end end
  • 57. symbol = AncientSymbol.new :name => 'Ohm' if symbol.save symbol.phonemes << Phoneme.create( :sound => 'aaa', :meaning => 'beginnging of universe', :god => 'Brahma', :ancient_symbol => symbol ) # ... end
  • 58. Cool, so how do find stuff?
  • 59.
  • 61. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]>
  • 62. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo'
  • 63. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]>
  • 64. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa'
  • 65. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]>
  • 66. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1]
  • 67. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa"
  • 68. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma">
  • 69. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol
  • 70. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol # <AncientSymbol:1 name="Ohm" description=nil>
  • 71. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol # <AncientSymbol:1 name="Ohm" description=nil> symbol.phonemes
  • 72. Phoneme.all # <Set (Phoneme): ["3", "1", "2"]> Phoneme.all.except :sound => 'ooo' # <Set (Phoneme): ["3", "1"]> Phoneme.find :sound => 'aaa' # <Set (Phoneme): ["1"]> pho = Phoneme[1] # <Phoneme:1 ancient_symbol_id="1" sound="aaa" meaning="beginnging of universe" god="Brahma"> pho.ancient_symbol # <AncientSymbol:1 name="Ohm" description=nil> symbol.phonemes # <Set (Phoneme): ["3", "1", "2"]>
  • 73. We also get sorting...
  • 74.
  • 76. symbol.phonemes.sort # [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>] symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' ) # [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>]
  • 77. symbol.phonemes.sort # [<Phoneme:1>, <Phoneme:2>, <Phoneme:3>] symbol.phonemes.sort_by( :sound, :order => 'ALPHA DESC' ) # [<Phoneme:2>, <Phoneme:3>, <Phoneme:1>] symbol.phonemes.sort_by( :sound, :get => :god ) # ["Shiva", "Brahma", "Vishnu"]
  • 78. What else can we do?
  • 79. Attribute types attribute set list counter reference collection
  • 80. Available validation assert_present assert_format assert_numeric assert_unique

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. We&amp;#x2019;re going to build up to why we need Ohm with an example of the pitfalls of trying to roll your own solution to interact with redis as a datastore.\n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. Get reference to database\n
  20. \n
  21. \n
  22. Awesome - we&amp;#x2019;re storing our information in redis!\nSo what&amp;#x2019;s wrong with this approach?\n
  23. \n
  24. The key we&amp;#x2019;re using for symbols isn&amp;#x2019;t adequate for multiple symbols...\n
  25. The key we&amp;#x2019;re using for symbols isn&amp;#x2019;t adequate for multiple symbols...\n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. Using a set because each element will be unique\nOrder isn&amp;#x2019;t important\n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. index: creates an index for an attribute you want to be able to search\ncollection: similar to has_many\n
  48. \n
  49. Validation behaves similarly to what we see in AR\nErrors are returned as an array of attributes and the associated failure\n
  50. Error messages are not defined within the model, but with a presenter\n\nerror_messages is just an array of errors\n
  51. Notice that the phoneme is added to the symbols phonemes\nAND a phoneme gets a reference to ancient_symbol\n
  52. \n
  53. All sets are created on the fly\n
  54. All sets are created on the fly\n
  55. All sets are created on the fly\n
  56. All sets are created on the fly\n
  57. All sets are created on the fly\n
  58. All sets are created on the fly\n
  59. All sets are created on the fly\n
  60. All sets are created on the fly\n
  61. All sets are created on the fly\n
  62. All sets are created on the fly\n
  63. All sets are created on the fly\n
  64. All sets are created on the fly\n
  65. All sets are created on the fly\n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. attribute-&gt;string set-&gt;unordered array list-&gt;array (great for queue) reference-&gt;foreign key collection-&gt;has_many\n
  72. \n
  73. Ohm contrib is a collection of drop-in modules\n
  74. \n
  75. \n
  76. \n