RailsCookbook
ByRobOrsini
...............................................
Publisher:O'Reilly
PubDate:January01,2007
ISBN-10:0-596-52731-4
ISBN-13:978-0-596-52731-0
Pages:600
TableofContents|Index
TheRailsCookbookisispackedwiththesolutionsyouneedtobeaproficientdeveloper
withRails,theleadingframeworkforbuildingthenewgenerationofWeb2.0applications.
Recipesrangefromthebasics,likeinstallingRailsandsettingupyourdevelopment
environment,tothelatesttechniques,suchasdevelopingRESTfulwebservices.
Withapplicationsthatarecodelight,feature-fullandbuilttoscalequickly,Railshas
revolutionizedwebdevelopment.TheRailsCookbookaddressesscoresofreal-world
challenges;eachoneincludesatestedsolution,plusadiscussionofhowandwhyitworks,
sothatyoucanadaptthetechniquestosimilarsituations.Topicsinclude:
ModelingdatawiththeActiveRecordlibrary
SettingupviewswithActionViewandRHTMLtemplates
Buildingyourapplication'slogicintoActionController
TestinganddebuggingyourRailsapplication
BuildingresponsivewebapplicationsusingJavaScriptandAjax
Ensuringthatyourapplicationissecurityandperformswell
DeployingyourapplicationwithMongrelandApache
UsingCapistranotoautomatedeployment
UsingthemanyRailsplugins
Workingwithgraphics
Whetheryou'renewtoRailsoranexperienceddeveloper,you'lldiscoverwaystotest,bug
andsecureyourapplications,incorporateAjax,usecachingtoimproveperformance,and
putyourapplicationintoproduction.WanttogetaheadoftheWeb2.0curve?This
valuablecookbookwillsaveyouhundredsofhourswhendevelopingapplicationswith
Rails.
RailsCookbook
ByRobOrsini
...............................................
Publisher:O'Reilly
PubDate:January01,2007
ISBN-10:0-596-52731-4
ISBN-13:978-0-596-52731-0
Pages:600
TableofContents|Index
Copyright
Foreword
Preface
Chapter1.GettingStarted
Section1.0.Introduction
Recipe1.1.JoiningtheRailsCommunity
Recipe1.2.FindingDocumentation
Recipe1.3.InstallingMySQL
Recipe1.4.InstallingPostgreSQL
Recipe1.5.InstallingRails
Recipe1.6.FixingRubyandInstallingRailsonOSX10.4Tiger
Recipe1.7.RunningRailsinOSXwithLocomotive
Recipe1.8.RunningRailsinWindowswithInstantRails
Recipe1.9.UpdatingRailswithRubyGems
Recipe1.10.GettingYourRailsProjectintoSubversion
Chapter2.RailsDevelopment
Section2.0.Introduction
Recipe2.1.CreatingaRailsProject
Recipe2.2.Jump-StartingDevelopmentwithScaffolding
Recipe2.3.SpeedingUpRailsDevelopmentwithMongrel
Recipe2.4.EnhancingWindowsDevelopmentwithCygwin
Recipe2.5.UnderstandingPluralizationPatternsinRails
Recipe2.6.DevelopingRailsinOSXwithTextMate
Recipe2.7.Cross-PlatformDevelopingwithRadRails
Recipe2.8.InstallingandRunningEdgeRails
Recipe2.9.SettingUpPasswordlessAuthenticationwithSSH
Recipe2.10.GeneratingRDocforYourRailsApplication
Recipe2.11.CreatingFull-FeaturedCRUDApplicationswithStreamlined
Chapter3.ActiveRecord
Section3.0.Introduction
Recipe3.1.SettingUpaRelationalDatabasetoUsewithRails
Recipe3.2.ProgrammaticallyDefiningDatabaseSchema
Recipe3.3.DevelopingYourDatabasewithMigrations
Recipe3.4.ModelingaDatabasewithActiveRecord
Recipe3.5.InspectingModelRelationshipsfromtheRailsConsole
Recipe3.6.AccessingYourDataviaActiveRecord
Recipe3.7.RetrievingRecordswithfind
Recipe3.8.IteratingOveranActiveRecordResultSet
Recipe3.9.RetrievingDataEfficientlywithEagerLoading
Recipe3.10.UpdatinganActiveRecordObject
Recipe3.11.EnforcingDataIntegritywithActiveRecordValidations
Recipe3.12.ExecutingCustomQuerieswithfind_by_sql
Recipe3.13.ProtectingAgainstRaceConditionswithTransactions
Recipe3.14.AddingSortCapabilitiestoaModelwithacts_as_list
Recipe3.15.PerformingaTaskWheneveraModelObjectIsCreated
Recipe3.16.ModelingaThreadedForumwithacts_as_nested_set
Recipe3.17.CreatingaDirectoryofNestedTopicswithacts_as_tree
Recipe3.18.AvoidingRaceConditionswithOptimisticLocking
Recipe3.19.HandlingTableswithLegacyNamingConventions
Recipe3.20.AutomatingRecordTimestamping
Recipe3.21.FactoringOutCommonRelationshipswithPolymorphic
Associations
Recipe3.22.MixingJoinModelsandPolymorphismforFlexibleDataModeling
Chapter4.ActionController
Section4.0.Introduction
Recipe4.1.AccessingFormDatafromaController
Recipe4.2.ChanginganApplication'sDefaultPage
Recipe4.3.ClarifyingYourCodewithNamedRoutes
Recipe4.4.ConfiguringCustomizedRoutingBehavior
Recipe4.5.DisplayingAlertMessageswithFlash
Recipe4.6.ExtendingtheLifeofaFlashMessage
Recipe4.7.FollowingActionswithRedirects
Recipe4.8.GeneratingURLsDynamically
Recipe4.9.InspectingRequestswithFilters
Recipe4.10.LoggingwithFilters
Recipe4.11.RenderingActions
Recipe4.12.RestrictingAccesstoControllerMethods
Recipe4.13.SendingFilesorDataStreamstotheBrowser
Recipe4.14.StoringSessionInformationinaDatabase
Recipe4.15.TrackingInformationwithSessions
Recipe4.16.UsingFiltersforAuthentication
Chapter5.ActionView
Section5.0.Introduction
Recipe5.1.SimplifyingTemplateswithViewHelpers
Recipe5.2.DisplayingLargeDatasetswithPagination
Recipe5.3.CreatingaStickySelectList
Recipe5.4.EditingMany-to-ManyRelationshipswithMultiselectLists
Recipe5.5.FactoringOutCommonDisplayCodewithLayouts
Recipe5.6.DefiningaDefaultApplicationLayout
Recipe5.7.GeneratingXMLwithBuilderTemplates
Recipe5.8.GeneratingRSSFeedsfromActiveRecordData
Recipe5.9.ReusingPageElementswithPartials
Recipe5.10.ProcessingDynamicallyCreatedInputFields
Recipe5.11.CustomizingtheBehaviorofStandardHelpers
Recipe5.12.CreatingaWebFormwithFormHelpers
Recipe5.13.FormattingDates,Times,andCurrencies
Recipe5.14.PersonalizingUserProfileswithGravatars
Recipe5.15.AvoidingHarmfulCodeinViewswithLiquidTemplates
Recipe5.16.GlobalizingYourRailsApplication
Chapter6.RESTfulDevelopment
Section6.0.Introduction
Recipe6.1.CreatingNestedResources
Recipe6.2.SupportingAlternativeDataFormatsbyMIMEType
Recipe6.3.ModelingRelationshipsRESTfullywithJoinModels
Recipe6.4.MovingBeyondSimpleCRUDwithRESTfulResources
Recipe6.5.ConsumingComplexNestedRESTResources
Recipe6.6.DevelopingYourRailsApplicationsRESTfully
Chapter7.RailsApplicationTesting
Section7.0.Introduction
Recipe7.1.CentralizingtheCreationofObjectsCommontoTestCases
Recipe7.2.CreatingFixturesforMany-to-ManyAssociations
Recipe7.3.ImportingTestDatawithCSVFixtures
Recipe7.4.IncludingDynamicDatainFixtureswithERb
Recipe7.5.InitializingaTestDatabase
Recipe7.6.InteractivelyTestingControllersfromtheRailsConsole
Recipe7.7.InterpretingtheOutputofTest::Unit
Recipe7.8.LoadingTestDatawithYAMLFixtures
Recipe7.9.MonitoringTestCoveragewithrakestats
Recipe7.10.RunningTestswithRake
Recipe7.11.SpeedingUpTestswithTransactionalFixtures
Recipe7.12.TestingAcrossControllerswithIntegrationTests
Recipe7.13.TestingControllerswithFunctionalTests
Recipe7.14.ExaminingtheContentsofCookie
Recipe7.15.TestingCustomandNamedRoutes
Recipe7.16.TestingHTTPRequestswithResponse-RelatedAssertions
Recipe7.17.TestingaModelwithUnitTests
Recipe7.18.UnitTestingModelValidations
Recipe7.19.VerifyingDOMStructurewithTag-RelatedAssertions
Recipe7.20.WritingCustomAssertions
Recipe7.21.TestingFileUpload
Recipe7.22.ModifyingtheDefaultBehaviorofaClassforTestingbyUsing
Mocks
Recipe7.23.ImprovingFeedbackbyRunningTestsContinuously
Recipe7.24.AnalyzingCodeCoveragewithRcov
Chapter8.JavaScriptandAjax
Section8.0.Introduction
Recipe8.1.AddingDOMElementstoaPage
Recipe8.2.CreatingaCustomReportwithDragandDrop
Recipe8.3.DynamicallyAddingItemstoaSelectList
Recipe8.4.MonitoringtheContentLengthofaTextarea
Recipe8.5.UpdatingPageElementswithRJSTemplates
Recipe8.6.InsertingJavaScriptintoTemplates
Recipe8.7.LettingaUserReorderaList
Recipe8.8.AutocompletingaTextField
Recipe8.9.SearchingforandHighlightingTextDynamically
Recipe8.10.EnhancingtheUserInterfacewithVisualEffects
Recipe8.11.ImplementingaLiveSearch
Recipe8.12.EditingFieldsinPlace
Recipe8.13.CreatinganAjaxProgressIndicator
Chapter9.ActionMailer
Section9.0.Introduction
Recipe9.1.ConfiguringRailstoSendEmail
Recipe9.2.CreatingaCustomMailerClasswiththeMailerGenerator
Recipe9.3.FormattingEmailMessagesUsingTemplates
Recipe9.4.AttachingFilestoEmailMessages
Recipe9.5.SendingEmailfromaRailsApplication
Recipe9.6.ReceivingEmailwithActionMailer
Chapter10.DebuggingRailsApplications
Section10.0.Introduction
Recipe10.1.ExploringRailsfromtheConsole
Recipe10.2.FixingBugsattheSourcewithRuby-cw
Recipe10.3.DebuggingYourApplicationinRealTimewiththebreakpointer
Recipe10.4.LoggingwiththeBuilt-inRailsLoggerClass
Recipe10.5.WritingDebuggingInformationtoaFile
Recipe10.6.EmailingApplicationExceptions
Recipe10.7.OutputtingEnvironmentInformationinViews
Recipe10.8.DisplayingObjectContentswithExceptions
Recipe10.9.FilteringDevelopmentLogsinRealTime
Recipe10.10.DebuggingHTTPCommunicationwithFirefoxExtensions
Recipe10.11.DebuggingYourJavaScriptinRealTimewiththeJavaScriptShell
Recipe10.12.DebuggingYourCodeInteractivelywithruby-debug
Chapter11.Security
Section11.0.Introduction
Recipe11.1.HardeningYourSystemswithStrongPasswords
Recipe11.2.ProtectingQueriesfromSQLInjection
Recipe11.3.GuardingAgainstCross-SiteScriptingAttacks
Recipe11.4.RestrictingAccesstoPublicMethodsorActions
Recipe11.5.SecuringYourServerbyClosingUnnecessaryPorts
Chapter12.Performance
Section12.0.Introduction
Recipe12.1.MeasuringWebServerPerformancewithHttperf
Recipe12.2.BenchmarkingPortionsofYourApplicationCode
Recipe12.3.ImprovingPerformancebyCachingStaticPages
Recipe12.4.ExpiringCachedPages
Recipe12.5.MixingStaticandDynamicContentwithFragmentCaching
Recipe12.6.FilteringCachedPageswithActionCaching
Recipe12.7.SpeedingUpDataAccessTimeswithmemcached
Recipe12.8.IncreasingPerformancebyCachingPost-ProcessedContent
Chapter13.HostingandDeployment
Section13.0.Introduction
Recipe13.1.HostingRailsUsingApache1.3andmod_fastcgi
Recipe13.2.ManagingMultipleMongrelProcesseswithmongrel_cluster
Recipe13.3.HostingRailswithApache2.2,mod_proxy_balancer,andMongrel
Recipe13.4.DeployingRailswithPoundinFrontofMongrel,Lighttpd,and
Apache
Recipe13.5.CustomizingPound'sLoggingwithcronolog
Recipe13.6.ConfiguringPoundwithSSLSupport
Recipe13.7.SimpleLoadBalancingwithPen
Recipe13.8.DeployingYourRailsProjectwithCapistrano
Recipe13.9.DeployingYourApplicationtoMultipleEnvironmentswith
Capistrano
Recipe13.10.DeployingwithCapistranoWhenYouCan'tAccessSubversion
Recipe13.11.DeployingwithCapistranoandmongrel_cluster
Recipe13.12.DisablingYourWebSiteDuringMaintenance
Recipe13.13.WritingCustomCapistranoTasks
Recipe13.14.CleaningUpResidualSessionRecords
Chapter14.ExtendingRailswithPlug-ins
Section14.0.Introduction
Recipe14.1.FindingThird-PartyPlug-ins
Recipe14.2.InstallingPlug-ins
Recipe14.3.ManipulatingRecordVersionswithacts_as_versioned
Recipe14.4.BuildingAuthenticationwithacts_as_authenticated
Recipe14.5.SimplifyingFolksonomywiththeacts_as_taggable
Recipe14.6.ExtendingActiveRecordwithacts_as
Recipe14.7.AddingViewHelperstoRailsasPlug-ins
Recipe14.8.UploadingFileswithfile_column
Recipe14.9.UploadingFileswithacts_as_attachment
Recipe14.10.DisablingRecordsInsteadofDeletingThemwith
acts_as_paranoid
Recipe14.11.AddingMoreElaborateAuthenticationUsingtheLoginEngine
Chapter15.Graphics
Section15.0.Introduction
Recipe15.1.InstallingRMagickforImageProcessing
Recipe15.2.UploadingImagestoaDatabase
Recipe15.3.ServingImagesDirectlyfromaDatabase
Recipe15.4.CreatingResizedThumbnailswithRMagick
Recipe15.5.GeneratingPDFDocuments
Recipe15.6.VisuallyDisplayingDatawithGruff
Recipe15.7.CreatingSmall,InformativeGraphswithSparklines
AppendixA.MigratingtoRails1.2
ActionController
ActiveRecord
ActionView
Colophon
Index
Copyright
Copyright©2007,O'ReillyMedia.Allrightsreserved.
PrintedinintheUnitedStatesofAmerica.
PublishedbyO'ReillyMedia,Inc.,1005GravensteinHighway
North,Sebastopol,CA95472.
O'Reillybooksmaybepurchasedforeducational,business,or
salespromotionaluse.Onlineeditionsarealsoavailablefor
mosttitles().Formoreinformation,
contactourcorporate/institutionalsalesdepartment:(800)
998-9938or
Editor:MikeLoukides
ProductionEditor:LaurelR.T.Ruma
Editor:MaryAnneWeeksMayo
NutshellHandbook,theNutshellHandbooklogo,andthe
O'ReillylogoareregisteredtrademarksofO'ReillyMedia,Inc.
RailsCookbook,theimageofaCapehuntingdog,andrelated
tradedressaretrademarksofO'ReillyMedia,Inc.
Manyofthedesignationsusesbymanufacturersandsellersto
distinguishtheirproductsareclaimedastrademarks.Where
thosedesignationsappearinthisbook,andO'ReillyMedia,Inc.
wasawareofatrademarkclaim,thedesignationshavebeen
printedincapsorinitialcaps.
Whileeveryprecautionhasbeentakeninthepreparationofthis
book,thepublisherandauthorassumenoresponsibilityfor
errorsoromissions,orfordamagesresultingfromtheuseof
theinformationcontainedherein.
Foreword
WhenRobaskedmetowritetheforewordforhisbookIjumped
atthechance.Actually,IjumpedattellinghimI'dwritethe
forewordandthenIgotdistractedwithbillionsofthingsand
hadtofinallygetitdowninaflashofbrilliance.Trustme,it's
brilliant.Thisforewordwillchangeyourlife,curebaldness,give
yourenemieslymphoma,andnunswillreciteittotheirclasses
asarewardforgoodbehavior.It'sthatgood.
ThereasonIwantedtowriteaforewordforacookbook,and
specificallyforRailsCookbook,isthatIwouldn'tbeheretoday
ifitweren'tforthistypeofbook.Whenlearningtowritecode,
administersystems,orcookfishtheyoungjuniorwilltypically
runoutandgetyourbasicintroductorybooks.Thesebookstry
takethenewbiethroughafixedroadoflearningthatcovers
mosttopicslightlyinthecurriculum.Atfirstthisisgreat,and
thejuniorlearnsalotof"bootstrapknowledge"withthethings
hedidn'tknowhedidn'tknowgettingfilledinlikegroutover
brokentile.
Afterthisinitiallearningthough,thesebooksarefairlyuseless
becausetheyarehorriblereferences.Ifyoureadthemstraight
throughandputstickiesontheimportantpagesyoumightget
somethingoutofit.Havingtotrollthroughoneofthesedense
tomestofindthatthingyouthoughtyourememberedin
chaptermaybe8or9sucksreallybadat2a.m.Beenthere,
donethat,boughtthepajamasinlimegreen.
Thisiswherethe"cookbook"genrecomesintoplay,andwhy
thesetypesofbooksmademeabetterprogrammer.Theone
bookthatstandsoutinmymindisPerlCookbook.No,I'mnot
sayingthatbecauseitisalsoanO'Reillybook;I'msayingit
becausethatbookwasbyfarthemostfantasticcookbookever.
InthedayswhenIwasdoingrelativelyseriousPerlcoding,
having"thecookbook"aroundhelpedmelearnallthetricksI
neededrightwhenIneededthem.
Perlhelpedmetakechargeofawildlymanagedheterogeneous
networkofcomputers,andthecookbookhelpedmetamethe
wildPerl.PerlwasalsomyfirstlightforayintoCGI
programmingandprocessingfortheWeb.Itwasagreatwayto
learnCGItoo,becauseallthenastystuffwasalreadytaken
careof,andPerlhadallthegearyouneededtoprogramback
then.Oh,Iremember<blink>fondly.
I'dhavetosayIdidn'tlearnanyPerluntilIboughtmycopyof
thecookbook,slammeditandacaseofsodaonatable,and
spentanentirenightwritingaprogramtolookformalicious
attacksinmysystemlogs.I'dreadafewgoodbooks,butit
wastheabilitytoaskaquestion,getananswer,then
implementthesolutionthattaughtmerealPerlcoding.Bestof
all,Icouldapplyatechnique,readabouthowitworked,and
thentotallyforgetaboutit,onlyleavingatinymarkerinmy
brainsayingwheretolookitupagain.
WithmyPerlCookbookIbecamearockstargeekinmyown
littleway.Mypeerswouldspendhourstryingtosolvea
problem,andI'djustlookitupandbangitoutwithPerlina
fewminutes.Icouldmanagehugenumbersofsystemswith
simpleautomation.Ievenlearnedtoappreciatesomeofthe
quirksofPerlforwhattheywere.
WhywouldIbetalkingaboutPerlinaRailsCookbook
foreword?Well,apartfromthefactthatRobsaidIcouldsay
anythingintheforeword,thePerlCookbookwastheonethat
setthestandardforme.Itdoesn'tmatterwhatlanguageitwas
about;whatmatteredwasthatthisonebookmademea
competentPerlprogrammerandsystemautomatorwhere
nearlyallotherbooksfellflat.It'sagreatexampleofthe
synergyofasetofcomponentsmakingthewholegreater.
Thepowerofagoodcookbookisitsabilitytoimpartexpert
knowledgeindigestiblechunkstobeginners.Justlikewithreal
cookbooks,theyaredesignedforpeoplewhomayknowthe
theoryorbasicsofthetask,butdon'thavethemountainsof
domainknowledgeandexperiencethatanexpertsteepedinthe
technologywouldhave.Thecookbookgetsreadersinto
practicinganddoingexpertactivitiesandhopefullyteaches
themtherightwaytodothetricksofthetrade.
Rob'sRailsCookbookwillhopefullydothesamethingforthose
peoplejuststartingoutwiththeirfirstRubyonRailsproject.It
alsowillbeagoodreferenceforthose"beginning
intermediates"whostillhavetolookthingsuptheyrarelyuse
orhaven'tdonebefore.It'salsogreatforcrustyoldguyslike
mewhocan'tevenrememberwhatwehadforbreakfastthat
morning.
ZedA.Shaw,creatorofMongrelandMUDCRAP-CEMasterBlack
BeltSifu,()
Preface
I'vebeenafulltimewebdevelopersince1998,andhave
workedwithjustabouteverypopularwebscriptinglanguage
overtheyears.Duringthedot-comboom,Ikeptbusyinweb
consultingshops,tryingtoturnvariousentrepreneurialideas
intoprofitablewebbusinesses.Theboomwasaveryinteresting
time;thecollectiveexcitementoversomeofthefirstpopular
webapplicationswasinfectious.Iwrotealotofcodeduring
thattime,someofwhichwasamess,butitwasfun,anditwas
anintroductiontoacareerthatIenjoytremendously.
Whenthedot-combubblecrashed,thetoneoftheindustry
changeddramatically.Webworkdriedupdrastically,andthe
overallenthusiasmoftheindustryseemedtosinkintorecession
alongwiththeindustry'seconomy.Imanagedtochaintogether
variouswebprogramminggigs,buttheworkwasnotas
interestingasithadbeenwhenpeoplehadmoremoneyto
experimentwithnewideas.
In2004,IlandedajobasthewebmasteratIndustrialLight
andMagic.AtILM,IworkedmostlywithPerlandJava,butthis
wasalsowhereIwasintroducedtoPython.Towardtheendof
mytimeatILM,IbegantohearaboutRubyandalotofthe
buzzontheNetaboutitversusPythonbothbeingverycapable
andlightweightdynamiclanguages.WhileatILM,Iwas
immersedintheexcitementofthevisualeffectsindustryand
managedtowaitoutthebadeconomyuntilfinallylandinga
softwareengineeringpositionatO'ReillyMedia.Itwasat
O'ReillythatIfirstfoundoutaboutRails.
AroundthetimeIstartedatO'Reilly,somethingverysignificant
happened:GooglereleasedGoogleMaps.Theeconomyhad
beenslowlyrecovering,butitwasthereleaseofthisoneweb
applicationthatre-ignitedmyexcitementaboutweb
applicationsandtheirdevelopment.Whatwassointeresting
aboutGoogleMapswasthatitwasn'tusinganynew
technology.Itwasjustanincrediblycreativeuseof
technologiesthathadbeenaroundforyears.
Beingabletodragamaparoundseemedtoshatterallprevious
assumptionsaboutthelimitationsofwebsoftware.Afterseeing
thisapplication,andanumberofothersthatwerecroppingup
atthetime,myviewofthepotentialoftheWeb,aswellasmy
enthusiasmindevelopingit,wasreborn.Now,ifIcouldjust
havethesamefeelingaboutthetoolsIwasusing.
That'swhenIdiscoveredRailsandsimultaneously,Ruby.For
me,discoveringandlearningRailshadasimilareffecttoGoogle
Maps;itseemedalmosttoogoodtobetrue.Railshandledallof
thethingsthatIfoundmostunpleasantaboutweb
developmentautomaticallyorsoelegantlythattheywereno
longerpainful.ThenextthingInoticedwashoweasilynew
projectswereorganizedaccordingtotheMVCdesignpattern.
IhadworkedonmanyMVCprojectsbefore,butoftenthey
werehome-grownandnoteasilyreusable.Insomecases,the
amountofsetupinvolvedmadethebenefitsofusingMVC
questionable,especiallyforsmallerprojects.I'veoftensaidthat
thesimpleactofcreatingaRailsprojectfeltliketherewasa
roomfullofexperiencedsoftwareveteransimpartingtheir
knowledgeaboutsoundapplicationdesign,ensuringthatmy
projectstartedoffintherightdirection.
IsoonrealizedthatnothingabouttheRailsframeworkorthe
bestpracticesencouragedbytheRailscommunitywas
particularlynew.Infact,mostofthetechniquesand
methodologiesinvolvedhavebeenaroundforyears.WhatI
foundspecialaboutRailswasthatallofthesethingshadcome
together,insortofaperfectstormofbestpractices.Theresult
wasaframeworkthatmadewebdevelopmentbothenjoyable
andrewarding.
WithanumberofRailsprojectsbehindme,Istarteddoingtalks
onRailstovariousgroupsaroundwhereIlive.Itwasatalocal
Linuxuser'sgroupthatIwasapproachedbyMikeHendrickson
(theexecutiveeditoratO'Reilly)aboutwritingaRailsbook.
MikeHendricksonthenintroducedmetomyeditor,Mike
Loukides,andwedecidedthatIshouldwritetheRails
Cookbook.Thatwasthebeginningofalongprocessthathas
finallyresultedinthebookyou'renowreading.
IliketothinkofRailsasasuccessfulrefactoringoftheprocess
ofwebdevelopmentthatjustkeepsgettingbetterwithtime.It
ismyhopethatthisbookwillhelpyoutodiscovermuchmore
aboutthistrulyamazingframework.
WhoThisBookIsFor
Inpreparationforwritingthisbook,Itriedtocollectalotof
dataaboutwhattheRailscommunityneededmostina
cookbook.TodothisIcollecteddatafromtheRailsmailinglists
aswellasfromthemostactiveIRCchannels.Iwasn'tvery
scientificabouthowIprocessedthedata,butIdidgetafeelfor
whatweremanyofthemostcommonlyaskedquestions.Based
onthis,Icreatedaninitialoutline,andthenranitpastasmany
peopleasIcouldfind,whoreviewedandfurthereditedit.
TheoutlinehasevolvedsinceIfirstpresentedittomyeditor,
butitstilltargetstheneedsofthebulkoftheRailscommunity.
Thetargetreaderforthisbookissomeonewithweb
developmentexperience,butperhapsnewtoRails,oran
intermediateRailsdeveloper.
Thatsaid,IbelievethatmuchoftheinformationIpresentis
goingtobevaluableacrosstheboard;forexample,Rails
applicationdeploymentisauniversalproblemthatallRails
developersneedtosolve.Intheend,Ihopethateveryonewho
readsthisbookwillfinditsignificantlyuseful.
OtherResources
WebSites
ThekeywebsitesforfindingoutaboutRubyandRailsare
,,and
.Butthesewebsitesarefarfrom
thewholestory.Perhapsmorethenanyothertechnology,Rails
isdrivenbybloggers.Insteadofprovidinganinevitably
incompletelistofRailsblogs,Isuggestthatyoustartby
readingthemainRailsblog()and
discoverotherblogsthatitlinksto.
Books
TherearemanyexcellentbooksonRubyandRailswithmore
beingaddedallthetime.HerearesomethatIrecommend:
RubyforRailsbyDavidA.Black(Manning)
ProgrammingRubybyDaveThomas,etal.(Pragmatic
Bookshelf)
AgileWebDevelopmentwithRailsbyDaveThomas,etal.
(PragmaticBookshelf)
RailsRecipesbyChadFowler(PragmaticBookshelf)
TheRubyWaybyHalFulton(Addison-WesleyProfessional)
RubyonRails:UpandRunningbyBruceA.TateandCurt
Hibbs(O'Reilly)
Mongrel:Serving,Deploying,andExtendingYourRuby
Applications(PDFShortcut)byMattPelletierandZedShaw
(Addison-WesleyProfessional)
ConventionsUsedinThisBook
Unlessotherwisenoted,therecipesinthisbookhavebeen
createdforthereleasecandidateofRailsversion1.2.Thefinal
versionofRails1.2shouldbeavailablebythetimeyouhave
thisbook.AfewrecipesrequireEdgeRails.InstallingEdgeRails
iscoveredinSection2.8."Allrecipesassumethatyou'reusing
Ruby1.8.4.
Somecodesampleshavefilenamesmentionedbeforethecode;
thefilesthataccompanythecodecanbefoundonthebook's
webpageat />
FontConventions
Thefollowingtypographicconventionsareusedinthisbook:
Italic
Usedforfileanddirectorynames,emailaddresses,and
URLs,aswellasfornewtermswheretheyaredefined.
Constantwidth
Usedforcodelistingsandforkeywords,variables,
functions,commandoptions,databasenames,parameters,
classnames,andHTMLtagswheretheyappearinthetext.
Constantwidth
bold
Usedtomarklinesofoutputincodelistingsandcommand
linestobetypedbytheuser.
Constantwidthitalic
Usedasageneralplaceholdertoindicateitemsthatshould
bereplacedbyactualvaluesinyourownprograms.
Thisiconsignifiesatip,suggestion,orgeneralnote.
CAUTION
Thisiconindicatesawarningorcaution.
UsingCodeExamples
Thisbookisheretohelpyougetyourjobdone.Ingeneral,you
mayusethecodeinthisbookinyourprogramsand
documentation.Youdonotneedtocontactusforpermission
unlessyou'rereproducingasignificantportionofthecode.For
example,writingaprogramthatusesseveralchunksofcode
fromthisbookdoesnotrequirepermission.Sellingor
distributingaCD-ROMofexamplesfromO'Reillybooksdoes
requirepermission.Answeringaquestionbycitingthisbook
andquotingexamplecodedoesnotrequirepermission.
Incorporatingasignificantamountofexamplecodefromthis
bookintoyourproduct'sdocumentationdoesrequire
permission.
Weappreciate,butdonotrequire,attribution.Anattribution
usuallyincludesthetitle,author,publisher,andISBN.For
example:"RailsCookbookbyRobOrsini.Copyright2007
O'ReillyMedia,Inc.,978-0-596-52731-0."
Ifyoufeelyouruseofcodeexamplesfallsoutsidefairuseor
thepermissiongivenabove,feelfreetocontactusat
Safari®Enabled
NOTE
WhenyouseeaSafari®Enabledicononthecover
ofyourfavoritetechnologybook,thatmeansthe
bookisavailableonlinethroughtheO'ReillyNetwork
SafariBookshelf.
Safarioffersasolutionthat'sbetterthane-books.It'savirtual
librarythatletsyoueasilysearchthousandsoftoptechbooks,
cutandpastecodesamples,downloadchapters,andfindquick
answerswhenyouneedthemostaccurate,currentinformation.
Tryitforfreeat.
CommentsandQuestions
Pleaseaddresscommentsandquestionsconcerningthisbookto
thepublisher:
O'ReillyMedia,Inc.
1005GravensteinHighwayNorth
Sebastopol,CA95472
800-998-9938(intheUnitedStatesorCanada)
707-829-0515(international/local)
707-829-0104(fax)
Wehaveawebpageforthisbookwherewelisterrata,
examples,oranyadditionalinformation.Youcanaccessthis
pageat:
/>Tocommentorasktechnicalquestionsaboutthisbook,send
emailto:
Formoreinformationaboutbooks,conferences,Resource
Centers,andtheO'ReillyNetwork,seetheO'Reillywebsiteat:
Acknowledgments
Itgoeswithoutsayingthatwritingabookisanenormous
amountofworkthiswasdefinitelytrueinmycase.Thankfully,I
receivedalotofhelpfromaverytalentedgroupofpeopleandI
wouldliketoacknowledgethem.
Thebook'sbiggestcontributor,asidefrommyself,hasbeen
MikeLoukides.Mike'sinputwasinvaluable,whetherhewas
refactoringaconfusingparagraphorofferinganinsightabout
anideaIhadn'tthoughttoinclude,hewastherehelpingevery
stepoftheway.ThegreatthingaboutworkingwithMikeisthat
herespectedmygoalsfortheprojectandultimatelygaveme
completecreativefreedomovertheproject.Ilookforwardto
ourcontinuedfriendshipandbeingabletotalkwithhimabout
oursharedinterestinmusicwithoutworryingaboutthe
conversationbeingaside-trackofsomethingelse.
Fifteenpeoplecontributedrecipestothebook.I'dliketopoint
outthethreethathelpedmethemostduringthefinalstagesof
theprocess.DiegoScataglinicontributedthemostrecipes(12
total).Moreimportantly,heproducedmanyoftheserecipes
withveryshortnoticeasIpushedtofitinmorecontentbefore
thefinaldeadline.ChristianRomneyandRyanWaldronalso
steppeduptotheplateinthefinalstagesandhelpedfillout
andcleanupmuchofthebook'scontent.Duringthefinaldays,
thethreeofuscollaboratedin#rorcb(a.k.a.TheWarRoom),
whereIwasabletodelegateahugeamountofworktoeachof
them.Theircontributionwasoutstandingbut,mostimportantly,
wehadagreattimeintheprocess.I'mgratefultoeveryone
whocontributedrecipes.TheyincludeBenBleything,Blaine
Cook,RyanDaigle,BillFroelich,EvanHenshaw-Plath,Rick
Olson,MattRidenour,DaeSanHwang,AndyShen,JoeVan
Dyk,NicholasWieland,andChrisWong.
MorespecialthanksgoestoCodaHalefordoinganexcellent
passoverthebookresultinginseveralemailsfullofvaluable
suggestions.AlsothankstoEvanHenshaw-Plath(rabble),Zed
Shaw,andGeoffreyGrosenbach(topfunky)forputtingupwith
manylatenightRailsquestionsandofferingsoundadvicealong
theway.
ThetoolthatIsettledonforcollaboratingwithreviewerswas
Beast(anexcellentRailsforumwrittenbyJoshGoebelandRick
Olson).Anumberofdiscussionshappenedtherethatdefinitely
improvedthebookseveraltimesover.I'mthankfultoallwho
reviewedmycontentandpostedcomments.TheyincludeSam
Aaron,AnjanBacchu,TonyFrey,MattGrayson,Stephan
Kamper,BinLi,TomLianza,ThomasLockney,MattMcKnight,
JamesMoore,HartmutProchaska,AndyShen,BillSpornitz,
AndrewTurner,ScottWalter,andNicholasWieland.
DuringtheinitialmonthsofwritingIswitchedbetweenseveral
differentwritingenvironments.Ifinallysettledonediting
directlyinDocBook.OnceIaccumulatedacertainamountof
contentandneededtoperformvarioustransformations,I
quicklydiscoveredthelimitsofmyknowledgeofXML
processing.ThisiswhereKeithFahlgrenandAndrewSavikas
steppedinwithjusttherightXPathexpressionorXMLMind
macrotogetthejobdone,whichletmefocusonwriting.
WritingabookislikenothingI'veeverdonebefore.Becauseof
that,I'mthankfulthatIwasabletotalkwithmyfriendswho
havewrittenbooksabouttheprocess.ThosefriendsareKyle
Rankin,AndrewSavikas,andTonyStubblebine.
Finally,Iwanttothankmywifeforhelpingmakethisproject
possible.Sheessentiallybecameasingleparentforquiteabit
longerthenshebargainedfor.Iamgratefulforhersupportand
encouragement.
Chapter1.GettingStarted
Section1.0.Introduction
Recipe1.1.JoiningtheRailsCommunity
Recipe1.2.FindingDocumentation
Recipe1.3.InstallingMySQL
Recipe1.4.InstallingPostgreSQL
Recipe1.5.InstallingRails
Recipe1.6.FixingRubyandInstallingRailsonOSX10.4
Tiger
Recipe1.7.RunningRailsinOSXwithLocomotive
Recipe1.8.RunningRailsinWindowswithInstantRails
Recipe1.9.UpdatingRailswithRubyGems
Recipe1.10.GettingYourRailsProjectintoSubversion
1.0.Introduction
SinceitfirstappearedinJuly2004,RubyonRailshas
revolutionizedtheprocessofdevelopingwebapplications.It
hasenabledwebdeveloperstobecomemuchfasterandmore
efficient,allowingforquickerapplicationdevelopmentacritical
advantageinthesedaysof"webtime."HowdoesRailsdoit?
ThereareafewreasonsbehindRails'success:
Conventionoverconfiguration
Ratherthanforcingyoutoconfigureeveryaspectofyour
application,Railsisfullofconventions.Ifyoucanfollow
thoseconventions,youcandoawaywithalmostall
configurationfilesandalotofextracoding.Ifyoucan't
followthoseconventions,you'reusuallynoworseoffthan
youwereinyourpreviousenvironment.
Liberaluseofcodegeneration
Railscanwritealotofyourcodeforyou.Forexample,
whenyouneedaclasstorepresentatableinyour
database,youdon'thavetowritemostofthemethods:
Railslooksatthetable'sdefinitionandcreatesmostofthe
classforyouonthefly.Youcanmixinmanyextensionsto
addspecialbehavior,andwhenyoureallyneedto,youcan
addyourownmethods.You'llfindthatyou'rewritingonlya
fractionasmuchcodeasyoudidwithotherweb
frameworks.
Don'trepeatyourself(DRY)