Rails Magazine Issue1

download Rails Magazine Issue1

of 36

Transcript of Rails Magazine Issue1

  • 8/8/2019 Rails Magazine Issue1

    1/36

    MyMagazneIe 1, Jly 00

    Extending Rails Trough Pluginsby John Yerhot

    Receiving E-Mail With Railsby Jason Seifer

    Delegation in Rubyby Khaled al Habache

    Subscription billing with Saasyby Alex MacCaw

    Making the Switch From RSpec to Shouldaby Dan Pickett

    Playing Hooky a.k.a. web hooksby John Nunemaker

    Adhearsionby Jason Goecke & Jay Phillips

    Rails Perormance Analysisby erry Heath

    Getting Started with JRuby

    and JRuby on Railsby Joshua Moore

    1

    ISSN 1916-8004 http://RailsMagazine.com

    http://railsmagazine.com/http://railsmagazine.com/
  • 8/8/2019 Rails Magazine Issue1

    2/36

    2

    Edtoral by Olimpiu Metiu

    Extendng Ral Trogh Plgn by John Yerhot

    Reevng EMal Wth Ral 4by Jason Seier

    Delegaton n Rby by Khaled al Habache

    Sbrpton bllng wth Saay 1by Alex MacCaw

    Makng the Swth From RSpe to Sholda16by Dan Pickett

    Playng Hooky aka web hook 1by John Nunemaker

    Adhearon by Jason Goecke & Jay Phillips

    Ral Perormane Analy by erry Heath

    Gettng Started wth JRby and JRby on Ral by Joshua Moore

    Edtoralby Olimpiu Metiu

    Welome to the rt edton o Ral Magazne, the rt andonlyree magazne dedated to the Rby on Ral ommnty!

    I yo are ntereted n a qalty omplaton o tmely,

    relevant artle, wth edtoral overght and beatl layot,pleae hek ot the magazne reglarly or brbe onlne

    Long beore lanh, I wa mpreed wth the level o nteretand reeptvene Ral alway had a vbrant and dedated ommnty, and I hope Ral Magazne wll beome an appreatedreore or thoe lookng or qalty normaton at the ametme provdng global expore to thoe ntereted n gettngpblhed

    009 hapng p to be a great year or Ral and t prattoner Contned adopton, and 0 releae and a globalreeon hold make Rby and Ral more appealng than ever,a entreprener and enterpre alke are trvng to beome

    more agle and oteetveRght now Ral Magazne a one man how, bt expet that

    to hange oon In at t a great opportnty, yo'd lke toget nvolved whle we're tartng Pleae pread the word abot, or get more nvolved a an athor, artt, ponor or partnerYor eedbak and nvolvement mh appreated, o pleaeget n toh wth at [email protected]

    Olimpiu Metiu a orontobaed arhtet andthe leader o the Emergent ehnologe grop atBell Canada H work nlde many o Canada'larget web te and ntranet portal A a longtme Ral enthat, he onded Ral Magazne aa way to gve bak to th amazng ommnty

    Follow me on wtter: http://twitter.com/olimpiuConnet on LnkedIn: http://www.linkedin.com/in/ometiu

    Discuss: http://railsmagazine.com/1/1

    Community PulseWe analyzed the repone t

    the Ral/Merb merger onthe oal Ral blog Twordle how the relt

    Content

    Editorial by Olimpiu Metiu

    2

    http://twitter.com/olimpiuhttp://www.linkedin.com/in/ometiuhttp://railsmagazine.com/1/1http://railsmagazine.com/1/1http://www.linkedin.com/in/ometiuhttp://twitter.com/olimpiu
  • 8/8/2019 Rails Magazine Issue1

    3/36

    Whle Ral a ll tak web ramework, by degn Raldoe not am to nlde every poble eatre Tere are manyreaon that the Ral Core eam wold hooe not to nlde a

    eatre too ntable, too obre, or mply not needed n theore Ral dtrbton In at, there have been ntane whereeatre have been removed rom Ral and plaed nto a plgn!For example, in_place_edit and auto_complete_for were removedrom Ral n veron 0

    o help developer who are lookng to add, replae, ormody Ral' eatre et, Ral ha been blt wth a hghly extenble nratrtre Mot addton and modaton ome aplgn Whle many plgn extend one o the major lae nRal, lke ActionView::Base or ActiveRecord::Base , yo are reeto reate yor own lae or modle Moreover, plgn anhave ther own Rake ak and tet Eentally, plgn are el

    ontaned Ral pe lbrare

    One o the bet way to e plgn the ree ode yond yorel ng rom projet to projet Robby Rell ha anexellent example h team at Planet Argon ed n ther applaton, Flah Meage Condtor Fndng that Ral' ah wanadeqate or ther applaton, they were rewrtng mh o trom applaton to applaton Te team reated a plgn thatadded helper to add meage, error, and note to ah anda new render_flash_messages method to render them n a vewBy ng Flah Meage Condtor n ther applaton, PlanetArgon ha an mproved ah, a ommon nterae, and n a veryDRY ahon

    For th artle, we wll ontrt a mple plgn that wlladd a qote method to or model Or goal very mplentonalty

    a = User.new

    a.quote

    => "If it bleeds, we can kill it."

    We wll reate a Rake tak to generate a YAML le wth orqote, load that YAML le and e the data or or qoteWhle th a arly trval plgn, my am not to teah yohow to wrte a large, omplex plgn, bt gve yo the tart yo

    need Let get tarted!

    Ral provde wth a generator or reatng plgn

    script/generate plugin quote

    T wll reate a bare plgn n yor vendor/plugin dretorywth the ollowng trtre:

    init.rb Loaded pon Ral tartng More ofen than not, twll reqre yor plgn le n the lb dretory

    install.rb Rn when yo ntall the plgn ng Ral'rpt/plgn ntall ommand

    lib/ Te lb dretory atomatally added to Ral' loadpath Ually yor plgn ode wll rede here

    MIT-LICENSE Yor plgn hold nlde a lene, MI orotherwe

    Rakefile Te man Rake denton or yor plgn

    README Yo plgn' readme A hort ynop o yorplgn, t age, and any other note wold go here

    tasks/ Any tom Rake tak an go here For or plgn,we wll reate one

    test/ Yor plgn' tet hold go here When tet are rnon a plgn, Ral not loaded

    Beore we go any rther, we hold reate a plan or howexatly or qote plgn hold work Frt, we hold reate aRake tak whh reate or YAML le lled wth qote Aferor Rake tak ompleted, we wll reate an ntrb le that wllreqre the or qoterb le n the lb dretory and load orqoteyml le nto an array o qote We wll reate a newModle, Quote::ClassMethods to hoe or new method, and addthoe method to ActiveRecord::Base a to be avalable n model

    John Yerhot lve n Northern Mnneotawth h we and dog where he ha been

    wrtng Ral applaton or the K1edaton ytem n Mnneota He

    mantan a blog at http://blog.john.yerhot.organd an be reahed [email protected]

    Extendng Ral Trogh Plgnby John Yerhot

    continued on page 15

    Extending Rails Trough Plugins by John Yerhot

    3

    http://blog.john.yerhot.org/http://blog.john.yerhot.org/
  • 8/8/2019 Rails Magazine Issue1

    4/36

    4

    4

    Reevng E-Mal Wth Ralby Jason Seier

    Introduction

    Reevng emal a great way to add ntonalty to yor

    applaton T one area, thogh, that not very well domented wth Ral Sre, we have AtonMaler domentaton,bt how doe omethng lke th atally work n a prodtonenvronment and what are the onern? I had to takle thproblem reently and no olton that wa n the wld woldwork wth the reqrement I had or th applaton In th artle, we wll take a look at a ople o opton and go n to detalwth one method that ha not reeved mh overage

    John Nnemaker, on the Ral p blog, poted a olton toth problem ng GMal wth IMAP to Reeve Emal n Ral1He e a rpt to onnet to an IMAP erver every mnte oro and poll or new emal Te Ral envronment loaded

    and there are new meage watng, th proeed ngan AtveReord model He e the Daemon lbrary to keepthe rpt rnnng and gve t tart/top ommand and keep apdle

    T a peretly vald and ntonal way to proe emalTe applaton I wa workng on, thogh, had to be able tohandle and proe emal n a lttle tme a poble Peoplewold lkely be emalng thng rom ther moble phone andmght want to hek on them oon afer an pload At that pont,pollng every X nmber o mnte wan't a vable olton, o Ihad to ome p wth omethng ele

    It' alo worth notng that pollng or emal hold take nto aont yor er bae and ze Let' ay that we have an appwth 10,000 atve er Let' alo ay that drng peak tme,theyalldede to emal or applaton Fnally, we'll ay thatthey are endng an average 5 emal apee Wth thee hypothetal nmber, th work ot to abot 833 emal per mnteI yor IMAP erver beng polled every three mnte, that'gong to leave yo abot 3,332 emal to download and proeeah tme

    1 http://railstips.org/2008/10/27/using-gmail-with-imap-to-receive-email-in-rails

    Jason Seier a web developer and halo Ral Envy He rrently lve n SothFlorda where he develop web applaton,prode the weekly Ral Envy podat,and oaonally tar n lly nternetvdeo He enjoy long walk on the beah,

    th, and poetry Yo an nd more o hm on the web at://railsenvy.com, h peronal blog at http://jasonseier.com, and ontter a 'jseier'

    Confguring Your Email Server

    Emal tel a problem that ha been largely olved Tere

    are a wealth o emal erver avalable bt th artle wll take alook at Potx Potx mot ealy ntalled ng the pakage manager o yor dtrbton and may already be ntalled yo have a VPS I preer Ubnt erver de o th artle wlo on that avor Jt be aware that ertan ongraton leloaton may vary dependng on yor dtrbton So let' gettarted

    Frt we need to add or hange ome DNS reord Tentrton or how to do th wll vary dependng on how yohave yor DNS hoted I peronally e DNS Made Easy and reommend t to my lent a well, hold they need DNS hotngDNS Made Easy ha very reaonable rate and qota Regardle

    o yor hot yo need to reate the ollowng reord:An A reord that ha yor doman name onlyAn A reord that jt mailAn MX reord that et to level 10 and pont to mailOptonal: An SPF reord

    OK, I wa lyng Te SPF reord n't really optonal T gong to be a X Reord and hold read omethng lke th:

    v=spf1 mx -all

    Tere are everal derent varaton yo an e wth SPFreord bt gong throgh them wold be beyond the ope oth artle Do ome reearh and pk the ombnaton that'

    rght or yor etp

    Now, the rt thng that yo're gong to need to do greot what addre yo want to reeve mal a T gong to beyor athall addre In th ae we're gong to hooe "kllerrobot" beae that jt mght keep pammer at bay I mean,who' gong to pam a kller robot?

    Readng ttoral arond the web or even lookng n omebook wll tell yo that yo an tell potx to orward malmply by ppng t n /et/alae Yo mght be tempted to do

    No t won't

    Receiving E-Mail With Rails by Jason Seifer

    4

    http://railsenvy.com/http://railsenvy.com/http://railsenvy.com/http://railsenvy.com/
  • 8/8/2019 Rails Magazine Issue1

    5/36

    omethng lke ppe everythng to a rby rpt:

    # /etc/aliases

    ...

    killerrobot: "|/usr/bin/ruby /var/www/apps/myapp/current/lib/

    mail_receiver.rb"

    *: killerrobot

    T, nortnately, won't work I yo do t th way, all oyor rpt are gong to rn a root T not what yo wantand an be a erty onern Te proper way to do th wtha potmap lter Open p /et/potx/mater Te rt lneafer all o the omment hold look lke th:

    Add a lne rght below that to tell potx that yo're ng alter:

    # /etc/postfix/master.cf

    smtp inet n - - - - smtpd

    # /etc/postfix/master.cf

    smtp inet n - - - - smtpd

    -o content_filter=myapp_filter:

    Ten go all the way down to the bottom o the le and addyor lter:

    # /etc/postfix/master.cf

    smtp inet n - - - - smtpd -o content_filter=myapp_filter:...

    myapp_filter unix - n n - - pipe

    flags=Xhq user=deploy argv=/usr/bin/ruby /var/www/apps/myapp/current/lib/mail_receiver.rb

    Te X parameter n flags=Xhq tell potx that an externalommand perorm nal delvery T gong to hange themeage tat rom relayed to delivered Te h ag etthe repent and doman to lowerae, and the q ag qotewhtepae and other peal harater Now, reload potx bydong sudo postfix reload At th pont, yo hold have a veryba mal erver ongred to reeve emal and pt t n to a

    mail_receiver.rb rpt

    Handling the Email

    We're gong to be pttng all o or mal that ome n to

    a meage qee and parng t wth the mmr gem In thartle I'm gong to e beanstalkd bt yo old bttte yoravorte meage qee or th part o the arhtetre I'm gongto ame that a meage qee already ntalled and rnnngand that yo have both the tmal and mmr gem ntalled

    We want or mail_receiver rpt to be per lean It' onlygong to erve one nton: pt the nomng mal n to a qeeWe'll proe the qee later bt or now we jt want to get t nthere and handle any attahment We want t to be per leanbeae we're reevng a lot o mal we don't want th rpt

    http://xph.us/soware/beanstalkd/

    to be memory ntenve or take a long tme to tart p or rn Itwll look omethng lke th:

    #!/usr/bin/env ruby

    require 'rubygems'

    require 'tmail'

    require 'mms2r'

    require 'beanstalk-client'

    message = $stdin.read

    mail = TMail::Mail.parse(message)

    mms = MMS2R::Media.new(mail)

    if !mail.to.nil?

    BEANSTALK = Beanstalk::Pool.new(['127.0.0.1:11300'])

    BEANSTALK.yput({:type => 'received_email',

    :to => mail.to.flatten.first.gsub('@mydomain.com', ''),

    :tags => mail.subject,

    :attachment => mms.default_media.path})

    end

    What we're dong here takng the emal meage romtandard npt and parng t by pttng t n to a Mal objetMal a great lbrary that take are o mot o the ormattng

    or It let do thng lkereer to mal meage a objet and e mail.to, mail.from,et I we have attahment,they're gong along a well

    MMSR an amazngpee o ofware It work or

    both emal and, a the name mple, MMS meage a wellWhat make t o amazng? Tere are dozen o derent ormat

    Breakthrough

    Receiving E-Mail With Rails by Jason Seifer

    5

  • 8/8/2019 Rails Magazine Issue1

    6/36

    6

    6

    that an attahment an ome n rom both emal and MMSDerent phone arrer eah have ther own way o dong MMSattahment, eah o them lghtly derent MMSR allevatethe problem o tryng to pare all o thee derent ormat anddoe t all or yo In th way we an all MMS2R::Media.new(mail) and be done wth t

    For the prpoe o or example applaton, the er an

    tag the photo they pload by pttng the derent tag n thebjet We end that n a another opton n the job hah orbeantalkd Eah er agned a nqe denter n theraont that let them end emal to the applaton, or example [email protected] We grab the rt repent (mail.to)beae that wll ome n a an array We take the doman otand end that n a the to eld Fnally, the temporary medaloaton on dk that we pared ng MMSR thrown n tothe qee a the :attachmentopton Or mal n the qee

    Processing the Queue

    Now that we have or emal n the qee, we need to get t

    ot For th part, we're atally gong to load the Ral envronment I have th n the lb dretory Te ode wold look

    omethng lke th:

    #!/usr/bin/env ruby

    require File.join(File.dirname(__FILE__), '..', 'config',

    'environment')

    require 'rubygems'

    require 'beanstalk-client'

    require 'yaml'

    beanstalk_config = YAML::load(File.open("#{RAILS_ROOT}/con-

    fig/beanstalk.yml"))

    @logger = Logger.new("#{RAILS_ROOT}/log/queue.#{Rails.env}.

    log")

    @logger.level = Logger::INFO

    BEANSTALK = Beanstalk::Pool.new(beanstalk_config[Rails.env]

    loop do

    job = BEANSTALK.reservejob_hash = job.ybody

    case job_hash[:type]

    when 'received_email'

    @logger.info("Got email: #{job_hash.inspect}")

    if EmailProcessor.process(job_hash)

    job.delete

    else

    @logger.warn("Did not process email: #{job_hash.in-

    spect}")

    job.bury

    end

    else

    @logger.warn("Don't know how to process #{job_hash.

    inspect}")

    end

    end

    Te rt lne load the Ral envronment o we have aeto all o or AtveReord model We want to keep or odeDRY and e only one method o proeng an attahment,rotng meage, or the lke I we were ng attahment_ opaperlp, we wold keep th ode n the model Yo mght eve

    want to make a eparate la, h a preenter, or yor logIn th ae the EmailProcessor la nd the er baed on the

    reception_email attrbte and then exete the do_stuff methodto proe the meage It wold look omethng lke th:

    require 'local_file'

    require 'tmail'

    require 'mms2r'

    class EmailProcessor

    attr_accessor :user, :options

    W

    hyareyousobad?

    Receiving E-Mail With Rails by Jason Seifer

    6

  • 8/8/2019 Rails Magazine Issue1

    7/36

    7

    def self.process(*args)

    email_processor = new(*args)

    email_processor.do_stuff

    end

    def find_user@user = User.find(:first, :conditions => {:reception_

    email => @options[:to]})

    end

    def do_stuff

    # Your actual logic would go here...

    end

    def initialize(*args)

    @options = args.extract_options!

    find_user

    end

    end

    T e the LocalFile la rom Ben Rbenten4

    We're not qte done yet We need to make the mail_processorrn a a daemon ntead o jt rnnng ruby mail_processor.rb when we want to lanh t We'll e the daemons lbrary orthat T wll take are o ettng p PID le and let do rubymail_processor_control.rb start and ruby mail_processor_control.rb stop We're alo ng the daemons_extension le rom Rapleathat atally gve eedbak on toppng o the daemon Terpt tel extremely mple and goe n the lib dretory wthyor mail_processor.rb rpt:

    require 'rubygems'

    require 'daemons'

    require File.join(File.dirname(__FILE__), 'daemons_exten-

    sion')

    ENV['RAILS_ENV'] ||= 'development'

    options = {

    :app_name => 'processor',:dir_mode => :script,

    :dir => '../log',

    :backtrace => true,

    :mode => :load,

    :monitor => true

    }

    Daemons.run(File.join(File.dirname(__FILE__), 'processor.

    4 http://www.benr75.com/articles/2008/01/04/attachment_u-now-with-local-le-u

    rb'), options)

    Now jt tart t by dong ruby mail_processor_control.rbstart and yor daemon wll be p and rnnng Tat' t! Yo'rereevng emal to yor Ral app

    Considerations

    Dependng on yor ongraton, yo may want to e aderent meage qee than beantalkd I've peronally ondbeantalkd to be relable bt yor arhtetre mght all oromethng ele For example, yo may want to pt yor meageqee on another erver I yo dd th then yo woldn't haveae to the temporary torage that MMSR dealt to or avng the attahment In that ae yo old e a qee and ptthe attahment dretly n the qee, on , et

    Some people have reported problem ng the daemonlbrary and havng ther daemon jt halt and top repondng I've never enontered that and I've had th mlar etprnnng or month Yo wll alo want to pt yor mal_proe

    or_ontrol nder ome ort o proe pervon, h a bymont or god

    Y

    ellowHeart

    Receiving E-Mail With Rails by Jason Seifer

    7

    http://www.benr75.com/articles/2008/01/04/attachment_fu-now-with-local-file-fuhttp://www.benr75.com/articles/2008/01/04/attachment_fu-now-with-local-file-fuhttp://www.benr75.com/articles/2008/01/04/attachment_fu-now-with-local-file-fuhttp://www.benr75.com/articles/2008/01/04/attachment_fu-now-with-local-file-fu
  • 8/8/2019 Rails Magazine Issue1

    8/36

    8

    Delegaton n Rbyby Khaled al Habache

    Separate hangeable part rom other that reman theame and ompoton preerred to nhertane are twoommon degn prnple when yo tart degnng n OOP

    world However and whle the rt eem logal, one mghtwonder why t' preerable to e ompoton over nhertaneand that' a logal qeton, o let' anwer t va an example

    Let' ppoe that we have a Robot that ha a heat enor, onwold wrte a very mple UML:

    T degn ha everal drawbak:

    1 Tere a trong probablty to have another type o robothat don't have heat enor (break the rt degn prnple:eparate hangeable ode rom tat one)

    Whenever I want to mody anythng related to the heatenor, I have to hange the robot la (break the rt degnprnple)

    Expore o heat enor method to n Robot la

    Let' enhane th la a bt:

    Well, now th an nhertane baed degn and t olve thrt problem, bt t' tll napable to olve the other problemrelated to the heat enor Let' do another enhanement:

    Yo may be akng yorel why we ddn't e AtonMalerto handle the nomng emal ne t doe that? Te anwer that yo do t the way t' derbed, or example, on the Ralwk, t wll pn p a new Ral proe or eah emal that'reeved Under any gnant load, th wll al Anotherdrawbak to that approah that there a alre, yo loe theemal Wth th type o arhtetre, t reman n the qee andyo an jt proe t later

    Conclusion

    T a good tart to handlng emal n yor applaton Beng able to proe emal a great way to enhane yor app andgve yor er moble ae Wth emalapable phone beomng bqto, they no longer need to be ted to a ompterto e yor app Remember, an app that an be ed anywhere an app that wll be ed anywhere

    Beae ral an't ale See http://canrailsscale.comor more normaton

    Discuss: http://railsmagazine.com/1/2

    Street Shelving

    Robot

    Operations+ measure_heat(): int+ start_heat_sensor(): void

    + stop_heat_sensor(): void

    Attributes

    VolcanoRobot

    Operations+ measure_heat(): int+ start_heat_sensor(): void+ stop_heat_sensor(): void

    Attributes

    Robot

    OperationsAttributes

    Receiving E-Mail With Rails by Jason Seifer

    8

    http://canrailsscale.com/http://railsmagazine.com/1/2http://railsmagazine.com/1/2http://canrailsscale.com/
  • 8/8/2019 Rails Magazine Issue1

    9/36

    9

    Now th a typal degn, baed on ompoton ratherthan nhertane, where we old olve the above problem,and moreover we ganed a new thng: we an now abtrat theHeatSenor or tre e

    Now what is delegation?

    Delegaton the proe o delegatng ntonalty to theontaned part

    I yo look arelly at the prevo gre, yo wll notethat the VolanoRobot tll ha the method related to the enor; thoe are wrapper method, they do nothng bt all to the

    enor orrepondng method Tat' exatly what delegaton, jt orwardng ntonalty to the ontaned part (delegate)

    Delegaton ome along wth ompoton to provde exble and elegant olton lke the one we had above, and alo terve the prnple eparate hangeable ode rom tat one,bt t alo ome wth a tax: the need or wrapper method, andextra tme needed n proeng beae o the all to theewrapper method

    Ruby and delegation

    Now let' take a look at a ode example:We have a mlt prpoe Robot that ha an arm and a heat

    enor Te robot doe everal job, lke pakagng boxe, takng them and mearng the heat

    We wll e ompoton and delegaton a ollow:

    class Robot

    def initialize

    @heat_sensor = HeatSensor.new

    @arm = RobotArm.new

    end

    def measure_heat(scale="c")@heat_sensor.measure(scale)

    end

    def stack(boxes_number=1)

    @arm.stack(boxes_number)

    end

    def package

    @arm.package

    end

    end

    class HeatSensor

    # Celsius or Fahrenheit scale

    def measure(scale="c")

    t = rand(100)

    t = scale=="c" ? t : t * (9/5)

    puts "Heat is #{t} #{scale.upcase}"

    end

    end

    class RobotArm

    def stack(boxes_number=1)

    puts "Stacking #{boxes_number} box(es)"

    end

    def package

    puts "Packaging"

    end

    end

    robo = Robot.new #=>#

    robo.stack 2 #=>Stacking 2 box(es)

    robo.package #=>Packaging

    robo.measure_heat #=> Heat is 59 C

    A yo an ee, I have wrapper method(tak, pakage andmeare_heat) n Robot la that are dong nothng bt to all

    VolcanoRobot

    Operations+ measure_heat(): int

    + start_heat_sensor(): void+ stop_heat_sensor(): void

    Attributes- heat_sensor: HeatSensor

    Robot

    OperationsAttributes

    HeatSensor

    Operations+ measure(): int+ start(): void+ stop(): void

    Attributes

    Delegation in Ruby by Khaled al Habache

    9

  • 8/8/2019 Rails Magazine Issue1

    10/36

    10

    10

    the ontaned objet orrepondng method

    T a naty thng, epeally when there are lot o ontaned objet

    However two lbrare ome to the ree n Rby: Forwardable and Delegate Let' hek ot eah o them

    Forwardable lib

    Forwardable lb lbrary that pport delegaton, t ha modle Forwardable and SngleForwardable

    Forwardable module

    Te Forwardable modle provde delegaton o peedmethod to a degnated objet, ng the method de_delegatorand de_delegator

    def_delegator(obj, method, alias = method): Dene a methodmethod whh delegate to obj I ala provded, t ed athe name or the delegate method

    def_delegators(obj, *methods): Shortt or denng mltpledelegator method, bt wth no provon or ng a derentname

    Let' reator or robot example to make t Forwardablemodle:

    require 'forwardable'

    class Robot

    # Extending provides class methods

    extend Forwardable

    # Use of def_delegators

    def_delegators :@arm,:package,:stack

    # Use of def_delegator

    def_delegator :@heat_sensor, :measure ,:measure_heat

    def initialize

    @heat_sensor = HeatSensor.new

    @arm = RobotArm.new

    end

    end

    class HeatSensor

    #Celsius or Fahrenheit scale

    def measure(scale="c")

    t = rand(100)

    t = scale=="c" ? t : t * (9/5)

    puts "Heat is #{t} #{scale.upcase}"

    end

    end

    class RobotArm

    def stack(boxes_number=1)

    puts "Stacking #{boxes_number} box(es)"

    end

    def package

    puts "Packaging"

    end

    end

    Well, that' a neater olton a yo an ee

    SingleForwardable moduleTe SngleForwardable modle provde delegaton o pe

    ed method to a degnated objet, ng the method de_delegator and de_delegator T modle mlar to Forwardable, bt t work on objet themelve, ntead o ther dennlae

    require "forwardable"

    require "date"

    date = Date.today #=> #

    # Prepare object for delegation

    date.extend SingleForwardable #=> #

    # Add delegation for Time.now

    date.def_delegator :Time, "now","with_time"

    puts date.with_time #=>Thu Jan 01 23:03:04 +0200 2009

    KingStreet-RestaurantRow

    Delegation in Ruby by Khaled al Habache

    10

  • 8/8/2019 Rails Magazine Issue1

    11/36

    11

    Delegate Lib

    Delegate lb another lb that provde delegaton, 'll explantwo way to e t

    DelegateClass method

    Ue the top level DelegateCla method, whh allow yo to

    ealy etp delegaton throgh la nhertane In the ollowng example, I want to make a new la alled CrrentDate,whh hold the rrent date and ome extra method, at theame tme I'm delegatng to normal date objet:

    require "delegate"

    require "date"

    # Notice the class definition

    class CurrentDate < DelegateClass(Date)

    def initialize

    @date = Date.today

    # Pass the object to be delegated to the superclass.super(@date)

    end

    def to_s

    @date.strftime "%Y/%m/%d"

    end

    def with_time

    Time.now

    end

    end

    cdate = CurrentDate.new

    # Notice how delegation works

    # Instead of using cdate.date.day and defining

    # attr_accessor for the date, I use c.day

    puts cdate.day #=>1

    puts cdate.month #=>1

    puts cdate.year #=>2009

    # Testing added methods

    # to_sputs cdate #=> 2009/01/01

    puts cdate.with_time #=> Thu Jan 01 23:22:20 +0200 2009

    SimpleDelegator class

    Ue t to delegate to an objet that mght be hanged:

    require "delegate"

    require "date"

    today = Date.today #=> #

    yesterday = today - 1 #=> #

    date = SimpleDelegator.new(today) #=> #

    puts date #=>2009-01-01

    # Use __setobj__ to change the delegate

    date.__setobj__(yesterday)#=> #

    puts date #=>2008-12-31

    A yo an ee, we made objet and then delegated tothem oneqently

    What about Rails?

    Ral add new ntonalty alled delegate, whh provde a delegate la method to ealy expoe ontaned objetmethod a yor own Pa one or more method (peed aymbol or trng) and the name o the target objet a the nal:to opton (alo a ymbol or trng) At leat one method and the:to opton are reqred

    Delegation in Ruby by Khaled al Habache

    11

  • 8/8/2019 Rails Magazine Issue1

    12/36

    1

    12

    Go to yor onole and reate a dmmy projet, then cd tothat projet and re the ral console:

    $ rails dummy

    ...

    $ cd dummy

    $ruby script/console

    Loading development environment (Rails 2.2.2)

    >> Person = Struct.new(:name, :address)

    => Person

    >> class Invoice < Struct.new(:client)

    >> delegate :name, :address, :to => :client

    >> end

    => [:name, :address]

    >> john_doe = Person.new("John Doe", "Vimmersvej 13")

    => #

    >> invoice = Invoice.new(john_doe)

    => #

    >> invoice.name

    => John Doe

    >> invoice.address

    =>Vimmersvej 13

    I trongly rge yo to hek the whole provded example nral API domentaton, to alo ee how to e th eetvely

    wth AtveReordBeore I nh th artle I want to hare wth yo the ode

    o delegate method rom ral API domentaton I'll add omeomment on the ode to explan what gong on:

    class Module

    # Delegate method

    # It expects an array of arguments that contains

    # the methods to be delegated and a hash of options

    def delegate(*methods)

    # Pop up the options hash from arguments array

    Khaled al Habache a ofwareengneer, workng or d1g.com a a deptyprojet manager and a enor RoR engneerA an or openore and bg projet,andreearh baed work

    Crrently gvng part o h tme or Rbyommnty and other web related work on h blog:http://www.khelll.com

    options = methods.pop

    # Check the availability of the options hash

    # and more specifically the :to option

    # Raises an error if one of them is not there

    unless options.is_a?(Hash) && to = options[:to]

    raise ArgumentError, "Delegation needs a target. Sup-

    ply an options hash with a :to key as the last argument (e.g.

    delegate :hello, :to => :greeter)."

    end

    # Make sure the :to option follows syntax rules

    # for method names

    if options[:prefix] == true && options[:to].to_s =~

    /^[^a-z_]/

    raise ArgumentError, "Can only automatically set the

    delegation prefix when delegating to a method."

    end

    # Set the real prefix value

    prefix = options[:prefix] && "#{options[:prefix] == tru

    ? to : options[:prefix]}_"

    # Here comes the magic of ruby :)

    # Reflection techniques are used here:

    # module_eval is used to add new methods on the fly whic

    # expose the contained methods' objects

    methods.each do |method|

    module_eval("def #{prefix}#{method}(*args, &block)\

    n#{to}.__send__(#{method.inspect}, *args, &block)\nend\n", "(__

    DELEGATION__)", 1)

    end

    end

    end

    Tat' t or th artle, we have overed pont:1 Compoton v nhertane What delegaton , and why t' ed Rby Forwardable lb4 Rby Delegate lb Ral delegate method

    Discuss: http://railsmagazine.com/1/3

    Delegation in Ruby by Khaled al Habache

    12

    http://www.khelll.com/http://railsmagazine.com/1/3http://railsmagazine.com/1/3http://www.khelll.com/
  • 8/8/2019 Rails Magazine Issue1

    13/36

    1

    Sbrpton bllng wth Saayby Alex MacCaw

    Sofware a a erve (SaaS) ha reently beome qte apoplar bne model and, n h a tmlto nanal lmate, t predtable nome nvalable However, brpton

    bllng an be trky (and borng) to etp and there are lot optall along the way Hopelly th artle wth help yo avodthem, and ave yo a bt o tme nto the bargan!

    o harge Credt Card yoll need:A orporate bank aontMerhant aontGateway aont

    Yor merhant aont atally a bank aont, bt notone yo an ae dretly Tey have agreement wth the major bank o they an perorm the redtard tranaton Yorgateway pae on yor tomer redt ard to the merhant

    aont, and addtonally ome wll tore thoe detal o yoan harge the ard later

    Yo holdnt attempt to tore the ard detal yorel Iyo do, yoll have to be PCI omplant, or er hge ne Itmh better to let yor gateway handle all o that

    Tere are Rby lbrare, h a AtveMerhant, thatabtrat mot o the gateway o yo an deal wth a ommonnterae

    However, mplementng brpton bllng tll a panSome o the gateway oer ther own brpton bllngmehanm bt gettng notaton when a harge hant gone

    throgh an be notoroly trky A good alternatve to rn abllng rpt nghtly whh goe throgh all the aont, hekto ee theyre bllng yle omng to a loe, and bll them applable Tat way, yo have total ontrol on who yo bll,and when yo bll Addtonally t make advaned thng lkerend and dont ode mh eaer to mplement

    T where Saay ome n Saay an open ore Ralapp that deal wth aont reaton, er athentaton andbrpton bllng Saay wll alo end ot all the maler oryo, generate nvoe, and deal wth aled harge

    Saay e AtveMerhant (wth a ew tweak) n the bakgrond, and rrently pport the ollowng gateway:

    BrantreertCommerePaymentExpre

    It degned a a deopled omponent that rn eparatelyrom yor SaaS erve (althogh they hare the ame DB) Tknd o arhtetre gettng more poplar, where yor app aere o agle deopled omponent, whh an be hared anddeveloped wthot endng p wth an nweldy ma o ode

    Saay alo at a a Sngle Sgn On (SSO), whh yoll needto ntegrate wth to athentate er Te advantage o th

    that yo dont need to wrte (or generate) more athentatonode and yor er an tay gned n aro all yor erve,even theyre on derent doman

    Initial setupIm amng yove already got Rby ntalled on yor

    mahne, bt not there are nmero artle onlne howngyo how

    Frtly yoll need to open a termnal and download Saay Iyore ng Gt, rn th:

    git clone git://github.com/maccman/saasy.git

    I dont have Gt, yo an download a Saay tarball o thegithub.com te (http://github.com/maccman/saasy)

    Ral and the gem Saay rele pon are all vendorzed, o

    yo dont need to worry abot ntallng them

    Ten opy the dealt ongraton le to ther orretloaton, lke th:

    cp config/database.example.yml config/database.yml

    cp config/application.example.yml config/application.yml

    cp config/subscription.example.yml config/subscription.yml

    Te dealt ongraton wll be ne to tart o wth, we anhange t later

    Te next tep to load the databae hema nto a Sqlte db,rn:

    rake db:schema:load

    Now were ready to tart the erver:

    script/server

    Tat all there to ettng p Saay; navgate to http://local-host:3000/signup

    Fll n the gnp orm, and e the ollowng dmmy redtard detal:

    ype: VisaNmber: 4111111111111111CVS: 999

    Alex MacCaw a Prototypng Developer orMade by Many (http://madebymany.co.uk), oal

    meda pealt baed n London He' manlya Rby developer, bt delve nto lot o other

    langage and area onernng applaton degnand mplementaton H peronal te http://eribiu

    Subscription billing with Saasy by Alex MacCaw

    13

    http://madebymany.co.uk/http://eribium.org/http://eribium.org/http://madebymany.co.uk/
  • 8/8/2019 Rails Magazine Issue1

    14/36

    14

    14

    So, the gnp valdaton paed, yoll be ent to the lognreen wth a prompt to hek yor nbox However, ne th rnnng n the Ral development envronment, that emal wllnever be ent o yoll have to hek the log whh wll ontanthe raw emal, and navgate to the atvaton rl manally

    One yor aont ha been atvated, and yove gnedn, yoll be lookng at yor prole management page Have an

    explore o the varo vew, epeally the bllng oneYoll note Saay ome wth a dealt blak theme yoll haveto tomze th to t n wth yor own te degn Lkewewth the gnp, and plan page

    By dealt Saay e a gateway alled Brantree a they allowandbox developng wthot regterng an aont wth themYo an hange the gateway n config/subscription.yml Tatalo the ongraton le where yo pey the plan yo want,ther draton and pre amont other thng I yo have a lookat the dealt everythng hold be arly el explanatory

    Te other ongraton le, config/application.yml , pee

    more applaton pe ettng h a the applaton name,doman and malng addre

    Integrating Saasy with your SaaS service

    One o the other benef Saay provde yo wth a SSO(Sngle Sgn On), o yo dont need to repeat athentaton oden all yor app, and yo an tay DRY At the moment, Saaye a tom SSO protool, ne I wa keen to keep t a mplea poble, wth only one rond reqet T may hange to awdely reogned SSO protool there are lot o all or t

    Im amng that the app yore ntegratng wth Saay

    alo a Ral te, not yoll have to look loer at the protoolto replate t Alo, the SSO lbrary I wrote alo ame yoventalled the RetlAthentaton plgn, whh yo an get to gthb (http://github.com/technoweenie/restul-authentication/tree)

    Copylib/sso.rb rom Saay to yor other app In app/control-lers/application.rb , yoll need to add th ongraton:

    include SSO::Client

    sso({

    :secret => sso_secret,

    :salt => sso_salt,

    :login_url => saas_site + /login,:logout_url => saas_site + /logout,

    :callback_url => app_site + /sessions/sso

    })

    Obvoly yoll need to replae thoe vale wth the realone Te eret and alt hold be derent, random nmber yo an generate them wth a rake tak alled eret Telogin_url wll need to pont to the logn rl o Saay, lkewe thelogout_url need to be et to Saay logot aton Te callback_url need to pont to an SSO aton (whh we havent made yet),on th applaton

    Yoll need to edt Saay config/application.yml le, o the

    sso_secret and sso_salt math the one yo added to the ontroler Tee are the hared eret ed to generate hekm orthe SSO, and o need to be the ame

    Create a ba Seon ontroller ontanng the ollowngode:

    class SessionsController < ApplicationController

    def new

    redirect_to sso_login_url

    end

    def destroy

    logout_killing_session!

    redirect_to sso_logout_url

    end

    def sso

    head(401) and return unless sso_valid_token?

    flash[:notice] = Logged in successfully

    redirect_back_or_default(/)

    end

    end

    Toe SSO pe method are provded by nldng

    Saasy::Client, whh we dd n application.rb A yo an ee,there gnantly le ode there than yod normally needor athentaton (not to menton the User model) Tere tll problem wth the ode thogh:

    One weve athorzed the lent n the method sso, we tlldont know whh one t , o we need to do an addtonal reqet too Saay Were gong to e AtveReore to do that:

    class RemoteUser < ActiveResource::Base

    class_inheritable_accessor :headers

    self.site = saas_site

    self.element_name = user

    class :current)

    end

    end

    end

    Te above what yoll need to nlde n app/models/remoteuser.rb Te reaon Im ng the la name RemoteUser, ratherthan User, to prevent lobberng o an extng User model ( ext)

    Now we an all jt User.current_user n the ontroller, andtll eth the rrent er rom Saay

    Make the SessionsController#sso method look lke th:

    Subscription billing with Saasy by Alex MacCaw

    14

    http://github.com/technoweenie/restful-authentication/treehttp://github.com/technoweenie/restful-authentication/treehttp://github.com/technoweenie/restful-authentication/treehttp://github.com/technoweenie/restful-authentication/tree
  • 8/8/2019 Rails Magazine Issue1

    15/36

    1

    def sso

    head(401) and return unless sso_valid_token?

    RemoteUser.headers =

    {Authorization => sso_header_token}

    remote_user = RemoteUser.current_user

    self.current_user = User.find(remote_user.id)

    flash[:notice] = Logged in successfullyredirect_back_or_default(/)

    end

    Yo an ee were ettng the header on RemoteUser, o Saayknow whh er were talkng abot Were then ettng cur-rent_user, whh an RetlAthentaton method, o that er d tay n the eon, and doent need athentaton everytme they make a reqet

    I yo jt want an overvew o the omplete ode, thereome domentaton n lib/sso.rb and ode example too

    And now, Im arad, a dlamer: Saay only a ew weekold, tll alpha and hant yet been ed n a prodton envronment Tat ad, thng are progreng qkly, and Im plannngon ng Saay n my own ommeral te, socialmod.com anatomated moderaton erve whh rrently n a prvatebeta Hopelly, wth the pport o the open ore ommnty,well have a prodton ready ramework oon

    I yore lookng or a more robt and teted olton, trythe Ral Kt SaaS app (http://railskits.com/saas/) whh habeen arond or qte a whle

    So, that a bre ntrodton to Saay, I hope t aved yoa bt o tme renventng the wheel by wrtng yor own bllngramework

    Resourceshttp://www.slash7.com/jumpstarthttp://letsreckle.com/blog/2008/12/ecommerce-stu/http://www.activemerchant.org/http://railskits.com/saas/http://particletree.com/notebook/processing-online-credit-card-transactions/http://www.37signals.com/svn/posts/753-ask-37signals-how-do-you-process-credit-cards

    http://activereload.net/2007/5/17/dealing-with-subscription-paymentshttp://www.setremedia.com/blog/7-top-tips-or-coding-with-currency

    Discuss: http://railsmagazine.com/1/4

    We wll alo ame that yo have a bare applaton wth aUer model

    Frt, let look at or tak/qote_takrake le We need tort reate a new namepae or or plgn, and add a etp tak

    namespace :quote do

    desc "Create Quotes YAML file in the config directory"

    task(:setup) do

    end

    end

    Or tak only need to reate a YAML le, o we wll eRby' Fle lbrary to reate or le and the pt method to wrteto t

    namespace :quote do

    desc "Create Quotes YML file in the config direcory"

    task(:setup) do

    puts "Creating #{RAILS_ROOT}/config/quotes.yml"

    quotes = File.new("#{RAILS_ROOT}/config/quotes.yml", "w")

    quotes.puts(

    "0: Come with me if you wanna live! \n1: If it bleeds,

    we can kill it.\n2: Its not a tumor!"

    )

    end

    end

    ry rnnng the tak and yo hold ee a newly generatedYAML le n yor ong/ dretory

    rake quote:setup

    Next, we wll get or ntrb le n order A mentonedbeore, th loaded pon Ral' ntalzaton, ntrb rn Wehold do any reqre and n or ae, open AtveReord andnlde or new method

    require "quote.rb"

    ActiveRecord::Base.send :include, Quote::ClassMethods

    Great Let tart on the n part! Open p lb/qoterb Anyreal mag gong to happen here In a larger plgn, we wllprobably e derent le or or derent lae or modle,bt or or we wll only need to e qoterb or or nglemethod

    # Quote

    module Quote

    module ClassMethods

    # displays a random quote frou our quotes.yml

    continued rom page 3

    continued on page 35

    Extendng Ralthrogh plgn

    Subscription billing with Saasy by Alex MacCaw

    15

    http://socialmod.com/http://railskits.com/saas/http://www.slash7.com/jumpstarthttp://letsfreckle.com/blog/2008/12/ecommerce-stuff/http://www.activemerchant.org/http://railskits.com/saas/http://particletree.com/notebook/processing-online-credit-card-transactions/http://particletree.com/notebook/processing-online-credit-card-transactions/http://www.37signals.com/svn/posts/753-ask-37signals-how-do-you-process-credit-cardshttp://www.37signals.com/svn/posts/753-ask-37signals-how-do-you-process-credit-cardshttp://activereload.net/2007/5/17/dealing-with-subscription-paymentshttp://activereload.net/2007/5/17/dealing-with-subscription-paymentshttp://www.setfiremedia.com/blog/7-top-tips-for-coding-with-currencyhttp://www.setfiremedia.com/blog/7-top-tips-for-coding-with-currencyhttp://railsmagazine.com/1/4http://railsmagazine.com/1/4http://www.setfiremedia.com/blog/7-top-tips-for-coding-with-currencyhttp://www.setfiremedia.com/blog/7-top-tips-for-coding-with-currencyhttp://activereload.net/2007/5/17/dealing-with-subscription-paymentshttp://activereload.net/2007/5/17/dealing-with-subscription-paymentshttp://www.37signals.com/svn/posts/753-ask-37signals-how-do-you-process-credit-cardshttp://www.37signals.com/svn/posts/753-ask-37signals-how-do-you-process-credit-cardshttp://particletree.com/notebook/processing-online-credit-card-transactions/http://particletree.com/notebook/processing-online-credit-card-transactions/http://railskits.com/saas/http://www.activemerchant.org/http://letsfreckle.com/blog/2008/12/ecommerce-stuff/http://www.slash7.com/jumpstarthttp://railskits.com/saas/http://socialmod.com/
  • 8/8/2019 Rails Magazine Issue1

    16/36

    16

    16

    Makng the Swth From RSpe to Sholdaby Dan Pickett

    Tank to Bryan Lle, we now know the anwer to theqeton, "When hold we tet?" An mportant qeton thatreman, however, "How hold I tet?" Whle th qte a

    loaded qeton, there are ome ramework avalable to help For a long tme, I wa marred to RSpe Wrtng behavorworked well or my workow and I ame to appreate the yntax Srely, we were meant to be together orever n DD blTe honeymoon ddn't lat, thogh Te deet o random pealre and the erey behnd Spe::Rnner raed ome qeton A eret tetng aar ened I tarted ng Sholda onall my pet projet Maro and tom aerton tempted meaway rom RSpe For the pat two month, all my new projettart wth Sholda, and I haven't looked bak, ne

    Why I Made the Switch

    Pror to doverng Sholda, my toolkt or tetng onted o RSpe or behavor, atory_grl or model generaton,atotet to keep the tet rnnng, and Moha or mokng andtbbng ogether, thee tool worked very well or me

    One weekend, I wa odng away on or projet or the 00Ral Rmble Wth great DD rhythm, I wa blatng throghbehavor and ther orrepondng mplementaton I wa wrtng atore and tbbng nder lke t wa nobody' bneA I wa movng along, I realzed I needed an athentatonmehanm, and de to the tme rnh, I tarted to ntegrateRESl Athentaton Ep alre ollowed Valable tme nthe 4 hor odeathon wa lot Why? RESl Athentaton generated a ere o Spe ng RSpe' natve mokngramework Sne I wa ng Moha, the generated pe orathentaton aled Afer watng an hor or two o valabletme, I old not make derent pe tlze derent ramework or mokng and tbbng Why? Spe::Rnner an takea ongraton opton alled mock_with Unortnately, wthota lot o hakng, I old not alter th ongraton bak andorth or pe example What I ame to realze that ng

    A Prnpal at Enlght Solton, In,

    Dan Pickett a reelaner and onltantn Boton, MA He heavly ntereted n theproe o ofware development and Aglemethodologe Dan ha been programmng

    wth Rby and Ral or three year Heha been reponble or the tehnologalhtetre and leaderhp behnd te lke wwwgazelleom andwrghtatalogom Dan ha a paon or leaderhp, and makngeloper better by evangelzng bet prate h goal

    derent mok ramework n the ame tet te n't eay Inmy opnon, th a ndamental problem wth the way RSpe wrtten I ddn't have tme to hange RESl Athentaton

    generated tet to tlze Moha, and I needed the overage orthe athentaton pee o my applaton In deeat, I had toomment ot all my athentaton tet and I lot overage orthe athentaton porton o my applaton T wa the natraw or Spe::Rnner and I

    I Shoulda used Shoulda

    Comng bak to et::Unt eqpped wth a ramework habeen great Yo an ntermngle tandard et::Unt tet wthholda blok Yo an bld yor own abtrat tet lae wthelper method and maro Generally, t' a lot more omortable or me to be workng wth a la trtre n my tet te

    In trantonng ome o my model pe to nt tet wthSholda, AtveReord maro or valdaton dereaed lneont gnantly It wa eay to wrte tom aerton aganand I ddn't have to add and remove a bnh o le afer rnnng script/generate

    describe Band do

    it "should have a name" do

    band = Factory.build(:band, :name => "")

    band.save.should be_false

    band.errors.size.should eql(1)

    end

    it "should have a unique name" do

    band = Factory(:band)

    band_2 = Factory.build(:band, :name => band.name)

    band_2.save.should be_false

    end

    it "could have a list of albums" do

    band = Factory(:band)

    album = Factory(:album, :band => band)

    album_2 = Factory(:album, :band => band)

    band.albums.size.should eql(2)

    end

    end

    trn to:

    class BandTest < ActiveSupport::TestCase

    context "a band" do

    setup do

    @band = Factory(:band)

    Note: ome o th normatonno longer apple de to reendevelopment n Sholda andRSpe Pleae hek or artl

    don area or more detal

    Making the Switch From RSpec to Shoulda by Dan Pickett

    16

    http://www.gazelle.com/http://www.frightcatalog.com/http://www.frightcatalog.com/http://www.gazelle.com/
  • 8/8/2019 Rails Magazine Issue1

    17/36

    17

    end

    should_require_attribute :name

    should_require_unique_attribute :name

    should_have_many :albums

    end

    end

    AtveReord::Maro provde a great deal o tlty Indegnng my model, I've ond should_have_db_column and theaoaton maro to be extremely el pror to generatngmgraton should_protect_attribute alo a great tlty thathelp yo to protet oregn key and other ere attrbterom ma agnment

    What I Shoulda Known

    Tere' a ew thng I learned along the way that I wh Iknew earler n my tranton

    I don't ally e Sholda' maro or my ntonal tetTey generally relt n ode mell when I want to et expetaton pror to ng the reqet For example, gven the ollowng ontext:

    context "when creating a user" do

    setup do

    post :create, :user => {:login => "jsmith",

    :password => "secret",

    :password_confirmation => "secret"}

    end

    should_respond_with :redirect

    end

    I I want to add an expetaton that the ontroller wll attempt to ave the reord, I an't really aomplh t leanlybeae the reqet ed n the etp blok Generally Ijt wrte my own hold tatement or ntonal tetng Teexample above wth the addton o the ave expetaton woldlook omethng lke th:

    context "when creating a user" do

    setup do

    @user = Factory.build(:user)

    User.stubs(:new).returns(@user)

    end

    should "redirect" do

    do_create_post

    assert_response :redirect

    end

    should "attempt to save the user" do

    @user.expects(:save).returns(true)

    do_create_post

    end

    end

    def do_create_post(user_attrs = {})

    post :create, :user => {:login => "jsmith", :password =>

    "secret", :password_confirmation => "secret"}.merge(user_attrs)

    end

    Alo, Sholda' valdate_nqene_o reqre a reord nthe table or t to rn One the tet broke, t wa eay to greot, bt t may tmp yo or a bt

    Tere' a great projet athored by Jeremy MAnally onGtHb alled Mathy It gve yo ome o the yntat garo RSpe' hold tatement nde et::Unt T wold havebeen el n movng my pe nto et::Unt and SholdaBeware, thogh, I beleve the hold =~ /regex/ never al (t'on my todo lt to wrte a path)

    What I Miss

    RSpe erved me well or a long tme Now that I've movedon to Sholda, there' dentely a ew thng to m

    Te before(:all) blok wa great n RSpe Sholda' etpblok rn or every hold tatement, where before(:all) wllexete one or a gven et o example Te perormane gann rnnng large tet te wth a before(:all) ntead o abefore(:each) wa ne when t wa avalable

    Whle t' not really an e wth Sholda' mplementatontel, I m the ablty to rn oed example n extMate TeRn Foed Shold bndle tem n Sholda' extMate bndlebreak wth a SytemStakError or me I an rn ndvdalexample n the ommand lne, bt not beng able to rn themn my edtor an be a bt o a nane In addton, I appreatedthe readablty o the RSpe Relt wndow n extMate

    Whle ore pport or tetng helper gettng better wthlae lke ActionView::TestCase , Helper tetng wa a bt morenttve or me n RSpe In tetng my helper wth Sholda, ttook a hak and a path to ore n order to get *_path and *_rlmethod workng or ActionView::TestCase.

    What You Should Know

    RSpe and Sholda are great ramework blt by martdeveloper I yo're ng a ramework and yo're wrtng tetbeore yo wrte mplementaton, yo're on the rght trakEah ramework ha t pro and on, and my ntent here wanot to be perave abot any ngle ramework, bt to doment my experene n makng the wth

    I yo're onderng the wth rom RSpe to Sholda orve vera, onder thee element arelly and what the ot omgratng a tet te ental Tey both get the job done, and I'veopted to leave a ew o my projet wth an RSpe tet te mply beae the tme nvetment n mgratng them to Sholdawold take too mh tme and eort A a developer yo holdalway onder the ot o yor eort relatve to ther benetalk t over wth yor team and enre that everyone omortable and ompetent enogh beore tlzng a new rameworkAnd don't orget, AF

    Discuss: http://railsmagazine.com/1/5

    Making the Switch From RSpec to Shoulda by Dan Pickett

    17

    http://railsmagazine.com/1/5http://railsmagazine.com/1/5
  • 8/8/2019 Rails Magazine Issue1

    18/36

    1

    18

    Playng Hooky a.k.a. web hookby John Nunemaker

    From everythng that I have read and experened, webhook are aweome! Tey let developer ealy extend andntegrate web applaton and allow er to reeve event and

    data n realtme Yep, realtme No pollng here olk So whatare web hook? Let tart wth example, ollowed by theory, andthen ap t o wth ode

    Examples

    Te bet example o web hook, that yo wold mot lkelybe amlar wth, GtHb GtHb ha a erve tab n theadmn o eah repotory that allow yo to end potommthook to URL whh yo pey Tey even have a handl oprerolled hook, h a Baeamp, Campre, Emal, FogBgz, IRC, Jabber, Lghthoe and wtter, and have even openored the ode

    Another example yo may be amlar wth, that ha beenarond a lttle longer, PayPal' Intant Payment Notaton(IPN) IPN " PayPal' nterae or handlng realtme prhaeonrmaton and ervertoerver ommnaton" aordngto PayPal' webte ranlated to Englh, PayPal end a reqetto a URL yo pey whenever omeone omplete a tranaton Ryan Bate ha a ew antat reenat on PayPal' IPNon Railscasts.com

    GtHb and PayPal are two great example, bt what abot awellknown applaton that doe not e web hook and oldbenet? Te rt that ome to mnd or me Feedbrner, a

    erve that provde tatt o brber ont and more oreed It pdate thee nmber one daly, yet there are probablythoand o dektop and web applaton that repeatedly pollthe Feedbrner Awarene API throghot the day

    Imagne , ntead o pollng Feedbrner' API, developerold jt provde Feedbrner wth a URL o ther hoongOne a day, when Feedbrner nhed reatng the daly mmare, they old pot realtme reqet to the developer'URL wth normaton abot the mmary No more ron job orthe developer and no more pollng the API or pdate Feedbrner mply ay, Hey, we jt pdated the tatt or th

    John Nunemaker paonate,drven and addted to new He a partner at Ordered Lt (http://orderedlist.com), where he doe h betto reate mple, able webte andweb applaton He alo athor a wellknown Rby and Ral programmngblog, Ralp (http://railstips.org)

    eed, here yo go Jt lke that, the developer an ealy yn Feedbrner data n ther applaton or end realtme notaton to thoe that are tat addt lke me

    red o wrtng the ode and ettng p nratrtre to reeve emal n yor web app? Rk Olon (aka tehnoweene)re wa Tat why he reated Atrotran, a mroapp thatend hook by way o an HP Pot reqet or a Jabber meage whenever an emal reeved An ntane o Atrotran atally power the emal ntonalty o Lghthoe and endertwo poplar app that Rk ha worked on

    Te poblte are pretty mh endle wth web hook anthee example are jt the tp o an eberg Now, we have proothat real ompane are ng web hook I don't know abotyo, bt I'm releved t n't jt a razy ad How abot we dve

    n a bt more wth ome theory?

    Teory

    A whle bak, when I rt tarted dong reearh abot webhook, there wa one graph that really made thng lk orme It ompare a nx program to a web applaton o gveredt where redt de, th graph' orgnal orm wa roma preentaton by Je Lnday, who, a ar a I an tell, oned thterm web hook

    STDIN STDOUTProgram

    API HooksWeb App

    Program vs Webapp

    A the gre above lltrate, an API or a web applaton mh lke SDIN or a nx program Tey both help get data bt what abot gettng t ot? Sre, yo an get data ot wth anAPI, bt only throgh pollng, whh not realtme I'll explath more n a e, bt trt me when I ay that pollng k

    Unx program, on the other hand, have SDOU, whh allow ppng ommand together (e: gem list | grep rails) Eanx program omplete a pe, mple tak that alone notoverly peal, bt the m o them workng together greaterthan the part What do web app have that allow th knd orealtme hanng?

    Nowaday, mot web app have eed and/or ome ort oAPI that allow yo to poll or pdate, bt th not the anweWhy hold we have to ak? Te app know when t ha newdata, why an't we jt tell t to gve the data rght away? Iam a val learner, o let take a look qk at the derenebetween pollng and phng

    Playing Hooky a.k.a. web hooks by John Nunemaker

    18

    http://orderedlist.com/http://orderedlist.com/http://railstips.org/http://railstips.org/http://orderedlist.com/http://orderedlist.com/
  • 8/8/2019 Rails Magazine Issue1

    19/36

    https://RightSignature.com/p/RM1

    https://rightsignature.com/p/RM1https://rightsignature.com/p/RM1http://www.elctech.com/?src=railsmagazine
  • 8/8/2019 Rails Magazine Issue1

    20/36

    0

    20

    Polling vs. Pushing Now that we ndertand what we are gong to reate, letgenerate the two app and ome aoldng to help get the ponaro qkly

    rails webhook_sender

    cd webhook_sender

    ruby script/generate scaffold Widget name:string

    rake db:migrate

    cd ..

    rails webhook_receiver

    cd webhook_receiver

    ruby script/generate scaffold Message body:text

    rake db:migrate

    cd ..

    At th pont, we have two app webhook_ender ha wdget, whh have jt a name, and webhook_reever ha meage wth a body to tore the meage ontent Let tart wth the

    webhook_ender app, mplementng the ntonalty to end aHP reqet (web hook) whenever a wdget get moded

    ending Hooks

    We old e AtveReord allbak or th ntonalty, bt Ral atally ha a bltn mehanm or th type othng known a oberver I yo aren't amlar wth oberver,they are lae that repond to leyle allbak, reate, pdatand detroy to name a ew, to mplement trggerlke behavorotde o the orgnal la (the Wdget model)

    cd webhook_sender

    ruby script/generate observer Widget

    Now tart p yor avorte edtor and open p the le app/models/widget_observer.rb All we have to do reate methodname that are mlar to the AtveReord allbak we want tohook nto

    class WidgetObserver < ActiveRecord::Observer

    def after_create(record)

    send_hook(record, :create)

    end

    def after_update(record)

    send_hook(record, :update)end

    def after_destroy(record)

    send_hook(record, :destroy)

    end

    private

    def send_hook(record, operation)

    uri = URI.parse('http://localhost:3001/hooks/create')

    Somethingnew

    Somethingnew

    Somethingnew

    Thanks! Thanks! Thanks!

    Any

    thin

    gne

    w?

    No

    Anythi

    ngnew

    ?No

    Anythi

    ngnew

    ?

    You

    Web App

    Polling

    You

    Web App

    Pushing

    Widget

    Modified

    Send

    Hook

    Receive

    Hook

    Process

    Hook

    Sending

    App

    Receiving

    App

    By phng new data when an event happen, the web applaton no longer ha to at lke a ather drng a long ar trp,ontantly tellng , the developer, "Not Yet!" Alo, we androp the annoyng kd at, ontnally akng, "Are we thereyet?" Pretty ool Ph better than pll Get t, got t, good

    How Can We Push Data?

    Now we know that ph better than pll, bt how an wept th nto prate? One poplar way to ph realtme dataarond XMPP (Extenble Meagng and Preene Protool,e: Jabber) XMPP great, bt t a heavyweght Yo wll needanother erver and to learn another protool

    Woldn't t be ne we old e a protool that we alreadyknew? Enter web hook Web hook, n ther mot mple orm,are ph over http Below an example o the mot mple webhook yo an reate ng Rby

    require 'net/http'

    Net::HTTP.post_form(URI.parse(url), {

    'from' => message.from,

    'to' => message.to,

    'subject' => message.subject,

    'body' => message.body

    })

    I yo an add omethng lke the ode above nto yorapplaton, yo an mplement web hook Enogh wth theexample and theory, let do ome odng!

    CodeFor the ode porton o th artle, we are gong to bld an

    app that end web hook and a eond app that reeve andproee thoe hook o help ndertand the proe, let takea look at one more val

    Playing Hooky a.k.a. web hooks by John Nunemaker

    20

  • 8/8/2019 Rails Magazine Issue1

    21/36

    1

    Net::HTTP.post_form(uri, {

    'id' => record.id,

    'name' => record.name,

    'operation' => operation

    })

    end

    end

    Te nal thng beore we tart p or endng app thatwe need to tell Ral that or WdgetOberver hold alway bernnng Open p ong/envronmentrb and add the ollownglne:

    config.active_record.observers = :widget_observer

    Or app now aware o or WdgetOberver at all tme andready to tart endng web hook Let tart th bad boy p!

    ruby script/server

    Receiving Hooks

    Now that or ender app p and rnnng, let get orreevng app whpped nto hape Frt, we are gong to need aontroller to reeve the ent hook Open p a new termnal tab(or wndow) and rn the ollowng ommand

    cd webhook_receiver

    ruby script/generate controller Hooks

    Next, we need an aton n that ontroller to reeve the hookmeage and proe t Open p app/ontroller/hook_ontrollerrb and hange t to the ollowng

    class HooksController < ApplicationController

    protect_from_forgery :except => :create

    def create

    body = params.except(:action, :controller)

    Message.create(:body => body)

    render :nothing => true

    end

    end

    Beae Ral ome wth CroSte Reqet Forgery (CSRF)proteton, we need to tell th ontroller to kp that, otherwewe'll get nvald athentty token error when reevng the

    hook

    In the reate aton, we reate the meage and then rendernothng Remember that or endng applaton doen't are we reeve th meage or not, t jt end the meage, thereore :nothing a peretly approprate repone Note alo thatwe exlded the param key :action and :controller a thoe donot matter at all or the hook

    We have now reated wdget, et the wdget to end hookwhen they are moded, and reated an applaton to reeveand proe thoe hook Let tart p or webhook_reeverapp a well, bt on port 001, o that t doe not ont wth or

    rrently rnnng webhook_ender app

    ruby script/server -p 3001

    Everythng hold be p and rnnng and hooked togetherorretly, bt let hek t n a brower jt to be re Open ptwo tab (or wndow) n yor brower o hoe, the rt tohttp://localhost:3000/widgets and the eond tohttp://localhost:3001/messages

    Create a new wdget n the rt tab, ng the "New wdget" lnk and then rereh the meage tab Yo hold ee thenew meage n the lt Congratlaton! Yo jt reated andreeved yor rt web hook

    Beyond Te Basics

    T a very mple example o that t an be ndertoodby a broader adene, bt I hope that yo get the dea o howpowerl and exble web hook an be Tat ad, yo are gong to tart mplementng hook nto yor app, yo wll want toonder the ollowng

    nterface for Managing

    ypally, yo hold oer an nterae or er to denether own web hook URL ntead o hard odng the rl n theWdgetOberver When I ay nterae, I am not neearlyreerrng to a web nterae An API wold be a peretly aeptable way o reatng, pdatng and deletng web hook Yo wllalo want to pport mltple hook per er and mltple erTe example I provded doe not

    Queue the ending

    A good prnple to lve by n applaton development

    omethng an be moved ot o the reqet/repone yle, dot! I I were gong to mplement hook lke th n a prodtonapplaton, ntead o endng the net/http reqet n the WdgetOberver, I wold qee t, ng delayed_job or ome othermehanm

    Te benet o qeeng thee hook two old Frt, yomove the pobly low proe o endng the hook otde othe reqet/repone yle T mean the er reatng thedata ng the web nterae do not have to wat or hook to beent beore gong abot ther bne T partlarly mportant the brbng erver ot o ommon or rnnnglow

    Seond, what one o the brbng erver down? I yoare dong a one or nothng reqet, the brber wll m otand have to poll or the med data On the other hand, yoqee the hook, yo an leave t n yor qee and keep tryngntl the brber repond wth e Shopy' wk pageon web hook explan how they leave the reqet n the qeentl the brbng erver repond wth a el repone,and even provde a mple example

    Playing Hooky a.k.a. web hooks by John Nunemaker

    21

  • 8/8/2019 Rails Magazine Issue1

    22/36

    22

    Toughts on ecurity

    Te other thng yo may have noted n the example ode that t wold be really eay to poo a hook to the reevngapp Shopy take the mple rote by provdng yo wth a key,whh yo an hek beore proeng the hook, th weedngot poble attak and pder PayPal goe to the extreme, allowng yo to et p SSL ertate and enrypt the data beng

    ent For mot app, a mple key or ba athentaton holdbe ne Yo wll have to dede what level o erty bet oryo and yor app' er

    Conclusion

    Web hook are the mot mple way to add realtme notaton to yor web applaton and they are not jt or HP AGtHb' erve and Atrotran how, yo an end web hookng a varety o ormat (HP, Emal, Jabber, IRC)

    Tere are alo ome very nteretng applaton poppng p,Swthb and AppJet or tarter, that deal olely wth reevng

    npt, proeng that npt and then generatng otpt Imagne a world where web applaton an be pped together n theame ahon a Unx program Tat get me exted abot thetre!

    Discuss: http://railsmagazine.com/1/6

    Coming Up..

    Ruby&

    RailsConerences

    I leave yo, not wth a powerl tatement that hok yorol, bt rather a lt o related lnk n hope that th artle halef yo wantng

    ResourcesJe Lindsay on Web Hooks (he eem to have oned the term)

    Inspiring and Mind Opening Slideshow by Je LindsayGitHub's post-receive hooksandservices codePayPal' IPN

    Astrotrain by Rk Olon (Lighthouse and ender)Shopiy Wiki Web HooksWeb Hooks WikiRailscast on PayPal NoticationsSwitchhub Push content around the web

    AppJet Instant web programmingDelayed Gratication with Rails

    Feb 15 Mar 1 Mar 15 Mar 29 Apr 12 Apr 26 May 10 May 24 Jun 7 Jun 21 Jul 5 Jul 19 Aug 2 Aug 1

    EuRuKo

    Locos X Rails

    MountainWest RubyConf

    RailsCamp (Brisbane)

    LA Ruby Conf

    Acts As Conference

    RailsConf

    Scotland on Rails

    Art and Code

    DSL Developers Conference

    Ruby on OS X

    RubyFringe

    RubyRx

    Golden Gate Ruby Conference

    Rails Underground

    Playing Hooky a.k.a. web hooks by John Nunemaker

    22

    http://railsmagazine.com/1/6http://blogrium.com/?s=web+hookshttp://www.slideshare.net/progrium/web-hooks-and-the-programmable-world-of-tomorrow-presentationhttp://github.com/guides/post-receive-hookshttp://github.com/pjhyett/github-services/tree/masterhttps://www.paypal.com/ipnhttp://github.com/entp/astrotrain/tree/masterhttp://lighthouseapp.com/http://tenderapp.com/http://wiki.shopify.com/WebHookhttp://webhooks.pbwiki.com/http://railscasts.com/episodes/142-paypal-notificationshttp://switchub.com/http://appjet.com/http://railstips.org/2008/11/19/delayed-gratification-with-railshttp://railstips.org/2008/11/19/delayed-gratification-with-railshttp://appjet.com/http://switchub.com/http://railscasts.com/episodes/142-paypal-notificationshttp://webhooks.pbwiki.com/http://wiki.shopify.com/WebHookhttp://tenderapp.com/http://lighthouseapp.com/http://github.com/entp/astrotrain/tree/masterhttps://www.paypal.com/ipnhttp://github.com/pjhyett/github-services/tree/masterhttp://github.com/guides/post-receive-hookshttp://www.slideshare.net/progrium/web-hooks-and-the-programmable-world-of-tomorrow-presentationhttp://blogrium.com/?s=web+hookshttp://railsmagazine.com/1/6
  • 8/8/2019 Rails Magazine Issue1

    23/36

    Adhearonby Jason Goecke & Jay Phillips

    What is Adhearsion?

    elephony development ha gnant e today It tend

    to be ragmented, ardo, and reqre a teep learnng rveo ndertandng propretary protool, jargon and lmted APITee e are exaperated by the teleom ndtry e o propretary ytem and nexble bne model T preventthe teleom ndtry rom keepng p wth nnovaton happenng elewhere, epeally n modern web development

    Adhearon a new way to wrte voeenabled applatonwth Rby It a omplete openore Rbybaed ramework,not jt an API or lbrary, that provde all o the neearyeatre to develop omprehenve voeenabled applatonFor example, one mght bld an Adhearon applaton wth aRal nterae or managng an nternatonal teh pport team

    Or maybe yo want to e a phone all a a CAPCHA ytem(onrmng the phone nmber at the ame tme) Or maybeyore omng home wth groere and want to nlok yordoor by allng yor hoe and enterng a paode Beae anAdhearon applaton ndamentally a voeenabled Rbyapplaton, there are vrtally no lmt to what may be done

    oday Adhearon work n tandem wth the Aterk openore telephony engne, mantanng Aterk a the ore telephony wthng platorm whle provdng an applaton layeratop t Te latet releae o Adhearon ome wth a omponentarhtetre that allow or ealy wrtng plgn that may behared among the Adhearon ommnty

    What is Asterisk?

    Aterk an openore telephony engne and toolktWth repet to Adhearon, Aterk provde pport oronvertng between ado ode, telephony protool, andprovdng lowerlevel abtraton o telephony ntonalty Aterk may be molded nto many applaton, romoe PBX ytem, to onerene allng erver to voemalytem Tere generally a teep learnng rve to gettarted developng applaton wth Aterk Tere are alodegn e n varo apet o the engne that make nga development ramework or extendng t more approprate

    or ale and tablty

    Te latet releae o Adhearon ome wth a ere oenhanement T nlde a new omponent arhtetre thatallow or ealy wrtng plgn that may be hared among theAdhearon ommnty A omplete rework o how Adhearon nterae to the Aterk Manager API (a protool edor reevng event and ng varo ommand) that e adynam thread pool, a well a Ragel to reate a tate mahnethat pare the protool eently provdng great alabltyAdhearon ha an extng roadmap that rapdly evolvng theramework or addtonal eatre and pport o more telephony engne

    Hello, World!

    Let dve rght nto the aton and wrte or rt Hello World

    applaton Intall the Adhearon gem by mply dong

    $ sudo gem install adhearsion

    Now that yo have Adhearon ntalled yo have the ahnommand that ed to generate, top and tart applaton awell a to reate, enable and dable omponent Yo an vewage normaton by dong

    $ ahn --help

    Let reate yor rt applaton by enterng

    $ ahn create ~/my_first_app

    T mlar to eneratng a Ral applaton wth the ral

    ommand Yo wll ee the program prnt ot a lt o le t jtreated n the my_first_app older Te next tep to wre yorapplaton to e the Adhearon Sandbox that avalable ordeveloper jt gettng tarted Te Sandbox allow yo to oon Adhearon, wthot havng to worry abot ettng p thenderlyng telephony ytem, gettng yo o and rnnng wthmnmal rton For th, yo mt gn p or a ree aont at:

    http://new.adhearsion.com/getting_started

    Aont are reqred to e the andbox beae nomngall need ome way o ndng yo ndvdally Afer yo have

    Jay Phillips ha the nteretng poton obeng a Rby programmer and telephony hakerat the ame tme H nteret n thee two eld

    led hm to reate theAdhearsion rameworkto help brng Rby' ltre to the orthodox

    teleom ndtry and olve ome o therendrng problem wth openore ofware

    Jason Goecke ha a long htory n telephonyH nqe perpetve blt on extenve

    bne experene arond the world a wella tehnal depth H paon or drpton

    manet tel n h ongong pport o openore telephony, wth the latet phae beng h

    ommtment to theAdhearsion projet

    Adhearsion by Jason Goecke & Jay Phillips

    23

    http://adhearsion.com/http://adhearsion.com/
  • 8/8/2019 Rails Magazine Issue1

    24/36

    4

    24

    yor aont, the next tep to enable the Sandbox omponentprovded wth Adhearon by dealt rom wthn yor

    my_first_app dretory:

    $ ahn enable component sandbox

    One yo have done th, yo hold then edt the~/my_first_app/components/sandbox/sandbox.yml le and enter yorredental yo reated on the gnp orm:

    username: railsrockstar

    password: rubyislove

    Were almot there! Let tart the applaton next by dong

    $ ahn start .

    Te next tep to mody the ~/my_first_app/dialplan.rb le,whh the le that ontan the DSL or handlng all nbondall wth realtme all ontrol method When yo open the leyo hold ee omethng lke th:

    adhearsion {

    simon_game

    }

    Add th to the bottom o the dialplan.rb le:

    sandbox {

    play hello-world

    }

    When a all ome nto the Sandbox, ontrol o t wll bepeally orwarded to yor Adhearon applaton rnnngon yor ytem Te ontext n dialplan.rb (adhearon andandbox n the example above) pey many entry pont ntowhh all may ome and, by dealt, the andbox tart exetng the andbox ontext Te helloworld Strng reerene atandard Aterk ond le we have on the andbox that wll bplayed bak to yo when yo all

    Te next tep to etp Voe over IP (VoIP) phone ofwa(alled a ofphone) on yor ompter Tere are many reeofphone to hooe rom, bt we reommend ng Gzmo(http://www.gizmo5.com) ne t doe a good job o dealng wtrewall e and work on Wndow, OSX and Lnx Yollneed to alo gn p or a ree Gzmo aont (the lat gnp,we prome) bt t atally qte el beae Gzmo erver

    wll help yo avod rewall e One yo have ntalled andongred Gzmo, all yo need to do now dal yor Sandboaont o do th, mply enter the ollowng nto the Gzmotext eld near the top o the man Gzmo wndow:

    [email protected]

    Tat t! I all went well yo hold now hear a woman ayHello, world! Let now try bldng a more ophtated applaton ng Ral

    Rails Integration

    Whle Adhearon a tandalone ramework, t may ea

    ly be ntegrated wth Ral to leverage all o the bne logtked away n the Ral model Sne Adhearon and Ral rn ther own nterpreter ntane, havng meagng reqredor harng tate aro yor applaton reqred beyondyor model For th, Adhearon lly pport DtrbtedRby (DRb), a Stomp meage qee a well a a et o RESlAPI by dealt

    o load Ral model and a databae envronment n theAdhearon applaton yo reated above, yo mody the

    config/startup.rb le a ollow:

    config.enable_rails :path => 'gui', :env => :development

    In the above lne the :path mply the path to yor rootRal dretory, th may be an abolte path or a ymbol lnk,and o ore the :env whh envronment rom database.ymlyo wold lke to e Ral and Adhearon wll rn a eparateproee wth ther own Rby nterpreter bt now both applaton hare the ame nderlyng model

    Now let ee how we may leverage th Let ay yo have aRal applaton that allow er to gnp and lten to peally reorded ado le on yor podatng webte Yo mghave a model that looked omethng lke th:

    First Nations 1

    Adhearsion by Jason Goecke & Jay Phillips

    24

  • 8/8/2019 Rails Magazine Issue1

    25/36

    class User < ActiveRecord::Base

    validates_presence_of :password

    validates_uniqueness_of :password

    has_many :podcasts, :order => created_at desc

    end

    class Podcast

    belongs_to :userend

    Now, rom the ame dialplan.rb we moded n the HelloWorld example above, we may enter the ollowng:

    podcast_content {

    password = input 5,

    :play => please-enter-your-pin-number,

    :timeout => 5.seconds

    user = User.find_by_password(password)

    if user

    play {user.id}/#{user.podcasts.first.id}

    else

    play vm-invalidpassword

    play goodbye

    end

    hangup

    }

    In the example above we how the ablty to ak the er aqeton and then reeve the dgt entered on ther phone nthe input method, where :play repreent the ado le to akthe qeton, :timeout the amont o tme n eond the erha to npt beore the reqet tme ot

    Now th a ontrved enaro, bt t provde a good avoro how Adhearon may leverage the model not only wthn aRal app bt anythng that may benet rom the e o AtveReord, or any other way o aeng hared tate Yo old beng CohDB, DRb, a meage qee, XMLRPC nterae, anLDAP lbrary or any other ntegratonorented tehnology

    Conclusion

    Adhearon a powerl ramework that brng voe to themodern web We have only overed a handl o the apabltehere and there o mh more to explore Adhearon may beed to generate otbond all, leverage exttoSpeeh (S)and Atomat Speeh Reognton (ASR) engne, provde advaned apablte to all enter, enable eamle voe enabledweb erve and applaton, the lt old go on Te lmtreally yor magnaton

    Htorally ndng a developer that old ro the weband voe doman wa a rare breed T no longer need to betre or the Ral ommnty Te tre potental o Adhearon

    to allow a Ral developer to extend ther apablte beyondthe web to nlde voe wth mnmal rton Not only mayyo leverage th n yor own applaton, bt n thoe o yortomer Wth yor new ond ablty to nlde all ormo ommnaton, yo have the opportnty to be a thoghtleader and reate more opportnte wth yor extng engagement and beyond

    We welome everyone to jon and get tarted addng nnovatve voe olton to yor web applaton Yo wll ndmore example by vtng the Adhearon projet (http://ad-hearsion.com) where yo may alo nd the API domentaton(http://api.adhearsion.com) and the wk (http://docs.adhearison.com)

    Discuss: http://railsmagazine.com/1/7

    Do Not Break Glass

    Adhearsion by Jason Goecke & Jay Phillips

    25

    http://api.adhearsion.com/http://docs.adhearison.com/http://docs.adhearison.com/http://railsmagazine.com/1/7http://railsmagazine.com/1/7http://docs.adhearison.com/http://docs.adhearison.com/http://api.adhearsion.com/
  • 8/8/2019 Rails Magazine Issue1

    26/36

    6

    26

    Ral Perormane Analyby erry Heath

    Introduction

    One o my avorte apet o development perormane

    work Te tak, wth the aoated prolng and benhmarktool, lend tel well to ent analy

    Uablty and appearane are alway bjetve, and have,at bet, zzy gdelne Perormane mearement are mhmore pree

    Im gong to gve an overvew o how to approah perormane analy, and the tool aoated wth the derent peethat orm an applaton I havent gone nto anythng arane,beae that wold take th artle rom t preent orm to athree pond paperbak at Barne & Noble

    Measurement

    umbers, not Feelings

    Beore I tarted readng abot perormane, bt wa takedwth optmzng omethng, Id go wth whether or not t eltat Whle th a omewhat aeptable way to determne omethng need to be optmzed, t not a good meare ooptmzaton

    Afer pttng hard work nto ome optmzaton, yore gongto want to ee mprovement So mh, o, that lef only to yorown ene, odd are yore gong to ee mprovement Even yove made thng wore Beae o th, t mportant to go bybenhmarkng and prolng tool, and not eelng

    Another reaon t mportant to rely on tool and not eel

    ng that they allow yo to hone n on what atally lowTere are a lot o thng that go on n a web reqet, an examplebeng yo end a reqet to Apahe, whh orward t to Mongrel, whh pn p ome Rby aton, whh then ppe t bakto yor lent Yo mght ee omethng n yor bakend odeand ay, I know that low, Im gong to peed t p Unortnately, wthot a baelne mearement, yo (1) dont know howmh the mprovement wll help, and () yo ant be re that tneed mprovement

    Nmber jty everythng Wthot them, t hard to explan to other what exatly yove been dong or a week

    erry Heath a Ral developer workng nAtn, exa He keep a blog that ometme talkabot Ral at terrbear.org

    tatistics

    I wa lky enogh to take a tatt la n ollege Lky

    n that t wa an eay A Unortnately, I dont remember mhele abot t Im amng yore n abot the ame poton

    Togh I thnk t taght a anaxom or omethng abot ampleze, n aal onveraton Iveheard t reerened a the law omall nmber Eentally, yodont have enogh ample, yoant be entrely re what yoremearng Yo old be mearng the tme o Rby garbageolletor, when yo really want to ee how long a regex math

    takng T woldnt only lead to narate relt, bt t mghmgde yor optmzaton eort In hort, rnnng a tet motme better

    Whle takng tattal mearement, t mportant to rede onondng ator Anythng that old nterere wth thnmber yore gatherng an kew yor data I yore rnnnga benhmark loally, loe down other applaton Agan, thard to know yore atally mearng Rby regex mathng peed yove got Lord o the Rng playng on ne andare playng ower Deene on Freox Maybe plang that watetower jt hogged ome CPU tme, makng yor Rby lowdown Te tmer wont know, and nether wll yo

    I yore tetng erver throghpt, be re that yore tetna loe a poble to the mahne I yo have a blng erverthat eet rom t, that better, beae yore not mearngother roter peed or blak hole nternet pot

    Latly, when preentng yor mearement, allate atandard devaton along wth the mean T nredbly mportant A tandard devaton ndate how ar mearementdevate rom the mean One tandard devaton wll over almo70% o the pont, and a eond tandard devaton wll over90% Togh there no blt n Rby tandard devaton allaton, Ive provded one below [0]

    I yo have a reqet that how t only takng hal a eonon average, yo an thnk, th great, or applaton oat! Bt yo ople that wth the related tandard devaton, and t 1 eond, yo know ome people are watng alot longer than hal a eond T old reveal omethng lkeome bakend ode hangng or a rae ondton that jt a meawoldnt provde

    Rails

    Important o note that all three area ded (bakend,rontend, erver ong) an dretly and gnantly aet per

    o jot your memory...

    Mean:

    Standard devaton:

    x=1

    n

    i=1

    n

    xi

    =E XE X

    Rails Performance Analysis by erry Heath

    26

    http://terrbear.org/http://terrbear.org/
  • 8/8/2019 Rails Magazine Issue1

    27/36

    7

    ormane Lkly, both Ral and the ront end an be dagnoedand proled ndvdally, o we dont have to play domnoe wthor tweak

    Server ongraton and tweakng, or example, the nmbero mongrel to rn on a erver, ant be done nqely A bak

    end proeng an nreae both the memory onmpton or amongrel and the tme or a mongrel to nblok, the Ral de othng need to be tweaked rt

    Where to look?

    Te rt tak to gre ot what need optmzng A goodplae to look the prodton log, ne theyll how wherepeople are pendng tme and how mh tme the erver takng to do t

    Tere a ne lookng tool alled PL Analyzer [1], part o theRal Analyzer te, bt t doent work ot o the box on OSX,whh I work on It alo provde a eparate et o data, o I go

    wth one I wrote a whle ago, alled logpwnr []

    Logpwnr wll provde thorogh mearement o all atonbeng ed n yor app I yo have everal prodton erver,yoll need to onatenate the log beore parng them wthlogpwnr Rn t lke th:

    ./logpwnr.rb production.log > output.csv

    T wll provde a CSV yo an mport to any preadheetHere a ample o the otpt:

    Here we an tart lookng at what ed the mot, and thengre ot whh o thoe aton a good plae to tart optmzng baed on total reqet tme (not provded on the reenhot,bt t the m o the mean o the aton, render, and db tme)ry to keep the nmber n the ontext o age Tere mght bea horrendoly low aton n yor app, bt t only been ed tme n a many month Optmzng rarely ed aton notworth yor tme ntl yor poplar one are ped p

    Further Down the Rabbit Hole

    One we nd an aton that look approprate to optmze,we an gre ot how to approah the problem wth RbyProRbyPro partly mantaned by Charle Savage [], who pttogether one o the bet qk gde or peedng p Ral [4]He alo provde a antat ntallaton gde or RbyPro []

    One aveat that yore ng Ral

  • 8/8/2019 Rails Magazine Issue1

    28/36

    28

    And a ew o my own:Alway do hek on loggng tatement, eg: logger.debug (n Controller#new) if logger.debug? th mportant to prevent nneeary and ometme expenveto_ all, and alo hort rt extra method all n aprodton envronment; dont omment ot logger tatement, a theyre el or, yo know, debggngAvod ele Ral helper (HML tag ater andjt a eay a Ral image_tag)Avod nneeded objet opyng (lke wth gsub) when poble, ng detrtve alternatve (gsub!)

    Frontend Optimization

    A antat analytal tool or load tme or a web page YSlow [7], a tool pt ot by Yahoo a an addon to Frebg []YSlow ore yor page aro everal rtera and make reommendaton or how to peed p yor te

    A per at te on the bakend wth a terrble YSlow orewll generally eem lggh to er

    One o the eaet thng to do hrnk yor javarpt andCSS I yo e a tool lke aet pakager [9], yo an have yorprodton javarpt and CSS le onatenated and mned,reqrng only extra download or yor er T a bgwn, beae t both hrnkng bandwdth reqrement and thenmber o download neeary to vew a page Mot browerome prepared to only download le rom a hot at a tme, oewer download almot alway helpl

    In yor Apahe ong, and then all tat aet wll be gvenwth that header At work, we ond a problem wth the Expre

    Dealt lae and IE7, where even reqet proxed throgh toMongrel were beng ahed, o we went more explt, replangthe ExpiresDefault lae wth:

    ExpiresByType image/gif "access 10 years"

    ExpiresByType image/jpg "access 10 years"

    ExpiresByType image/png "access 10 years"

    ExpiresByType text/css "access 10 years"

    ExpiresByType text/javascript "access 10 years"

    One gotha wth th approah that ahng an aeproblem yore pdatng yor mage or CSS or javarptAet pakager olve th or yor CSS and javarpt, and yoan ollow the ame olton wth yor mage: hange the lename whenever the le hange An vn or gt revon nmbero ome ort at the end o the le work great

    Latly, Eag ongraton an be tweaked on Apahe Speally, t an be trned o T epeally mportant oneyor te get bg enogh to pan aro mltple aet erverTe dealt Eag hahng mehanm mahnedependent aoppoed to trtly datadependent, o aet aro derenterver wll have derent Eag T eqate to both nneeary ahe nvaldaton and nneeary erver proeng toreate the Eag o trn t o n Apahe, jt pt

    FileETag none

    n yor httpd.conf

    On the Ral end, however, Eag are a lot more el Ralha a blt n Eag mehanm that ae to onder ontenaro mahne, and n the ode been greatly mpledYo an pey expry ondton and make an entre atonondtonal lke th:

    if stale?(:last_modified => @user.updated_at, :etag => @use

    end

    YSlow eentally look at thng that blok page downloadand way to peed p download tme o that end, a ew qkApahe tweak an go a long way

    Apache weakage

    Mot mantream brower aept gzpd ontent So zp thatp, ng Apahe mod_deate [10] Alo, tat aet holdhave a really ar ahead expre header Yo an jt pt

    ExpiresDefault access plus 10 years

    WhoAreYouLookinAt

    Rails Performance Analysis by erry Heath

    28

  • 8/8/2019 Rails Magazine Issue1

    29/36

    9

    And wont be exeted nle the moded tme or theEag ndate t need to be

    Afer yove made thee hange, work throgh the YSlowrbr and ee what yo an mprove YSlow provde exellentlnk that explan both the problem wth yor page and the betway to x them [11]

    Server/HP weaksIt doent eem that Phon Paenger ha th ame Mon

    grel tweakng problem, bt yo need to proxy to mltpleApahe, or jt need to ee how yor erver repond nderheavy load, th eton wll be helpl

    Im not re how mot people et p mltple boxe o Mongrel, bt t wa reently dovered on one o or applatonthat we had t et p poorly We had omethng lke:

    Ignore the only (t hold be 6) ble arrow omng romthe Apahe boxe; that my own lazne Te e here wathat we had one Apahe ntane proxyng to 4 other Apahentane, whh then trned arond and proxed to mongrel orerved p tat ontent

    httper [1] analy (omng n the next ew paragraph!)howed that, or mall reqet, the derene wa neglgble,bt a reqet per eond tarted to tak, proxyng needlelyto more Apahe beame a bottlenek Proxyng dretly to themongrel rom the load balanng Apahe box how abot a% perormane mprovement nder heavy load (00req/ or10e)

    good at ervng p tat le a Apahe , o be re that anyle n yor pbl dretory that reqeted get erved rghtbak by Apahe, preldng any Mongrel nterventon Pt thn yor vhot ong (Im amng the ret o yor rewrte rleare already n plae):

    Options FollowSymLinks

    AllowOverride None

    Order allow,deny

    Allow from all

    # Rewrite index to check for static

    RewriteRule ^/$ /index.html [QSA]

    # Rewrite to check for Rails cached page

    RewriteRule ^([^.]+)$ $1.html [QSA]

    RewriteRule ".*(images|stylesheets|javascripts)/?(.*)" "$0" [L]

    And then afer an Apahe reload, yor aet wll be ervedp by Apahe Whh mean t tme to tweak or Mongrelntane

    Apache

    Mongrel

    Static assets

    A a qk rereher, Mongrel ran n a ynhronzed threadntl Ral T mean that, or Ral, a Mongrel ntanean only handle 1 reqet at a tme, and when t proeng thatreqet, t blokng all other reqet omng to t T makeor an obvo alng olton (to a pont): more Mongrel!

    Bt, beore even worryng abot the nmber o Mongrelrght or yor mahne, yo hold be re yore not ngMongrel or thng t not made to do Mongrel nt nearly a

    Walk Into My Garden

    Rails Performance Analysis by erry Heath

    29

  • 8/8/2019 Rails Magazine Issue1

    30/36

    0

    30

    Enter httperf

    Now, whle mot o thee thng hold be done drng ohor or wth aton, th lat tet eem lke t an be donedrng the day Tat wold be wrong I yo happen to lam yorerver well enogh, yo an brng down everythng (Im peakng rom experene when I navely httperlammed a prodton box a ew year bak) Do th tet drng lowage tme

    T eentally a reap o Zed Shaw (o Mongrel, andthen Ral a Ghetto ame) nredbly helpl malng lt pot[1]

    Frt, nd a mahne that loe (both on the network and nproxmty) to the erver yo want to tet, bt that not the amemahne (tetng loopbak doent help o mh wth proxeand whatnot)

    Next p, yoll want to tet a tat aet on that mahneTe good new , yove already gone throgh th gde, allo yor tat Ral aet are hoted by Apahe T gve yo abetae baelne agant whh yo an meare yor Mongrel

    Start ot rnnng a ommand lke th:

    httperf --h