Sie sind auf Seite 1von 51

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Moreatrubyonrails.org: Overview|Download|Deploy|Code|Screencasts|Documentation|Ecosystem|Community|Blog

Getting Started with Rails


ThisguidecoversgettingupandrunningwithRubyonRails.Afterreadingit, youshouldbefamiliarwith:
InstallingRails,creatinganewRailsapplication,andconnectingyour applicationtoadatabase ThegenerallayoutofaRailsapplication ThebasicprinciplesofMVC(Model,ViewController)andRESTfuldesign HowtoquicklygeneratethestartingpiecesofaRailsapplication.

Chapters
1. GuideAssumptions 2. WhatisRails? TheMVCArchitecture TheComponentsofRails REST 3. CreatingaNewRailsProject InstallingRails CreatingtheBlogApplication InstallingtheRequiredGems ConfiguringaDatabase CreatingtheDatabase 4. Hello,Rails! StartinguptheWebServer SayHello,Rails SettingtheApplicationHomePage 5. GettingUpandRunningQuicklywithScaffolding 6. CreatingaResource RunningaMigration AddingaLink WorkingwithPostsintheBrowser TheModel AddingSomeValidation UsingtheConsole ListingAllPosts CustomizingtheLayout CreatingNewPosts ShowinganIndividualPost EditingPosts DestroyingaPost 7. AddingaSecondModel

1 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails


GeneratingaModel AssociatingModels AddingaRouteforComments GeneratingaController 8. Refactoring RenderingPartialCollections RenderingaPartialForm 9. DeletingComments DeletingAssociatedObjects 10. Security 11. BuildingaMulti-ModelForm 12. ViewHelpers 13. WhatsNext? 14. ConfigurationGotchas 15. Changelog

http://guides.rubyonrails.org/getting_started.html#...

ThisGuideisbasedonRails3.0.SomeofthecodeshownherewillnotworkinearlierversionsofRails.

1 Guide Assumptions
ThisguideisdesignedforbeginnerswhowanttogetstartedwithaRailsapplicationfromscratch.Itdoesnotassumethatyouhaveanyprior experiencewithRails.However,togetthemostoutofit,youneedtohavesomeprerequisitesinstalled: TheRubylanguageversion1.8.7orhigher NotethatRuby1.8.7p248andp249havemarshalingbugsthatcrashRails3.0.RubyEnterpriseEditionhavethesefixedsincerelease 1.8.7-2010.02though.Onthe1.9front,Ruby1.9.1isnotusablebecauseitoutrightsegfaultsonRails3.0,soifyouwanttouseRails3with 1.9.xjumpon1.9.2forsmoothsailing. TheRubyGemspackagingsystem AworkinginstallationoftheSQLite3Database RailsisawebapplicationframeworkrunningontheRubyprogramminglanguage.IfyouhavenopriorexperiencewithRuby,youwillfindavery steeplearningcurvedivingstraightintoRails.TherearesomegoodfreeresourcesontheinternetforlearningRuby,including: Mr.NeighborlysHumbleLittleRubyBook ProgrammingRuby Whys(Poignant)GuidetoRuby

2 What is Rails?
RailsisawebapplicationdevelopmentframeworkwrittenintheRubylanguage.Itisdesignedtomakeprogrammingwebapplicationseasierby makingassumptionsaboutwhateverydeveloperneedstogetstarted.Itallowsyoutowritelesscodewhileaccomplishingmorethanmany otherlanguagesandframeworks.ExperiencedRailsdevelopersalsoreportthatitmakeswebapplicationdevelopmentmorefun. Railsisopinionatedsoftware.Itmakestheassumptionthatthereisabestwaytodothings,anditsdesignedtoencouragethatwayandin somecasestodiscouragealternatives.IfyoulearnTheRailsWayyoullprobablydiscoveratremendousincreaseinproductivity.Ifyoupersist inbringingoldhabitsfromotherlanguagestoyourRailsdevelopment,andtryingtousepatternsyoulearnedelsewhere,youmayhavealess happyexperience. TheRailsphilosophyincludesseveralguidingprinciples: DRYDontRepeatYourselfsuggeststhatwritingthesamecodeoverandoveragainisabadthing. ConventionOverConfigurationmeansthatRailsmakesassumptionsaboutwhatyouwanttodoandhowyouregoingtodoit,rather thanrequiringyoutospecifyeverylittlethingthroughendlessconfigurationfiles.

2 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

RESTisthebestpatternforwebapplicationsorganizingyourapplicationaroundresourcesandstandardHTTPverbsisthefastest waytogo.

2.1 The MVC Architecture


AtthecoreofRailsistheModel,View,Controllerarchitecture,usuallyjustcalledMVC.MVCbenefitsinclude: Isolationofbusinesslogicfromtheuserinterface EaseofkeepingcodeDRY Makingitclearwheredifferenttypesofcodebelongforeasiermaintenance 2.1.1 Models Amodelrepresentstheinformation(data)oftheapplicationandtherulestomanipulatethatdata.InthecaseofRails,modelsareprimarily usedformanagingtherulesofinteractionwithacorrespondingdatabasetable.Inmostcases,onetableinyourdatabasewillcorrespondto onemodelinyourapplication.Thebulkofyourapplicationsbusinesslogicwillbeconcentratedinthemodels. 2.1.2 Views Viewsrepresenttheuserinterfaceofyourapplication.InRails,viewsareoftenHTMLfileswithembeddedRubycodethatperformtasksrelated solelytothepresentationofthedata.Viewshandlethejobofprovidingdatatothewebbrowserorothertoolthatisusedtomakerequests fromyourapplication. 2.1.3 Controllers Controllersprovidethegluebetweenmodelsandviews.InRails,controllersareresponsibleforprocessingtheincomingrequestsfromtheweb browser,interrogatingthemodelsfordata,andpassingthatdataontotheviewsforpresentation.

2.2 The Components of Rails


Railsshipsasmanyindividualcomponents. ActionPack ActionController ActionDispatch ActionView ActionMailer ActiveModel ActiveRecord ActiveResource ActiveSupport Railties 2.2.1 Action Pack ActionPackisasinglegemthatcontainsActionController,ActionViewandActionDispatch.TheVCpartofMVC. 2.2.2 Action Controller ActionControlleristhecomponentthatmanagesthecontrollersinaRailsapplication.TheActionControllerframeworkprocessesincoming requeststoaRailsapplication,extractsparameters,anddispatchesthemtotheintendedaction.ServicesprovidedbyActionControllerinclude sessionmanagement,templaterendering,andredirectmanagement. 2.2.3 Action View ActionViewmanagestheviewsofyourRailsapplication.ItcancreatebothHTMLandXMLoutputbydefault.ActionViewmanagesrendering templates,includingnestedandpartialtemplates,andincludesbuilt-inAJAXsupport. 2.2.4 Action Dispatch ActionDispatchhandlesroutingofwebrequestsanddispatchesthemasyouwant,eithertoyourapplicationoranyotherRackapplication. 2.2.5 Action Mailer ActionMailerisaframeworkforbuildinge-mailservices.YoucanuseActionMailertoreceiveandprocessincomingemailandsendsimpleplain textorcomplexmultipartemailsbasedonflexibletemplates.

3 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

2.2.6 Active Model ActiveModelprovidesadefinedinterfacebetweentheActionPackgemservicesandObjectRelationshipMappinggemssuchasActiveRecord. ActiveModelallowsRailstoutilizeotherORMframeworksinplaceofActiveRecordifyourapplicationneedsthis. 2.2.7 Active Record ActiveRecordisthebaseforthemodelsinaRailsapplication.Itprovidesdatabaseindependence,basicCRUDfunctionality,advancedfinding capabilities,andtheabilitytorelatemodelstooneanother,amongotherservices. 2.2.8 Active Resource ActiveResourceprovidesaframeworkformanagingtheconnectionbetweenbusinessobjectsandRESTfulwebservices.Itimplementsaway tomapweb-basedresourcestolocalobjectswithCRUDsemantics. 2.2.9 Active Support ActiveSupportisanextensivecollectionofutilityclassesandstandardRubylibraryextensionsthatareusedintheRails,bothbythecorecode andbyyourapplications. 2.2.10 Railties RailtiesisthecoreRailscodethatbuildsnewRailsapplicationsandgluesthevariousframeworksandpluginstogetherinanyRailsapplication.

2.3 REST
ReststandsforRepresentationalStateTransferandisthefoundationoftheRESTfularchitecture.ThisisgenerallyconsideredtobeRoy Fieldingsdoctoralthesis,ArchitecturalStylesandtheDesignofNetwork-basedSoftwareArchitectures.Whileyoucanreadthroughthe thesis,RESTintermsofRailsboilsdowntotwomainprinciples: UsingresourceidentifierssuchasURLstorepresentresources. Transferringrepresentationsofthestateofthatresourcebetweensystemcomponents. Forexample,toaRailsapplicationarequestsuchasthis: DELETE /photos/17 wouldbeunderstoodtorefertoaphotoresourcewiththeIDof17,andtoindicateadesiredactiondeletingthatresource.RESTisanatural styleforthearchitectureofwebapplications,andRailshooksintothisshieldingyoufrommanyoftheRESTfulcomplexitiesandbrowserquirks. IfyoudlikemoredetailsonRESTasanarchitecturalstyle,theseresourcesaremoreapproachablethanFieldingsthesis: ABriefIntroductiontoRESTbyStefanTilkov AnIntroductiontoREST(videotutorial)byJoeGregorio RepresentationalStateTransferarticleinWikipedia HowtoGETaCupofCoffeebyJimWebber,SavasParastatidis&IanRobinson

3 Creating a New Rails Project


Ifyoufollowthisguide,youllcreateaRailsprojectcalledblog,a(very)simpleweblog.Beforeyoucanstartbuildingtheapplication,youneed tomakesurethatyouhaveRailsitselfinstalled.

3.1 Installing Rails


Inmostcases,theeasiestwaytoinstallRailsistotakeadvantageofRubyGems:

Usually run this as the root user: # gem install rails

IfyoureworkingonWindows,youshouldbeawarethatthevastmajorityofRailsdevelopmentisdoneinUnixenvironments.WhileRubyand RailsthemselvesinstalleasilyusingforexampleRubyInstaller,thesupportingecosystemoftenassumesyouareabletobuildC-based rubygemsandworkinacommandwindow.Ifatallpossible,wesuggestthatyouinstallaLinuxvirtualmachineandusethatforRails development,insteadofusingWindows.

4 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails


3.2 Creating the Blog Application

http://guides.rubyonrails.org/getting_started.html#...

Thebestwaytousethisguideistofolloweachstepasithappens,nocodeorstepneededtomakethisexampleapplicationhasbeenleftout, soyoucanliterallyfollowalongstepbystep.Ifyouneedtoseethecompletedcode,youcandownloaditfromGettingStartedCode. Tobegin,openaterminal,navigatetoafolderwhereyouhaverightstocreatefiles,andtype:

$ rails new blog

ThiswillcreateaRailsapplicationcalledBloginadirectorycalledblog. YoucanseealloftheswitchesthattheRailsapplicationbuilderacceptsbyrunningrails -h. Afteryoucreatetheblogapplication,switchtoitsfoldertocontinueworkdirectlyinthatapplication:

$ cd blog

Inanycase,Railswillcreateafolderinyourworkingdirectorycalledblog.Openupthatfolderandexploreitscontents.Mostoftheworkinthis tutorialwillhappenintheapp/folder,butheresabasicrundownonthefunctionofeachfolderthatRailscreatesinanewapplicationby default: File/Folder Gemfile README.rdoc Rakefile app/ config/ config.ru db/ doc/ lib/ log/ public/ script/ test/ tmp/ vendor/ Purpose ThisfileallowsyoutospecifywhatgemdependenciesareneededforyourRailsapplication. Thisisabriefinstructionmanualforyourapplication.Useittotellotherswhatyourapplicationdoes,howtosetitup,and soon. Thisfilecontainsbatchjobsthatcanberunfromtheterminal. Containsthecontrollers,models,andviewsforyourapplication.Youllfocusonthisfolderfortheremainderofthisguide. Configureyourapplicationsruntimerules,routes,database,andmore. RackconfigurationforRackbasedserversusedtostarttheapplication. Showsyourcurrentdatabaseschema,aswellasthedatabasemigrations.Youlllearnaboutmigrationsshortly. In-depthdocumentationforyourapplication. Extendedmodulesforyourapplication(notcoveredinthisguide). Applicationlogfiles. Theonlyfolderseentotheworldas-is.Thisiswhereyourimages,javascript,stylesheets(CSS),andotherstaticfilesgo. Containstherailsscriptthatstartsyourappandcancontainotherscriptsyouusetodeployorrunyourapplication. Unittests,fixtures,andothertestapparatus.ThesearecoveredinTestingRailsApplications Temporaryfiles Aplaceforallthird-partycode.InatypicalRailsapplication,thisincludesRubyGems,theRailssourcecode(ifyouinstall itintoyourproject)andpluginscontainingadditionalprepackagedfunctionality.

3.3 Installing the Required Gems


RailsapplicationsmanagegemdependencieswithBundlerbydefault.Aswedontneedanyothergemsbeyondtheonesinthegenerated Gemfilewecandirectlyrun

bundle install

tohavethemready.

3.4 Configuring a Database

5 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

JustabouteveryRailsapplicationwillinteractwithadatabase.Thedatabasetouseisspecifiedinaconfigurationfile,config/database.yml. IfyouopenthisfileinanewRailsapplication,youllseeadefaultdatabaseconfigurationusingSQLite3.Thefilecontainssectionsforthree differentenvironmentsinwhichRailscanrunbydefault: Thedevelopmentenvironmentisusedonyourdevelopmentcomputerasyouinteractmanuallywiththeapplication Thetestenvironmentisusedtorunautomatedtests Theproductionenvironmentisusedwhenyoudeployyourapplicationfortheworldtouse. 3.4.1 Configuring an SQLite3 Database Railscomeswithbuilt-insupportforSQLite3,whichisalightweightserverlessdatabaseapplication.Whileabusyproductionenvironmentmay overloadSQLite,itworkswellfordevelopmentandtesting.RailsdefaultstousinganSQLitedatabasewhencreatinganewproject,butyoucan alwayschangeitlater. Heresthesectionofthedefaultconfigurationfile(config/database.yml)withconnectioninformationforthedevelopmentenvironment:

development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000

InthisguideweareusinganSQLite3databasefordatastorage,becauseitisazeroconfigurationdatabasethatjustworks.Railsalsosupports MySQLandPostgreSQLoutofthebox,andhaspluginsformanydatabasesystems.Ifyouareusingadatabaseinaproductionenvironment Railsmostlikelyhasanadapterforit. 3.4.2 Configuring a MySQL Database IfyouchoosetouseMySQLinsteadoftheshippedSqlite3database,yourconfig/database.ymlwilllookalittledifferent.Heresthe developmentsection:

development: adapter: mysql2 encoding: utf8 database: blog_development pool: 5 username: root password: socket: /tmp/mysql.sock

IfyourdevelopmentcomputersMySQLinstallationincludesarootuserwithanemptypassword,thisconfigurationshouldworkforyou. Otherwise,changetheusernameandpasswordinthedevelopmentsectionasappropriate. 3.4.3 Configuring a PostgreSQL Database FinallyifyouchoosetousePostgreSQL,yourconfig/database.ymlwillbecustomizedtousePostgreSQLdatabases:

6 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

development: adapter: postgresql encoding: unicode database: blog_development pool: 5 username: blog password:

Changetheusernameandpasswordinthedevelopmentsectionasappropriate.

3.5 Creating the Database


Nowthatyouhaveyourdatabaseconfigured,itstimetohaveRailscreateanemptydatabaseforyou.Youcandothisbyrunningarake command:

$ rake db:create

ThiswillcreateyourdevelopmentandtestSQLite3databasesinsidethedb/folder. Rakeisageneral-purposecommand-runnerthatRailsusesformanythings.Youcanseethelistofavailablerakecommandsinyourapplication byrunningrake -T.

4 Hello, Rails!
Oneofthetraditionalplacestostartwithanewlanguageisbygettingsometextuponscreenquickly,todothis,youneedtogetyourRails applicationserverrunning.

4.1 Starting up the Web Server


YouactuallyhaveafunctionalRailsapplicationalready.Toseeit,youneedtostartawebserveronyourdevelopmentmachine.Youcando thisbyrunning:

$ rails server

ThiswillfireupaninstanceoftheMongrelwebserverbydefault(Railscanalsouseseveralotherwebservers).Toseeyourapplicationin action,openabrowserwindowandnavigatetohttp://localhost:3000.YoushouldseeRailsdefaultinformationpage: Tostoptheweb server,hitCtrl+C intheterminal windowwhereits running.In development mode,Railsdoes notgenerally requireyouto stoptheserver; changesyou makeinfileswill beautomatically pickedupbythe server. TheWelcome Aboardpageis

7 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...
thesmoketest foranewRails application:it makessurethat youhaveyour software configured correctlyenough toserveapage. Youcanalso clickonthe Aboutyour

applicationsenvironmentlinktoseeasummaryofyourApplicationsenvironment.

4.2 Say Hello, Rails


TogetRailssayingHello,youneedtocreateatminimumacontrollerandaview.Fortunately,youcandothatinasinglecommand.Enterthis commandinyourterminal:

$ rails generate controller home index

IfyoureonWindows,oryourRubyissetupinsomenon-standardfashion,youmayneedtoexplicitlypassRailsrailscommandstoRuby: ruby \path\to\rails controller home index. Railswillcreateseveralfilesforyou,includingapp/views/home/index.html.erb.Thisisthetemplatethatwillbeusedtodisplaytheresults oftheindexaction(method)inthehomecontroller.Openthisfileinyourtexteditorandeditittocontainasinglelineofcode:


<h1>Hello, Rails!</h1>

4.3 Setting the Application Home Page


Nowthatwehavemadethecontrollerandview,weneedtotellRailswhenwewantHelloRailstoshowup.Inourcase,wewantittoshowup whenwenavigatetotherootURLofoursite,http://localhost:3000,insteadoftheWelcomeAboardsmoketest. Thefirststeptodoingthisistodeletethedefaultpagefromyourapplication:

$ rm public/index.html

WeneedtodothisasRailswilldeliveranystaticfileinthepublicdirectoryinpreferencetoanydynamiccontactwegeneratefromthe controllers. Now,youhavetotellRailswhereyouractualhomepageislocated.Openthefileconfig/routes.rbinyoureditor.Thisisyourapplications routingfilewhichholdsentriesinaspecialDSL(domain-specificlanguage)thattellsRailshowtoconnectincomingrequeststocontrollersand actions.Thisfilecontainsmanysampleroutesoncommentedlines,andoneofthemactuallyshowsyouhowtoconnecttherootofyoursiteto aspecificcontrollerandaction.Findthelinebeginningwith:root to,uncommentitandchangeitlikethefollowing:

Blog::Application.routes.draw do #... # You can have the root of your site routed with "root" # just remember to delete public/index.html. root :to => "home#index"

8 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Theroot :to => "home#index"tellsRailstomaptherootactiontothehomecontrollersindexaction. Nowifyounavigatetohttp://localhost:3000inyourbrowser,youllseeHello, Rails!. Formoreinformationaboutrouting,refertoRailsRoutingfromtheOutsideIn.

5 Getting Up and Running Quickly with Scaffolding


Railsscaffoldingisaquickwaytogeneratesomeofthemajorpiecesofanapplication.Ifyouwanttocreatethemodels,views,andcontrollers foranewresourceinasingleoperation,scaffoldingisthetoolforthejob.

6 Creating a Resource
Inthecaseoftheblogapplication,youcanstartbygeneratingascaffoldedPostresource:thiswillrepresentasingleblogposting.Todothis, enterthiscommandinyourterminal:

$ rails generate scaffold Post name:string title:string content:text

Whilescaffoldingwillgetyouupandrunningquickly,theonesizefitsallcodethatitgeneratesisunlikelytobeaperfectfitforyourapplication. Inmostcases,youllneedtocustomizethegeneratedcode.ManyexperiencedRailsdevelopersavoidscaffoldingentirely,preferringtowriteall ormostoftheirsourcecodefromscratch. Thescaffoldgeneratorwillbuild15filesinyourapplication,alongwithsomefolders,andeditonemore.Heresaquickoverviewofwhatit creates: File db/migrate /20100207214725_create_posts.rb.rb app/models/post.rb test/fixtures/posts.yml app/controllers/posts_controller.rb app/views/posts/index.html.erb app/views/posts/edit.html.erb app/views/posts/show.html.erb app/views/posts/new.html.erb app/views/posts/_form.html.erb app/helpers/posts_helper.rb test/unit/post_test.rb test/functional/posts_controller_test.rb test/unit/helpers/posts_helper_test.rb config/routes.rb public/stylesheets/scaffold.css Purpose Migrationtocreatethepoststableinyourdatabase(yournamewillincludeadifferent timestamp) ThePostmodel Dummypostsforuseintesting ThePostscontroller Aviewtodisplayanindexofallposts Aviewtoeditanexistingpost Aviewtodisplayasinglepost Aviewtocreateanewpost Apartialtocontroltheoveralllookandfeeloftheformusedineditandnewviews Helperfunctionstobeusedfromthepostviews Unittestingharnessforthepostsmodel Functionaltestingharnessforthepostscontroller Unittestingharnessforthepostshelper Editedtoincluderoutinginformationforposts Cascadingstylesheettomakethescaffoldedviewslookbetter

6.1 Running a Migration


Oneoftheproductsoftherails generate scaffoldcommandisadatabasemigration.MigrationsareRubyclassesthataredesignedto makeitsimpletocreateandmodifydatabasetables.Railsusesrakecommandstorunmigrations,anditspossibletoundoamigrationafterits beenappliedtoyourdatabase.Migrationfilenamesincludeatimestamptoensurethattheyreprocessedintheorderthattheywerecreated. Ifyoulookinthedb/migrate/20100207214725_create_posts.rbfile(remember,yourswillhaveaslightlydifferentname),hereswhat youllfind:

9 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

class CreatePosts < ActiveRecord::Migration def self .up create_table :posts do |t| t.string :name t.string :title t.text :content t.timestamps end end def self .down drop_table :posts end end

Theabovemigrationcreatestwomethods,up,calledwhenyourunthismigrationintothedatabase,anddownincaseyouneedtoreversethe changesmadebythismigrationatalaterdate.Theupcommandinthiscasecreatesapoststablewithtwostringcolumnsandatextcolumn. Italsocreatestwotimestampfieldstotrackrecordcreationandupdating.MoreinformationaboutRailsmigrationscanbefoundintheRails DatabaseMigrationsguide. Atthispoint,youcanusearakecommandtorunthemigration:

$ rake db:migrate

RailswillexecutethismigrationcommandandtellyouitcreatedthePoststable.

== CreatePosts: migrating ==================================================== -- create_table(:posts) -> 0.0019s == CreatePosts: migrated (0.0020s) ===========================================

Becauseyoureworkinginthedevelopmentenvironmentbydefault,thiscommandwillapplytothedatabasedefinedinthedevelopment sectionofyourconfig/database.ymlfile.

6.2 Adding a Link


Tohookthepostsuptothehomepageyouvealreadycreated,youcanaddalinktothehomepage.Openapp/views /home/index.html.erbandmodifyitasfollows:

10 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails


<h1>Hello, Rails!</h1> <%= link_to "My Blog", posts_path %>

http://guides.rubyonrails.org/getting_started.html#...

Thelink_tomethodisoneofRailsbuilt-inviewhelpers.Itcreatesahyperlinkbasedontexttodisplayandwheretogointhiscase,tothe pathforposts.

6.3 Working with Posts in the Browser


Nowyourereadytostartworkingwithposts.Todothat,navigatetohttp://localhost:3000andthenclicktheMyBloglink: ThisistheresultofRailsrenderingtheindexviewofyourposts.Therearentcurrentlyanyposts inthedatabase,butifyouclicktheNew Postlinkyoucancreateone.Afterthat,youllfindthat youcaneditposts,lookattheirdetails,ordestroythem.AllofthelogicandHTMLtohandlethis wasbuiltbythesinglerails generate scaffoldcommand. Indevelopmentmode(whichiswhatyoureworkinginbydefault),Railsreloadsyourapplication witheverybrowserrequest,sotheresnoneedtostopandrestartthewebserver. Congratulations,youreridingtherails!Nowitstimetoseehowitallworks.

6.4 The Model


Themodelfile,app/models/post.rbisaboutassimpleasitcanget:

class Post < ActiveRecord::Base end

ThereisntmuchtothisfilebutnotethatthePostclassinheritsfromActiveRecord::Base.ActiveRecordsuppliesagreatdealof functionalitytoyourRailsmodelsforfree,includingbasicdatabaseCRUD(Create,Read,Update,Destroy)operations,datavalidation,aswell assophisticatedsearchsupportandtheabilitytorelatemultiplemodelstooneanother.

6.5 Adding Some Validation


Railsincludesmethodstohelpyouvalidatethedatathatyousendtomodels.Opentheapp/models/post.rbfileandeditit:

class Post < ActiveRecord::Base validates :name , :presence => true validates :title , :presence => true , :length => { :minimum => 5 } end

11 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Thesechangeswillensurethatallpostshaveanameandatitle,andthatthetitleisatleastfivecharacterslong.Railscanvalidateavarietyof conditionsinamodel,includingthepresenceoruniquenessofcolumns,theirformat,andtheexistenceofassociatedobjects.

6.6 Using the Console


Toseeyourvalidationsinaction,youcanusetheconsole.Theconsoleisacommand-linetoolthatletsyouexecuteRubycodeinthecontext ofyourapplication:

$ rails console

Aftertheconsoleloads,youcanuseittoworkwithyourapplicationsmodels:

>> p = Post.new(:content => "A new post") => #<Post id: nil, name: nil, title: nil, content: "A new post", created_at: nil, updated_at: nil> >> p.save => false >> p.errors => #<OrderedHash { :title=>["can't be blank", "is too short (minimum is 5 characters)"], :name=>["can't be blank"] }>

ThiscodeshowscreatinganewPostinstance,attemptingtosaveitandgettingfalseforareturnvalue(indicatingthatthesavefailed),and inspectingtheerrorsofthepost. Whenyourefinished,typeexitandhitreturntoexittheconsole. Unlikethedevelopmentwebserver,theconsoledoesnotautomaticallyloadyourcodeafreshforeachline.Ifyoumakechangestoyourmodels whiletheconsoleisopen,typereload!attheconsoleprompttoloadthem.

6.7 Listing All Posts


Theeasiestplacetostartlookingatfunctionalityiswiththecodethatlistsallposts.Openthefileapp/controllers/posts_controller.rb andlookattheindexaction:

def index @posts = Post.all respond_to do |format| format.html # index.html.erb format.xml :xml => @posts } end end { render

12 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Post.allcallsthePostmodeltoreturnallofthepostscurrentlyinthedatabase.Theresultofthiscallisanarraycontainingthepostswhich hasbeensavedinaninstancevariablecalled@posts. FormoreinformationonfindingrecordswithActiveRecord,seeActiveRecordQueryInterface. Therespond_toblockhandlesbothHTMLandXMLcallstothisaction.Ifyoubrowsetohttp://localhost:3000/posts.xml,youllseeallofthe postsinXMLformat.TheHTMLformatlooksforaviewinapp/views/posts/withanamethatcorrespondstotheactionname.Railsmakesall oftheinstancevariablesfromtheactionavailabletotheview.Heresapp/views/posts/index.html.erb:

13 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< h1 >Listing posts</ h1 > < table > < tr > < th >Name</ th > < th >Title</ th > < th >Content</ th > < th ></ th > < th ></ th > < th ></ th > </ tr > <% @posts . each do |post| %> < tr > < td > <%= post.name %> </ td > < td > <%= post.title %> </ td > <

14 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Thisviewiteratesoverthecontentsofthe@postsarraytodisplaycontentandlinks.Afewthingstonoteintheview: link_tobuildsahyperlinktoaparticulardestination edit_post_pathandnew_post_patharehelpersthatRailsprovidesaspartofRESTfulrouting.Youllseeavarietyofthesehelpers forthedifferentactionsthatthecontrollerincludes. InpreviousversionsofRails,youhadtouse<%=h post.name %>sothatanyHTMLwouldbeescapedbeforebeinginsertedintothepage.In Rails3.0,thisisnowthedefault.TogetunescapedHTML,younowuse<%= raw post.name %>. Formoredetailsontherenderingprocess,seeLayoutsandRenderinginRails.

6.8 Customizing the Layout


TheviewisonlypartofthestoryofhowHTMLisdisplayedinyourwebbrowser.Railsalsohastheconceptoflayouts,whicharecontainersfor views.WhenRailsrendersaviewtothebrowser,itdoessobyputtingtheviewsHTMLintoalayoutsHTML.InpreviousversionsofRails,the rails generate scaffoldcommandwouldautomaticallycreateacontrollerspecificlayout,likeapp/views/layouts/posts.html.erb,for thepostscontroller.HoweverthishasbeenchangedinRails3.0.Aapplicationspecificlayoutisusedforallthecontrollersandcanbefound inapp/views/layouts/application.html.erb.Openthislayoutinyoureditorandmodifythebodytag:

<!DOCTYPE html> < html > < head > < title >Blog</ title > <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> </ head > < body style = "background: #EEEEEE;" > <%= yield %> </ body > </ html >

15 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Nowwhenyourefreshthe/postspage,youllseeagraybackgroundtothepage.Thissamegraybackgroundwillbeusedthroughoutallthe viewsforposts.

6.9 Creating New Posts


Creatinganewpostinvolvestwoactions.Thefirstisthenewaction,whichinstantiatesanemptyPostobject:

def new @post = Post. new respond_to do |format| format.html # new.html.erb format.xml :xml => @post } end end { render

Thenew.html.erbviewdisplaysthisemptyPosttotheuser:

< h1 >New post</ h1 > <%= render 'form' %> <%= link_to 'Back' , posts_path %>

The<%= render 'form' %>lineisourfirstintroductiontopartialsinRails.ApartialisasnippetofHTMLandRubycodethatcanbereusedin multiplelocations.Inthiscase,theformusedtomakeanewpost,isbasicallyidenticaltoaformusedtoeditapost,bothhavetextfieldsforthe nameandtitleandatextareaforthecontentwithabuttontomakeanewpostorupdatetheexistingpost. Ifyoutakealookatviews/posts/_form.html.erbfile,youwillseethefollowing:

16 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

<%= form_for( @post ) do |f| %> <% if @post .errors.any? %> < div id = "errorExplanation" > < h2 > <%= pluralize( @post .errors.count, "error" ) %> prohibited this post from being saved:</ h2 > < ul > <% @post .errors.full_messages. each do |msg| %> < li > <%= msg %> </ li > <% end %> </ ul > </ div > <% end

17 of 51

%> < div

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Thispartialreceivesalltheinstancevariablesdefinedinthecallingviewfile,sointhiscase,thecontrollerassignedthenewPostobjectto @postandso,thisisavailableinboththeviewandpartialas@post. Formoreinformationonpartials,refertotheLayoutsandRenderinginRailsguide. Theform_forblockisusedtocreateanHTMLform.Withinthisblock,youhaveaccesstomethodstobuildvariouscontrolsontheform.For example,f.text_field :nametellsRailstocreateatextinputontheform,andtohookituptothenameattributeoftheinstancebeing displayed.Youcanonlyusethesemethodswithattributesofthemodelthattheformisbasedon(inthiscasename,title,andcontent). Railsusesform_forinpreferencetohavingyouwriterawHTMLbecausethecodeismoresuccinct,andbecauseitexplicitlytiestheformtoa particularmodelinstance. Theform_forblockisalsosmartenoughtoworkoutifyouaredoingaNewPostoranEditPostaction,andwillsettheformactiontagsand submitbuttonnamesappropriatelyintheHTMLoutput. IfyouneedtocreateanHTMLformthatdisplaysarbitraryfields,nottiedtoamodel,youshouldusetheform_tagmethod,whichprovides shortcutsforbuildingformsthatarenotnecessarilytiedtoamodelinstance. WhentheuserclickstheCreate Postbuttononthisform,thebrowserwillsendinformationbacktothecreatemethodofthecontroller(Rails knowstocallthecreatemethodbecausetheformissentwithanHTTPPOSTrequest;thatsoneoftheconventionsthatImentionedearlier):

18 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

def create @post = Post. new (params[ :post ]) respond_to do |format| if @post .save format.html { redirect_to( @post , :notice => 'Post was successfully created.' ) } format.xml :xml => @post , :status => :created , :location => @post } else format.html { render :action => "new" } format.xml :xml => @post .errors, :status => :unprocessable_entity } end end end { render { render

19 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

ThecreateactioninstantiatesanewPostobjectfromthedatasuppliedbytheuserontheform,whichRailsmakesavailableintheparams hash.Aftersuccessfullysavingthenewpost,createreturnstheappropriateformatthattheuserhasrequested(HTMLinourcase).Itthen redirectstheusertotheresultingpostshowactionandsetsanoticetotheuserthatthePostwassuccessfullycreated. Ifthepostwasnotsuccessfullysaved,duetoavalidationerror,thenthecontrollerreturnstheuserbacktothenewactionwithanyerror messagessothattheuserhasthechancetofixtheerrorandtryagain. ThePostwassuccessfullycreatedmessageisstoredinsideoftheRailsflashhash,(usuallyjustcalledtheFlash)sothatmessagescanbe carriedovertoanotheraction,providingtheuserwithusefulinformationonthestatusoftheirrequest.Inthecaseofcreate,theusernever actuallyseesanypagerenderedduringthePostcreationprocess,becauseitimmediatelyredirectstothenewPostassoonRailssavesthe record.TheFlashcarriesoveramessagetothenextaction,sothatwhentheuserisredirectedbacktotheshowaction,theyarepresented withamessagesayingPostwassuccessfullycreated.

6.10 Showing an Individual Post


Whenyouclicktheshowlinkforapostontheindexpage,itwillbringyoutoaURLlikehttp://localhost:3000/posts/1.Railsinterprets thisasacalltotheshowactionfortheresource,andpassesin1asthe:idparameter.Herestheshowaction:

def show @post = Post.find(params[ :id ]) respond_to do |format| format.html # show.html.erb format.xml :xml => @post } end end { render

TheshowactionusesPost.findtosearchforasinglerecordinthedatabasebyitsidvalue.Afterfindingtherecord,Railsdisplaysitbyusing show.html.erb:

20 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > <%= link_to 'Edit' , edit_post_path( @post ) %> | <%= link_to 'Back' , posts_path %>

21 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails


6.11 Editing Posts

http://guides.rubyonrails.org/getting_started.html#...

Likecreatinganewpost,editingapostisatwo-partprocess.Thefirststepisarequesttoedit_post_path(@post)withaparticularpost.This callstheeditactioninthecontroller:

def edit @post = Post.find(params[ :id ]) end

Afterfindingtherequestedpost,Railsusestheedit.html.erbviewtodisplayit:

< h1 >Editing post</ h1 > <%= render 'form' %> <%= link_to 'Show' , @post %> | <%= link_to 'Back' , posts_path %>

Again,aswiththenewaction,theeditactionisusingtheformpartial,thistimehowever,theformwilldoaPUTactiontothePostsController andthesubmitbuttonwilldisplayUpdatePost Submittingtheformcreatedbythisviewwillinvoketheupdateactionwithinthecontroller:

22 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

def update @post = Post.find(params[ :id ]) respond_to do |format| if @post .update_attributes(params[ :post ]) format.html { redirect_to( @post , :notice => 'Post was successfully updated.' ) } format.xml :ok } else format.html { render :action => "edit" } format.xml :xml => @post .errors, :status => :unprocessable_entity } end end end { render { head

Intheupdateaction,Railsfirstusesthe:idparameterpassedbackfromtheeditviewtolocatethedatabaserecordthatsbeingedited.The update_attributescallthentakestherestoftheparametersfromtherequestandappliesthemtothisrecord.Ifallgoeswell,theuseris redirectedtothepostsshowview.Ifthereareanyproblems,itsbacktotheeditviewtocorrectthem.

6.12 Destroying a Post


Finally,clickingoneofthedestroylinkssendstheassociatedidtothedestroyaction:

23 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

def destroy @post = Post.find(params[ :id ]) @post .destroy respond_to do |format| format.html { redirect_to(posts_url) } format.xml :ok } end end { head

ThedestroymethodofanActiveRecordmodelinstanceremovesthecorrespondingrecordfromthedatabase.Afterthatsdone,thereisnt anyrecordtodisplay,soRailsredirectstheusersbrowsertotheindexviewforthemodel.

7 Adding a Second Model


Nowthatyouveseenhowamodelbuiltwithscaffoldinglookslike,itstimetoaddasecondmodeltotheapplication.Thesecondmodelwill handlecommentsonblogposts.

7.1 Generating a Model


ModelsinRailsuseasingularname,andtheircorrespondingdatabasetablesuseapluralname.Forthemodeltoholdcomments,the conventionistousethenameComment.Evenifyoudontwanttousetheentireapparatussetupbyscaffolding,mostRailsdevelopersstill usegeneratorstomakethingslikemodelsandcontrollers.Tocreatethenewmodel,runthiscommandinyourterminal:

$ rails generate model Comment commenter:string body:text post:references

Thiscommandwillgeneratefourfiles: app/models/comment.rbThemodel db/migrate/20100207235629_create_comments.rbThemigration test/unit/comment_test.rbandtest/fixtures/comments.ymlThetestharness. First,takealookatcomment.rb:

class Comment < ActiveRecord::Base belongs_to :post end

Thisisverysimilartothepost.rbmodelthatyousawearlier.Thedifferenceisthelinebelongs_to :post,whichsetsupanActiveRecord association.Youlllearnalittleaboutassociationsinthenextsectionofthisguide. Inadditiontothemodel,Railshasalsomadeamigrationtocreatethecorrespondingdatabasetable:

24 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

class CreateComments < ActiveRecord::Migration def self .up create_table :comments do |t| t.string :commenter t.text :body t.references :post t.timestamps end end def self .down drop_table :comments end end

Thet.referenceslinesetsupaforeignkeycolumnfortheassociationbetweenthetwomodels.Goaheadandrunthemigration:

$ rake db:migrate

Railsissmartenoughtoonlyexecutethemigrationsthathavenotalreadybeenrunagainstthecurrentdatabase,sointhiscaseyouwilljust see:

== CreateComments: migrating ================================================= -- create_table(:comments) -> 0.0017s == CreateComments: migrated (0.0018s) ========================================

7.2 Associating Models


ActiveRecordassociationsletyoueasilydeclaretherelationshipbetweentwomodels.Inthecaseofcommentsandposts,youcouldwriteout therelationshipsthisway: Eachcommentbelongstoonepost Onepostcanhavemanycomments Infact,thisisveryclosetothesyntaxthatRailsusestodeclarethisassociation.YouvealreadyseenthelineofcodeinsidetheComment modelthatmakeseachcommentbelongtoaPost:

25 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

class Comment < ActiveRecord::Base belongs_to :post end

Youllneedtoeditthepost.rbfiletoaddtheothersideoftheassociation:

class Post < ActiveRecord::Base validates :name , :presence => true validates :title , :presence => true , :length => { :minimum => 5 } has_many :comments end

Thesetwodeclarationsenableagoodbitofautomaticbehavior.Forexample,ifyouhaveaninstancevariable@postcontainingapost,you canretrieveallthecommentsbelongingtothatpostasthearray@post.comments. FormoreinformationonActiveRecordassociations,seetheActiveRecordAssociationsguide.

7.3 Adding a Route for Comments


Aswiththehomecontroller,wewillneedtoaddaroutesothatRailsknowswherewewouldliketonavigatetoseecomments.Openupthe config/routes.rbfileagain,youwillseeanentrythatwasaddedautomaticallyforpostsnearthetopbythescaffoldgenerator,resources :posts,edititasfollows:

resources :posts do resources :comments end

Thiscreatescommentsasanestedresourcewithinposts.Thisisanotherpartofcapturingthehierarchicalrelationshipthatexistsbetween postsandcomments.

26 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Formoreinformationonrouting,seetheRailsRoutingfromtheOutsideInguide.

7.4 Generating a Controller


Withthemodelinhand,youcanturnyourattentiontocreatingamatchingcontroller.Again,theresageneratorforthis:

$ rails generate controller Comments

Thiscreatesfourfilesandoneemptydirectory: app/controllers/comments_controller.rbThecontroller app/helpers/comments_helper.rbAviewhelperfile test/functional/comments_controller_test.rbThefunctionaltestsforthecontroller test/unit/helpers/comments_helper_test.rbTheunittestsforthehelper app/views/comments/Viewsofthecontrollerarestoredhere Likewithanyblog,ourreaderswillcreatetheircommentsdirectlyafterreadingthepost,andoncetheyhaveaddedtheircomment,willbesent backtothepostshowpagetoseetheircommentnowlisted.Duetothis,ourCommentsControlleristheretoprovideamethodtocreate commentsanddeleteSPAMcommentswhentheyarrive. Sofirst,wellwireupthePostshowtemplate(/app/views/posts/show.html.erb)toletusmakeanewcomment:

27 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > < h2 >Add a comment:</ h2 > <%= form_for([ @post , @post .comments.build]) do

28 of 51

|f| %> < div

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

ThisaddsaformonthePostshowpagethatcreatesanewcomment,whichwillcalltheCommentsControllercreateaction,soletswirethat up:

class CommentsController < ApplicationController def create @post = Post.find(params[ :post_id ]) @comment = @post .comments.create(params[ :comment ]) redirect_to post_path( @post ) end end

Youllseeabitmorecomplexityherethanyoudidinthecontrollerforposts.Thatsaside-effectofthenestingthatyouvesetup;eachrequest foracommenthastokeeptrackoftheposttowhichthecommentisattached,thustheinitialfindactiontothePostmodeltogetthepostin question. Inaddition,thecodetakesadvantageofsomeofthemethodsavailableforanassociation.Weusethecreatemethodon@post.comments tocreateandsavethecomment.Thiswillautomaticallylinkthecommentsothatitbelongstothatparticularpost. Oncewehavemadethenewcomment,wesendtheuserbacktotheoriginalpostusingthepost_path(@post)helper.Aswehavealready seen,thiscallstheshowactionofthePostsControllerwhichinturnrenderstheshow.html.erbtemplate.Thisiswherewewantthe commenttoshow,soletsaddthattotheapp/views/posts/show.html.erb.

29 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > < h2 >Comments</ h2 > <% @post .comments. each do |comment| %> < p >

30 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Nowyoucanaddpostsandcommentstoyourblogandhavethemshowupintherightplaces.

8 Refactoring
NowthatwehavePostsandCommentsworking,ifwetakealookattheapp/views/posts/show.html.erbtemplate,itsgettinglongand awkward.Wecanusepartialstocleanthisup.

8.1 Rendering Partial Collections


Firstwewillmakeacommentpartialtoextractshowingallthecommentsforthepost.Createthefileapp/views/comments /_comment.html.erbandputthefollowingintoit:

< p > < b >Commenter:</ b > <%= comment.commenter %> </ p > < p > < b >Comment:</ b > <%= comment.body %> </ p >

Thenintheapp/views/posts/show.html.erbyoucanchangeittolooklikethefollowing:

31 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > < h2 >Comments</ h2 > <%= render :partial => "comments/comment" ,

32 of 51

:collection => @post .comments %>

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Thiswillnowrenderthepartialinapp/views/comments/_comment.html.erbonceforeachcommentthatisinthe@post.comments collection.Astherendermethoditeratesoverthe@post.commentscollection,itassignseachcommenttoalocalvariablenamedthesameas thepartial,inthiscasecommentwhichisthenavailableinthepartialforustoshow.

8.2 Rendering a Partial Form


Letsalsomovethatnewcommentsectionouttoitsownpartial,again,youcreateafileapp/views/comments/_form.html.erbandinityou put:

33 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

<%= form_for([ @post , @post .comments.build]) do |f| %> < div class = "field" > <%= f.label :commenter %> < br /> <%= f.text_field :commenter %> </ div > < div class = "field" > <%= f.label :body %> < br /> <%= f.text_area :body %> </ div > < div class = "actions" > <%= f.submit %> </ div > <% end

34 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Thenyoumaketheapp/views/posts/show.html.erblooklikethefollowing:

35 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > < h2 >Comments</ h2 > <%= render :partial => "comments/comment" ,

36 of 51

:collection => @post .comments %>

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Thesecondrenderjustdefinesthepartialtemplatewewanttorender,comments/form,Railsissmartenoughtospottheforwardslashinthat stringandrealizethatyouwanttorenderthe_form.html.erbfileintheapp/views/commentsdirectory. The@postobjectisavailabletoanypartialsrenderedintheviewbecausewedefineditasaninstancevariable.

9 Deleting Comments
AnotherimportantfeatureonablogisbeingabletodeleteSPAMcomments.Todothis,weneedtoimplementalinkofsomesortintheview andaDELETEactionintheCommentsController. Sofirst,letsaddthedeletelinkintheapp/views/comments/_comment.html.erbpartial:

< p > < b >Commenter:</ b > <%= comment.commenter %> </ p > < p > < b >Comment:</ b > <%= comment.body %> </ p > < p > <%= link_to 'Destroy Comment' , [comment.post, comment], :confirm => 'Are you sure?' , :method => :delete %> </ p >

ClickingthisnewDestroyCommentlinkwillfireoffaDELETE /posts/:id/comments/:idtoourCommentsController,whichcanthenuse thistofindthecommentwewanttodelete,soletsaddadestroyactiontoourcontroller:

37 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

class CommentsController < ApplicationController def create @post = Post.find(params[ :post_id ]) @comment = @post .comments.create(params[ :comment ]) redirect_to post_path( @post ) end def destroy @post = Post.find(params[ :post_id ]) @comment = @post .comments.find(params[ :id ]) @comment .destroy redirect_to post_path( @post ) end end

Thedestroyactionwillfindthepostwearelookingat,locatethecommentwithinthe@post.commentscollection,andthenremoveitfromthe databaseandsendusbacktotheshowactionforthepost.

9.1 Deleting Associated Objects


Ifyoudeleteapostthenitsassociatedcommentswillalsoneedtobedeleted.Otherwisetheywouldsimplyoccupyspaceinthedatabase.Rails allowsyoutousethedependentoptionofanassociationtoachievethis.ModifythePostmodel,app/models/post.rb,asfollows:

38 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

class Post < ActiveRecord::Base validates :name , :presence => true validates :title , :presence => true , :length => { :minimum => 5 } has_many :comments , :dependent => :destroy end

10 Security
Ifyouweretopublishyourblogonline,anybodywouldbeabletoadd,editanddeletepostsordeletecomments. RailsprovidesaverysimpleHTTPauthenticationsystemthatwillworknicelyinthissituation.First,weenablesimpleHTTPbasedauthentication inourapp/controllers/application_controller.rb:

class ApplicationController < ActionController::Base protect_from_forgery private def authenticate authenticate_or_request_with_http_basic do |user_name, password| user_name == 'admin' && password == 'password' end end end

39 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Youcanobviouslychangetheusernameandpasswordtowhateveryouwant.WeputthismethodinsideofApplicationControllersothat itisavailabletoallofourcontrollers. TheninthePostsControllerweneedtohaveawaytoblockaccesstothevariousactionsifthepersonisnotauthenticated,herewecan usetheRailsbefore_filtermethod,whichallowsustospecifythatRailsmustrunamethodandonlythenallowaccesstotherequested actionifthatmethodallowsit. Tousethebeforefilter,wespecifyitatthetopofourPostsController,inthiscase,wewanttheusertobeauthenticatedoneveryaction, exceptforindexandshow,sowewritethat:

class PostsController < ApplicationController before_filter :authenticate , :except => [ :index , :show ] # GET /posts # GET /posts.xml def index @posts = Post.all respond_to do |format| # snipped for brevity

Wealsoonlywanttoallowauthenticateduserstodeletecomments,sointheCommentsControllerwewrite:

class CommentsController < ApplicationController before_filter :authenticate , :only => :destroy def create @post = Post.find(params[ :post_id ]) # snipped for brevity

Nowifyoutrytocreateanewpost,youwillbegreetedwithabasicHTTPAuthenticationchallenge

40 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

11 Building a Multi-Model Form


Anotherfeatureofyouraverageblogistheabilityto tagposts.Toimplementthisfeatureyourapplication needstointeractwithmorethanonemodelona singleform.Railsofferssupportfornestedforms. Todemonstratethis,wewilladdsupportforgiving eachpostmultipletags,rightintheformwhereyou createthepost.First,createanewmodeltoholdthe tags:

$ rails generate model tag name:string post:references

Again,runthemigrationtocreatethedatabase table:

$ rake db:migrate

Next,editthepost.rbfiletocreatetheotherside oftheassociation,andtotellRails(viatheaccepts_nested_attributes_formacro)thatyouintendtoedittagsviaposts:

41 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

class Post < ActiveRecord::Base validates :name , :presence => true validates :title , :presence => true , :length => { :minimum => 5 } has_many :comments , :dependent => :destroy has_many :tags accepts_nested_attributes_for :tags , :allow_destroy => :true , :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } end

The:allow_destroyoptiononthenestedattributedeclarationtellsRailstodisplayaremovecheckboxontheviewthatyoullbuildshortly. The:reject_ifoptionpreventssavingnewtagsthatdonothaveanyattributesfilledin. Wewillmodifyviews/posts/_form.html.erbtorenderapartialtomakeatag:

42 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

<% @post .tags.build %> <%= form_for( @post ) do |post_form| %> <% if @post .errors.any? %> < div id = "errorExplanation" > < h2 > <%= pluralize( @post .errors.count, "error" ) %> prohibited this post from being saved:</ h2 > < ul > <% @post .errors.full_messages. each do |msg| %> < li > <%= msg %> </ li > <% end %> </ ul > </ div >

43 of 51

<% end %>

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Notethatwehavechangedthefinform_for(@post) do |f|topost_formtomakeiteasiertounderstandwhatisgoingon. Thisexampleshowsanotheroptionoftherenderhelper,beingabletopassinlocalvariables,inthiscase,wewantthelocalvariableformin thepartialtorefertothepost_formobject. Wealsoadda@post.tags.buildatthetopofthisform,thisistomakesurethereisanewtagreadytohaveitsnamefilledinbytheuser.If youdonotbuildthenewtag,thentheformwillnotappearasthereisnonewTagobjectreadytocreate. Nowcreatethefolderapp/views/tagsandmakeafileintherecalled_form.html.erbwhichcontainstheformforthetag:

44 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

<%= form.fields_for :tags do |tag_form| %> < div class = "field" > <%= tag_form.label :name , 'Tag:' %> <%= tag_form.text_field :name %> </ div > <% unless tag_form.object. nil ? || tag_form.object.new_record? %> < div class = "field" > <%= tag_form.label :_destroy, 'Remove:' %> <%= tag_form.check_box :_destroy %> </ div > <% end %> <% end %>

45 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Finally,wewilledittheapp/views/posts/show.html.erbtemplatetoshowourtags.

46 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > < p > < b >Tags:</ b > <%= @post .tags.map { |t| t.name }.join( ", " ) %> </ p >

47 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Withthesechangesinplace,youllfindthatyoucaneditapostanditstagsdirectlyonthesameview. However,thatmethodcall@post.tags.map { |t| t.name }.join(", ")isawkward,wecouldhandlethisbymakingahelpermethod.

12 View Helpers
ViewHelpersliveinapp/helpersandprovidesmallsnippetsofreusablecodeforviews.Inourcase,wewantamethodthatstringsabunchof objectstogetherusingtheirnameattributeandjoiningthemwithacomma.AsthisisforthePostshowtemplate,weputitinthePostsHelper. Openupapp/helpers/posts_helper.rbandaddthefollowing:

module PostsHelper def join_tags(post) post.tags.map { |t| t.name }.join(", ") end end

Nowyoucanedittheviewinapp/views/posts/show.html.erbtolooklikethis:

48 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

< p class = "notice" > <%= notice %> </ p > < p > < b >Name:</ b > <%= @post .name %> </ p > < p > < b >Title:</ b > <%= @post .title %> </ p > < p > < b >Content:</ b > <%= @post .content %> </ p > < p > < b >Tags:</ b > <%= join_tags( @post ) %> </ p >

49 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

13 Whats Next?
NowthatyouveseenyourfirstRailsapplication,youshouldfeelfreetoupdateitandexperimentonyourown.Butyoudonthavetodo everythingwithouthelp.AsyouneedassistancegettingupandrunningwithRails,feelfreetoconsultthesesupportresources: TheRubyonRailsguides TheRubyonRailsTutorial TheRubyonRailsmailinglist The#rubyonrailschannelonirc.freenode.net TheRailsWiki Railsalsocomeswithbuilt-inhelpthatyoucangenerateusingtherakecommand-lineutility: Runningrake doc:guideswillputafullcopyoftheRailsGuidesinthedoc/guidesfolderofyourapplication.Opendoc/guides /index.htmlinyourwebbrowsertoexploretheGuides. Runningrake doc:railswillputafullcopyoftheAPIdocumentationforRailsinthedoc/apifolderofyourapplication.Open doc/api/index.htmlinyourwebbrowsertoexploretheAPIdocumentation.

14 Configuration Gotchas
TheeasiestwaytoworkwithRailsistostoreallexternaldataasUTF-8.Ifyoudont,RubylibrariesandRailswilloftenbeabletoconvertyour nativedataintoUTF-8,butthisdoesntalwaysworkreliably,soyourebetteroffensuringthatallexternaldataisUTF-8. Ifyouhavemadeamistakeinthisarea,themostcommonsymptomisablackdiamondwithaquestionmarkinsideappearinginthebrowser. Anothercommonsymptomischaracterslikeappearinginsteadof.Railstakesanumberofinternalstepstomitigatecommoncausesof theseproblemsthatcanbeautomaticallydetectedandcorrected.However,ifyouhaveexternaldatathatisnotstoredasUTF-8,itcan occasionallyresultinthesekindsofissuesthatcannotbeautomaticallydetectedbyRailsandcorrected. TwoverycommonsourcesofdatathatarenotUTF-8: Yourtexteditor:Mosttexteditors(suchasTextmate),defaulttosavingfilesasUTF-8.Ifyourtexteditordoesnot,thiscanresultin specialcharactersthatyouenterinyourtemplates(suchas)toappearasadiamondwithaquestionmarkinsideinthebrowser.This alsoappliestoyourI18Ntranslationfiles.MosteditorsthatdonotalreadydefaulttoUTF-8(suchassomeversionsofDreamweaver) offerawaytochangethedefaulttoUTF-8.Doso. Yourdatabase.RailsdefaultstoconvertingdatafromyourdatabaseintoUTF-8attheboundary.However,ifyourdatabaseisnot usingUTF-8internally,itmaynotbeabletostoreallcharactersthatyourusersenter.Forinstance,ifyourdatabaseisusingLatin-1 internally,andyouruserentersaRussian,Hebrew,orJapanesecharacter,thedatawillbelostforeveronceitentersthedatabase.If possible,useUTF-8astheinternalstorageofyourdatabase.

15 Changelog
August30,2010:MinoreditingafterRails3releasebyJoostBaaij July12,2010:Fixes,editingandupdatingofcodesamplesbyJaimeIniesta May16,2010:AddedasectiononconfigurationgotchastoaddresscommonencodingproblemsthatpeoplemighthavebyYehuda Katz April30,2010:Fixes,editingandupdatingofcodesamplesbyRohitArondekar April25,2010:CoupleofmoreminorfixupsMikelLindsaar April1,2010:FixeddocumenttovalidateXHTML1.0Strict.JaimeIniesta February8,2010:Fullre-writeforRails3.0-beta,addedhelpersandbefore_filters,refactoredcodebyMikelLindsaar January24,2010:Re-writeforRails3.0byMikelLindsaar July18,2009:MinorcleanupinanticipationofRails2.3.3byMikeGunderloy February1,2009:UpdatedforRails2.3byMikeGunderloy November3,2008:FormattingpatchfromDaveRothlisberger November1,2008:FirstapprovedversionbyMikeGunderloy October16,2008:RevisedbasedonfeedbackfromPratikNaikbyMikeGunderloy(notyetapprovedforpublication) October13,2008:FirstcompletedraftbyMikeGunderloy(notyetapprovedforpublication) October12,2008:Moredetail,rearrangement,editingbyMikeGunderloy(notyetapprovedforpublication) September8,2008:initialversionbyJamesMiller(notyetapprovedforpublication)

Feedback
You'reencouragedtohelpinkeepingthequalityofthisguide.

50 of 51

02/11/2011 11:39 AM

Ruby on Rails Guides: Getting Started with Rails

http://guides.rubyonrails.org/getting_started.html#...

Ifyouseeanytyposorfactualerrorsyouareconfidenttopatchpleaseclonedocrailsandpushthechangeyourself.ThatbranchofRailshas publicwriteaccess.Commitsarestillreviewed,butthathappensafteryou'vesubmittedyourcontribution.docrailsiscross-mergedwithmaster periodically. Youmayalsofindincompletecontent,orstuffthatisnotuptodate.Pleasedoaddanymissingdocumentationformaster.ChecktheRubyon RailsGuidesGuidelinesguideforstyleandconventions. IssuesmayalsobereportedinGithub. Andlastbutnotleast,anykindofdiscussionregardingRubyonRailsdocumentationisverywelcomeintherubyonrails-docsmailinglist. ThisworkislicensedunderaCreativeCommonsAttribution-ShareAlike3.0License "Rails","RubyonRails",andtheRailslogoaretrademarksofDavidHeinemeierHansson.Allrightsreserved.

51 of 51

02/11/2011 11:39 AM

Das könnte Ihnen auch gefallen