Table Of ContentFoundation Rails 2
Eldon Alameda
Foundation Rails 2
Copyright©2008byEldonAlameda
Allrightsreserved.Nopartofthisworkmaybereproducedortransmittedinanyformorbyanymeans,electronicormechanical,
includingphotocopying,recording,orbyanyinformationstorageorretrievalsystem,withoutthepriorwrittenpermission
ofthecopyrightownerandthepublisher.
ISBN-13(pbk):978-1-4302-1039-9
ISBN-13(electronic):978-1-4302-1040-5
PrintedandboundintheUnitedStatesofAmerica987654321
Trademarkednamesmayappearinthisbook.Ratherthanuseatrademarksymbolwitheveryoccurrenceofatrademarkedname,
weusethenamesonlyinaneditorialfashionandtothebenefitofthetrademarkowner,withnointentionofinfringement
ofthetrademark.
DistributedtothebooktradeworldwidebySpringer-VerlagNewYork,Inc.,233SpringStreet,6thFloor,NewYork,NY10013.
Phone1-800-SPRINGER,fax201-348-4505,[email protected],orvisitwww.springeronline.com.
Forinformationontranslations,pleasecontactApressdirectlyat2855TelegraphAvenue,Suite600,Berkeley,CA94705.
Phone510-549-5930,fax510-549-5939,[email protected],orvisitwww.apress.com.
ApressandfriendsofEDbooksmaybepurchasedinbulkforacademic,corporate,orpromotionaluse.eBookversionsandlicenses
arealsoavailableformosttitles.Formoreinformation,referenceourSpecialBulkSales–eBookLicensingwebpageat
http://www.apress.com/info/bulksales.
Theinformationinthisbookisdistributedonan“asis”basis,withoutwarranty.Althougheveryprecautionhasbeentakeninthe
preparationofthiswork,neithertheauthor(s)norApressshallhaveanyliabilitytoanypersonorentitywithrespecttoany
lossordamagecausedorallegedtobecauseddirectlyorindirectlybytheinformationcontainedinthiswork.
Thesourcecodeforthisbookisfreelyavailabletoreadersatwww.friendsofed.comintheDownloadssection.
Credits
LeadEditor ProductionEditor
BenRenow-Clarke EllieFountain
TechnicalReviewer Compositor
SeanCribbs DinaQuan
EditorialBoard Proofreader
ClayAndres,SteveAnglin, PatrickVincent
EwanBuckingham,TonyCampbell,
GaryCornell,JonathanGennick, Indexer
MatthewMoodie,JosephOttinger, RonStrauss
JeffreyPepper,FrankPohlmann,
BenRenow-Clarke,DominicShakeshaft, Artist
MattWade,TomWelsh AprilMilne
ProjectManager CoverImageDesigner
KylieJohnston CornévanDooren
CopyEditor InteriorandCoverDesigner
HeatherLang KurtKrames
AssociateProductionDirector ManufacturingDirector
KariBrooks-Copony TomDebolski
For my daughter Kaylee
“As you wish . . .”
CONTENTS AT A GLANCE
AbouttheAuthor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
AbouttheTechnicalReviewer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
AbouttheCoverImageDesigner. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Chapter 1 WhyRails? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 2 AShortIntroductiontoRuby . . . . . . . . . . . . . . . . . . . . . . . . 13
Chapter 3 TouringaRailsApplication . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Chapter 4 IntroducingActiveRecord. . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Chapter 5 AdvancedActiveRecord . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Chapter 6 PresentingtheViews. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Chapter 7 ExploringActionPack:UnderstandingtheController . . . . . 171
Chapter 8 ControllingOurRouting . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Chapter 9 ScaffoldingandPlug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Chapter 10 IntroductiontoTestingwithRSpec . . . . . . . . . . . . . . . . . . 253
Chapter 11 BuildingaCompleteApplication. . . . . . . . . . . . . . . . . . . . 291
Chapter 12 EnhancingOurApplication . . . . . . . . . . . . . . . . . . . . . . . . 339
Chapter 13 SecurityandPerformanceEnhancements . . . . . . . . . . . . . 381
Chapter 14 DeployingYourRailsApplication. . . . . . . . . . . . . . . . . . . . 401
Appendix A WheretoGofromHere. . . . . . . . . . . . . . . . . . . . . . . . . . 415
Appendix B RailsInstallation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Appendix C DatabaseDesign101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
v
CONTENTS
AbouttheAuthor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
AbouttheTechnicalReviewer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
AbouttheCoverImageDesigner. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Chapter 1 WhyRails? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
WhatmakesRailssospecial? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Extractedfromarealapplication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Usesconventionoverconfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
80/20rule. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Model-View-Controllerpattern. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
DRY(Don’tRepeatYourself) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Opinionatedsoftware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
UsesRubyfor(almost)everything . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Emphasisonbeauty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Testing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Developmenttools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Richcommunityandplug-ins. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Supportfordifferentenvironments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Advancedwebservicessupport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Commondirectorystructure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Fasttodevelopin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Fun. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
WhynotRails?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Notasilverbullet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Slowerbenchmarks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Deploymentdifficulties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Rapidlychanging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Notunderstandingthecode. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
vii
CONTENTS
Chapter 2 AShortIntroductiontoRuby . . . . . . . . . . . . . . . . . . . . . . . . 13
WhatisRuby? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Rubyisobjectoriented. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Rubyisinterpreted. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Rubyisdynamicallytyped . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Rubyisreflective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
InteractingwithRuby. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Introducingirb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Literals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Thereisalwaysareturnedvalue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Everythingisanobject. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Variablesandconstants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Localvariables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Instancevariables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Classvariables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Globalvariables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Fixnums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Bignum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Floats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Nil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Conditionals. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Hashes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Thewhileloop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Theforloop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Theeachcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Instancemethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Accessormethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Methodswithpunctuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Classmethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
TheAnarchyofRuby. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Chapter 3 TouringaRailsApplication . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Ourroadmap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Creatingasampleapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Commondirectorystructure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
app/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
app/controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
viii
CONTENTS
app/models. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
app/views. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
app/helpers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
db . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
doc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
lib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
log. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
public . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
test. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
tmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
vendor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Multipleenvironments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Standardconfigurationfiles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Databaseconfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Environmentconfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Routesconfiguration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Startingourapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
AtouroftheRailsframework. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
ComponentsofRails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
ActionMailer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
ActionPack. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
ActiveRecord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
ActiveResource. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
ActiveSupport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Railties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
TeachingRailstosayhello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Chapter 4 IntroducingActiveRecord. . . . . . . . . . . . . . . . . . . . . . . . . . . 67
WhatIsActiveRecord? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Thedemonstrationapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Creatingyourfirstmodel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
CRUDinteractionusingourmodel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Tailingthelog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Findingyourfirstcompany . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Creatinganewcompany. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
ActiveRecord’snewmethodinourapplication . . . . . . . . . . . . . . . . . . . . . . 76
Readingandfindingcompanyrecords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
find . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
find_by_*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Optionalparametersforfindmethods. . . . . . . . . . . . . . . . . . . . . . . . . . . 81
find_by_sql . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
ActiveRecord’sfindmethodinourapplication . . . . . . . . . . . . . . . . . . . . . . 83
Movingfindstoourmodel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Updatingacompanyrecord. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
ActiveRecord’supdatemethodinourapplication . . . . . . . . . . . . . . . . . . . . 85
ix
CONTENTS
Deletingacompany . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
ActiveRecord’sdeletemethodinourapplication. . . . . . . . . . . . . . . . . . . . . 87
CRUDrecap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Validations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Ensuringvaluesareset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Ensuringvaluesaretheproperlength . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Ensuringvaluesarenumbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Ensuringthattherecanbeonlyone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Ensuringthatinputsareintheproperformat. . . . . . . . . . . . . . . . . . . . . . . . . 97
Ensuringthatinputsarethesame(confirmation). . . . . . . . . . . . . . . . . . . . . . . 99
Ensuringthattheuseracceptedsomething . . . . . . . . . . . . . . . . . . . . . . . . . 100
Othervalidationrules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Definingyourownvalidations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Sexymigrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Magiccolumns. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Legacyordifficultdatabases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Chapter 5 AdvancedActiveRecord . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Callbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Buildingassociations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Theimportanceofprimaryandforeignkeys. . . . . . . . . . . . . . . . . . . . . . . . . 117
Typesofassociations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Singularassociations(one-to-one) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
belongs_to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
has_one . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Collectionassociations(one-to-manyandmany-to-many) . . . . . . . . . . . . . . . . . 121
has_many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
has_and_belongs_to_many. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
has_many:through. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Customassociations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Recursiverelationships(self-referentialjoins). . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Single-tableinheritance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Namedscopes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Dirtyobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Chapter 6 PresentingtheViews. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Namingtemplates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
MeettheERbtags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
The<%= %>Tags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
The<% %>Tags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
The<%- -%>Tags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
The<%# %>Tags. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Customlayoutcontentfromtheview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
x
CONTENTS
Helpermethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Rails-providedhelpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
stylesheet_link_tag. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
javascript_include_tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
image_tag. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Formattinghelpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Formhelpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Buildingyourownhelpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Partials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Callingapartialfromanothertemplate. . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Passingvariablesintoapartial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Renderacollection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Chapter 7 ExploringActionPack:UnderstandingtheController . . . . . 171
Application.rbandcontrollerinheritance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Definingactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Communicationwiththecontroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Disablingthesession . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Sessionoptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Cookies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Adeeperlookatthecontroller’sresponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Renderingtemplates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Directlyrendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Redirect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Sendingdata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
send_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
send_file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Propercontrollerdesign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Skinnycontrollers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
CRUD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
BuildingourCRUDcontroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Thenewaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Thecreateaction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Theeditaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Theupdateaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Thedeleteaction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Updatingtheindextemplate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Chapter 8 ControllingOurRouting . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Introducingrouting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Whatroutingdoes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Settingthehomedirectory. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
xi
CONTENTS
Regularroutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Prefixingourblogposts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Routingbydate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Namedroutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
RESTfulrouting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Singularroutes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Nestedroutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
CustomizingRESTfulroutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
Memberroutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
Collectionroutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
rakeroutes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Chapter 9 ScaffoldingandPlug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Overviewofwhatwe’regoingtobuild . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Creatingourapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Yourfirstscaffold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Viewingthescaffold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Generatingtheplug-inscaffold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Associatingourmodels. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Cleaninguptheviews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Addingaplug-intoourapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Modifyingourviews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Modifyingtheplug-inviews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Editingtheshowtemplate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Addaratingscontroller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Chapter 10 IntroductiontoTestingwithRSpec . . . . . . . . . . . . . . . . . . 253
Whatistesting? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Whyshouldwetest?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Isitenoughtoseethatyourapplicationisworkingcorrectly?. . . . . . . . . . . . . 254
Won’twritingtestsslowmedown?. . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Whendoweneedtowritetests? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Introducingtesting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
IntroducingRSpec. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
RSpecstories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
RSpecspecs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Matchers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
InstallingRSpec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Addingmodelspecs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
AddingabeforeblocktoDRYupourspecs . . . . . . . . . . . . . . . . . . . . . . . . . 271
Removingredundancy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Addingcontrollerspecs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Mockingmodels. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Testingtheindexaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Testingthecreateaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
xii