Вы находитесь на странице: 1из 19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

RailsTutorialforDevisewithCanCanandTwitterBootstrap
byDanielKehoe

Lastupdated19April2012 RubyonRailstutorialshowinghowtocreateaRails3.2applicationusingDevisewithCanCanandTwitterBootstrap.
Devisegivesyoureadymadeauthenticationandusermanagement. CanCanprovidesauthorizationwhichrestrictswhatresourcesagivenuserisallowedtoaccess. TwitterBootstrapisafrontendframeworkforCSSstyling.

RailsAppsProject

Blog

Twitter

Google+

GitHubRepository

Youcancreatetheexampleappfromthistutorialorclonetherails3bootstrapdevisecancanrepositoryforthecompleteapplication.Ifyouwant tousetheprojectasastarterappforyourowncustomizedapplication,seetherails3bootstrapdevisecancanREADMEtouseanapplication templatetogenerateayourownversionoftheexampleapp.Generatingtheapplicationgivesyoumanyoptions,suchasusingHamlforviews, additionalDevisemodules,andotherpopulargemssuchaswillpaginate.

RailsAppsExamplesandTutorials
ThisisoneinaseriesofRailsexampleappsandtutorialsfromtheRailsAppsProject.SeealistofsimilarRailsexamples,tutorials,andstarter apps. Thisexampleapplicationisbasedontherails3deviserspeccucumberexampleandtutorialandaddsCanCanandTwitterBootstrap.Viewthe rails3deviserspeccucumberexampleandtutorialforthebasicsofsettingupanapplicationwithRSpecandCucumber. ThisexampleapplicationusesActiveRecordandaSQLitedatabase.YoucanusetheMongoidORMwiththeMongoDBdatastoreinstead,for fasterdevelopmentwithoutschemasormigrations.Therails3mongoiddeviseexampleappandtutorialshowshowtosetupDeviseand MongoidwithRSpecandCucumber. ToseeamorecomplexapplicationthatusesDevise,CanCan,andTwitterBootstrap,seetherailsprelaunchsignupexampleandtutorialfrom theRailsAppsproject.

FollowonTwitter
FollowtheprojectonTwitter:rails_apps.Tweetsomepraiseifyoulikewhatyouvefound.

Tutorial
Thistutorialdocumentseachstepthatyoumustfollowtocreatethisapplication.Everystepisdocumentedconcisely,soacompletebeginner cancreatethisapplicationwithoutanyadditionalknowledge.However,noexplanationisofferedforanyofthesteps,soifyouareabeginner, youreadvisedtolookforanintroductiontoRailselsewhere.SeeresourcesforgettingstartedwithRails.

BeforeYouStart
Ifyoufollowthistutorialclosely,youllhaveaworkingapplicationthatcloselymatchestheexampleappinthisGitHubrepository.Theexample appintherails3bootstrapdevisecancanrepositoryisyourreferenceimplementation.Ifyoufindproblemswiththeappyoubuildfromthis tutorial,downloadtheexampleapp(inGitspeak,cloneit)anduseafilecomparetooltoidentifydifferencesthatmaybecausingerrors.Ona Mac,goodfilecomparetoolsareFileMerge,DiffMerge,Kaleidoscope,orIanBairdsChanges. Ifyoucloneandinstalltheexampleappandfindproblemsorwishtosuggestimprovements,pleasecreateaGitHubissue.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

1/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

Toimprovethistutorial,pleaseeditthiswikipageorleavecommentsbelow.

CreatingtheApplication
OptionOne
Followthistutorial. Tocreatetheapplication,youcancutandpastethecodefromthetutorialintoyourownfiles.Itsabittediousanderrorpronebutyoullhavea goodopportunitytoexaminethecodeclosely.

OptionTwo
Usethereadymadeapplicationtemplatetogeneratethecode. YoucanuseanapplicationtemplatetogenerateanewRailsappwithcodethatcloselymatchesthetutorial.Youllfindanapplicationtemplatefor thistutorialintheRailsApplicationTemplatesrepository. Youllbeabletogiveityourownprojectnamewhenyougeneratetheapp.Generatingtheapplication(describedbelow)givesyoumanyoptions, suchasusingHamlforviews,additionalDevisemodules,andotherpopulargemssuchaswillpaginate. Usethecommand:
$ r a i l s n e w r a i l s 3 b o o t s t r a p d e v i s e c a n c a n m h t t p s : / / r a w . g i t h u b . c o m / R a i l s A p p s / r a i l s 3 a p p l i c a t i o n t e m p l a t e s / m a s t e r / r a i l s 3 b o o t s t r a p d e v i s e c a n c a n t e m p l a t e . r b T

Usethe The

T flagtoskipTest::Unitfiles.

$ characterindicatesashellpromptdontincludeitwhenyourunthecommand. r a i l s 3 b o o t s t r a p d e v i s e c a n c a n onyourcomputer.Youcanuseadifferentnameifyouwish.

ThiscreatesanewRailsappnamed

Theapplicationgeneratortemplatewillaskyouforyourpreferences. Toproduceanapplicationexactlylikethetutorial,makethefollowingselections:
WouldyouliketouseHamlinsteadofERB?no WouldyouliketouseRSpecinsteadofTestUnit?yes Wouldyouliketousefactory_girlfortestfixtureswithRSpec?yes WouldyouliketousemachinistfortestfixtureswithRSpec?no WouldyouliketouseCucumberforyourBDD?yes WouldyouliketouseGuardtoautomateyourworkflow?no Howwillyousendemail?#2 1. SMTPaccount 2. Gmailaccount 3. SendGridaccount WouldyouliketouseDeviseforauthentication?#2 1. No 2. Devisewithdefaultmodules 3. DevisewithConfirmablemodule 4. DevisewithConfirmableandInvitablemodules WouldyouliketomanageauthorizationwithCanCan&Rolify?yes WhichfrontendframeworkwouldyoulikeforHTML5andCSS3?#4 1. None 2. ZurbFoundation 3. TwitterBootstrap(less) 4. TwitterBootstrap(sass) 5. Skeleton 6. NormalizeCSSforconsistentstyling Whichformgemwouldyoulike?#1 1. None 2. simpleform 3. simpleform(bootstrap) Wouldyouliketouserailsfootnotesduringdevelopment?no Wouldyouliketosetarobots.txtfiletobanspiders?yes Wouldyouliketoaddwill_paginateforpagination?no

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

2/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

BesuretochoosetheCanCan&Rolify optionaswellastheTwitterBootstrap(sass)optiontocreatetheexampleapplication. Youcanchooseotherselectionsifyoudontcareaboutmatchingtheexampleapplicationexactly. YoucanchoosetheDevisewithConfirmablemoduleoptionifyouwantnewuserstoconfirmtheiremailaddressbeforegainingaccessto yoursite.Ifyoudontwishtorequireemailconfirmation,choosetheoptionDevisewithdefaultmodules.

OptionThree
Usetherails_apps_composergemtocreateareusuableapplicationtemplate. Thisisoptimalifyouarecreatingastarterappbasedonthisexampleappbutwishtocustomizethecodeforyourownpreferences. EachstepinthistutorialhasacorrespondingapplicationtemplaterecipefromtheRailsAppsComposerrecipesrepository.Youcancreateyour ownapplicationtemplateusingthetemplaterecipes.Todoso,clonetheRailsAppsComposerproject,customizerecipesasneeded,andfollow theinstructionstocreateareusableapplicationtemplatefile.

Assumptions
Beforebeginningthistutorial,youneedtoinstall
TheRubylanguage(version1.9.3ornewer) Rails3.2

CheckthatappropriateversionsofRubyandRailsareinstalledinyourdevelopmentenvironment:
$r u b yv $r a i l sv

BesuretoreadInstallingRailsfordetailedinstructionsandadvice.

CreatetheRailsApplication
Beginninghere,weshowhowtocreatetheapplicationfromscratch. Openaterminal,navigatetoafolderwhereyouhaverightstocreatefiles,andtype:
$r a i l sn e wr a i l s 3 b o o t s t r a p d e v i s e c a n c a nT

Usethe

T flagtoskipTest::Unitfiles(sinceyouareusingRSpec).

Youmaygivetheappadifferentnameifyouarebuildingitforyourownuse.Forthistutorial,wellassumethenameisrails3bootstrapdevise cancan. ThiswillcreateaRailsapplicationthatusesaSQLitedatabasefordatastorage. Afteryoucreatetheapplication,switchtoitsfoldertocontinueworkdirectlyinthatapplication:


$c dr a i l s 3 b o o t s t r a p d e v i s e c a n c a n

EdittheREADME
IfyoureopensourcingtheapponGitHub,pleaseedittheREADMEfiletoaddadescriptionoftheappandyourcontactinfo.Changingthe READMEisimportantifyoureusingacloneoftheexampleapp.Ivebeenmistaken(andcontacted)astheauthorofappsthatarecopiedfrom myexample.

SetUpSourceControl(Git)
Ifyourecreatinganappfordeploymentintoproduction,youllwanttosetupasourcecontrolrepositoryatthispoint.Ifyouarebuildingathrow awayappforyourowneducation,youmayskipthisstep.
$g i ti n i t. $g i ta d d. $g i tc o m m i tm' I n i t i a lc o m m i t '

SeedetailedinstructionsforUsingGitwithRails.

SetUpGems
AboutRequiredGems
Theapplicationusesthefollowinggems:

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

3/19

19/06/2013
rails rspecrails database_cleaner factory_girl_rails email_spec cucumberrails capybara devise cancan rolify bootstrapsass

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

SetupYourGemfile
Itsagoodideatocreateanewgemsetusingrvm,theRubyVersionManager,asdescribedinthearticleInstallingRails. SeeExampleGemfilesforRails3.2. OpenyourGemfileandreplacethecontentswiththefollowing: Gemfile
s o u r c e ' h t t p s : / / r u b y g e m s . o r g ' g e m ' r a i l s ' , ' 3 . 2 . 6 ' g e m ' s q l i t e 3 ' g r o u p : a s s e t s d o g e m ' s a s s r a i l s ' , ' ~ > 3 . 2 . 3 ' g e m ' c o f f e e r a i l s ' , ' ~ > 3 . 2 . 1 ' g e m ' u g l i f i e r ' , ' > = 1 . 0 . 3 ' e n d g e m ' j q u e r y r a i l s ' g e m " r s p e c r a i l s " , " > = 2 . 9 . 0 . r c 2 " , : g r o u p = > [ : d e v e l o p m e n t , : t e s t ] g e m " f a c t o r y _ g i r l _ r a i l s " , " > = 3 . 1 . 0 " , : g r o u p = > [ : d e v e l o p m e n t , : t e s t ] g e m " e m a i l _ s p e c " , " > = 1 . 2 . 1 " , : g r o u p = > : t e s t g e m " c u c u m b e r r a i l s " , " > = 1 . 3 . 0 " , : g r o u p = > : t e s t g e m " c a p y b a r a " , " > = 1 . 1 . 2 " , : g r o u p = > : t e s t g e m " d a t a b a s e _ c l e a n e r " , " > = 0 . 7 . 2 " , : g r o u p = > : t e s t g e m " l a u n c h y " , " > = 2 . 1 . 0 " , : g r o u p = > : t e s t g e m " d e v i s e " , " > = 2 . 1 . 0 . r c " g e m " c a n c a n " , " > = 1 . 6 . 7 " g e m " r o l i f y " , " > = 3 . 1 . 0 " g e m " b o o t s t r a p s a s s " , " > = 2 . 0 . 1 "

CheckforthecurrentversionofRailsandreplace

g e m' r a i l s ' ,' 3 . 2 . 6 ' accordingly.

Note:TheRailsAppsexamplesaregeneratedwithapplicationtemplatescreatedbytheRailsAppsComposerGem.Forthatreason,groups suchas : d e v e l o p m e n t or : t e s t arespecifiedinline.YoucanreformattheGemfilestoorganizegroupsinaneyepleasingblockstyle.The functionalityisthesame.

InstalltheRequiredGems
Installtherequiredgemsonyourcomputer:
$b u n d l ei n s t a l l

Youcancheckwhichgemsareinstalledonyourcomputerwith:
$g e ml i s tl o c a l

Keepinmindthatyouhaveinstalledthesegemslocally.Whenyoudeploytheapptoanotherserver,thesamegems(andversions)mustbe available.

ConfigurationforHaml
Inthistutorial,wellusethedefaultERBRailstemplateengine.Optionally,youcanuseanothertemplateengine,suchasHaml.See instructionsforaddingHamltoRails.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

4/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

AddRSpecforUnitTesting
Therails3deviserspeccucumbertutorialshowshowtosetupRSpecandprovidesexamplespecsforusewithDevise.

AddCucumberforBehaviorDrivenDevelopment
Therails3deviserspeccucumbertutorialshowshowtosetupCucumberandprovidesexamplescenariosforusewithDevise.

TesttheApp
Youcancheckthatyourapprunsproperlybyenteringthecommand
$r a i l ss e r v e r

Toseeyourapplicationinaction,openabrowserwindowandnavigatetohttp://localhost:3000/.YoushouldseetheRailsdefaultinformation page. StoptheserverwithControlC.

ConfigureEmail
TheConfigureEmailstepintherails3deviserspeccucumbertutorialisidentical. Youmustconfiguretheappforyouremailaccountifyouwantyourapplicationtosendemailmessages,forexample,ifyouvegeneratedthe applicationwiththeoptiontoinstalltheDevise : c o n f i r m a b l e module.

ConfigureActionMailer
Removethefollowingfromtheconfig/environments/development.rbfile:
# D o n ' t c a r e i f t h e m a i l e r c a n ' t s e n d c o n f i g . a c t i o n _ m a i l e r . r a i s e _ d e l i v e r y _ e r r o r s = f a l s e

Addthefollowingtotheconfig/environments/development.rbfile:
# A c t i o n M a i l e r C o n f i g c o n f i g . a c t i o n _ m a i l e r . d e f a u l t _ u r l _ o p t i o n s = { : h o s t = > ' l o c a l h o s t : 3 0 0 0 ' } c o n f i g . a c t i o n _ m a i l e r . d e l i v e r y _ m e t h o d = : s m t p # c h a n g e t o f a l s e t o p r e v e n t e m a i l f r o m b e i n g s e n t d u r i n g d e v e l o p m e n t c o n f i g . a c t i o n _ m a i l e r . p e r f o r m _ d e l i v e r i e s = t r u e c o n f i g . a c t i o n _ m a i l e r . r a i s e _ d e l i v e r y _ e r r o r s = t r u e c o n f i g . a c t i o n _ m a i l e r . d e f a u l t : c h a r s e t = > " u t f 8 "

Addthefollowingtotheconfig/environments/production.rbfile:
c o n f i g . a c t i o n _ m a i l e r . d e f a u l t _ u r l _ o p t i o n s = { : h o s t = > ' e x a m p l e . c o m ' } # A c t i o n M a i l e r C o n f i g # S e t u p f o r p r o d u c t i o n d e l i v e r i e s , n o e r r o r s r a i s e d c o n f i g . a c t i o n _ m a i l e r . d e l i v e r y _ m e t h o d = : s m t p c o n f i g . a c t i o n _ m a i l e r . p e r f o r m _ d e l i v e r i e s = t r u e c o n f i g . a c t i o n _ m a i l e r . r a i s e _ d e l i v e r y _ e r r o r s = f a l s e c o n f i g . a c t i o n _ m a i l e r . d e f a u l t : c h a r s e t = > " u t f 8 "

Addthefollowingtotheconfig/environments/test.rbfile:
# A c t i o n M a i l e r C o n f i g c o n f i g . a c t i o n _ m a i l e r . d e f a u l t _ u r l _ o p t i o n s = { : h o s t = > ' e x a m p l e . c o m ' }

Thiswillsettheexampleapplicationtodeliveremailinbothdevelopmentandproduction.Itwillraisedeliveryerrorsindevelopmentbutnot production. Indevelopment, c o n f i g . a c t i o n _ m a i l e r . d e f a u l t _ u r l _ o p t i o n s issetforahostat emailmessagestoworkproperlyduringdevelopment. Fortesting,


l o c a l h o s t : 3 0 0 0 whichwillenablelinksinDeviseconfirmation

c o n f i g . a c t i o n _ m a i l e r . d e f a u l t _ u r l _ o p t i o n s issetforahostat e x a m p l e . c o m .Anyvalueallowsteststorun.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

5/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps
c o n f i g . a c t i o n _ m a i l e r . d e f a u l t _ u r l _ o p t i o n s hostoptionfrom e x a m p l e . c o m toyourowndomain.

Forproduction,youllneedtochangethe

UseaGmailaccount
IfyouwanttouseaGmailaccounttosendemail,youllneedtomodifythefilesconfig/environments/development.rband config/environments/production.rb:
c o n f i g . a c t i o n _ m a i l e r . s m t p _ s e t t i n g s = { a d d r e s s : " s m t p . g m a i l . c o m " , p o r t : 5 8 7 , d o m a i n : " e x a m p l e . c o m " , a u t h e n t i c a t i o n : " p l a i n " , e n a b l e _ s t a r t t l s _ a u t o : t r u e , u s e r _ n a m e : E N V [ " G M A I L _ U S E R N A M E " ] , p a s s w o r d : E N V [ " G M A I L _ P A S S W O R D " ] }

Youcanreplace E N V [ " G M A I L _ U S E R N A M E " ] and E N V [ " G M A I L _ P A S S W O R D " ] withyourGmailusernameandpassword.However,committingthefile toapublicGitHubrepositorywillexposeyoursecretpassword. IfyourefamiliarwithsettingUnixenvironmentvariables,itsadvisabletoleave c o n f i g . a c t i o n _ m a i l e r . s m t p _ s e t t i n g s unchangedandsetyour environmentvariablesinthefilethatisreadwhenstartinganinteractiveshell(the~/.bashrcfileforthebashshell).Thiswillkeepthepassword outofyourrepository. Areyouusingabashshell?Use
e c h o$ S H E L L tofindout.Forabashshell,editthe~/.bashrcfileandadd:

e x p o r t G M A I L _ U S E R N A M E = " m y n a m e @ g m a i l . c o m " e x p o r t G M A I L _ P A S S W O R D = " s e c r e t * "

Openanewshellorrestartyourterminalapplicationtocontinue.

SetUpAuthentication
TheSetUpAuthenticationstepintherails3deviserspeccucumbertutorialisidentical. ThisappusesDeviseforusermanagementandauthentication.

SetUpConfigurationforDevise
YoushouldhavethefollowinggeminyourGemfilefile:
g e m ' d e v i s e '

Ifyouhaventalready,run:
$b u n d l ei n s t a l l

RunthegeneratortoinstallDevise:
$r a i l sg e n e r a t ed e v i s e : i n s t a l l

whichinstallsaconfigurationfile: config/initializers/devise.rb andalocalizationfile.

ConfigureDeviseforEmail
Completeyouremailconfigurationbymodifying config/initializers/devise.rb andsettingthe
c o n f i g . m a i l e r _ s e n d e r optionforthereturnemailaddressformessagesthatDevisesendsfromtheapplication.

GenerateaModelandRoutesforUsers
UseDevisetogeneratemodelsandroutesforaUser.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

6/19

19/06/2013
$ r a i l s g e n e r a t e d e v i s e U s e r

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

DevisewillcreateadatabasemigrationandaUsermodel. DevisewilltrytocreateaspecfilefortheUsermodel.Ifyouvealreadydownloadedtheexampleappspecfiles,dontlettheDevisegenerator overwritethespec/models/user_spec.rbfile. Devisewillmodifytheconfig/routes.rbfiletoadd:


d e v i s e _ f o r : u s e r s

whichprovidesacompletesetofroutesforusersignupandlogin.Ifyourun

r a k er o u t e s youcanseetheroutesthatthislineofcodecreates.

AccommodateCucumberTestingforSignOut
Bydefault,DeviseusesanhttpDELETErequestforsignoutrequests( d e s t r o y _ u s e r _ s e s s i o n _ p a t h ).RailsusesJavascripttoimplementhttp DELETErequests.PriortoDevise1.4.1(27June2011),DeviseusedanhttpGETrequestforsignoutrequests.JoseValimexplainedthe change:GETrequestsshouldnotchangethestateoftheserver.WhensignoutisaGETrequest,CSRFcanbeusedtosignyouout automaticallyandthingsthatpreloadlinkscaneventuallysignyououtbymistakeaswell. However,CucumberwantstotestGETrequestsnotDELETErequests.IfyouintendtouseCucumberwithDevise,youmustchangethe DevisedefaultfromDELETEtoGETin/config/initializers/devise.rbfortheRailstestenvironment.Youmayseeasuggestionelsewhereto tweaktheroutes.rbfileorchangethelog_outlinktomakethefix.Itisntnecessaryifyouchangethe/config/initializers/devise.rbfile.
# T h e d e f a u l t H T T P m e t h o d u s e d t o s i g n o u t a r e s o u r c e . D e f a u l t i s : d e l e t e . c o n f i g . s i g n _ o u t _ v i a = R a i l s . e n v . t e s t ? ? : g e t : : d e l e t e

SinceyouonlyuseCucumberduringtesting,switchingthedefaultisonlyneededfortesting. IfyourenotgoingtouseCucumber,leaveDevisesdefault(DELETE)inplace.

PreventLoggingofPasswords
Wedontwantpasswordswrittentoourlogfile. Modifythefileconfig/application.rbtoinclude:
c o n f i g . f i l t e r _ p a r a m e t e r s + = [ : p a s s w o r d , : p a s s w o r d _ c o n f i r m a t i o n ]

Notethatfilter_parametersisanarray.

SetUpAuthorization
Therails3deviserspeccucumbertutorialdoesnotincludeaSetUpAuthorizationstep. Deviseprovidesauthentication,asystemtosecurelyidentifyusers,makingsuretheuserisreallywhoherepresentshimselftobe.Weneedto addasystemforauthorizationtodetermineifanauthenticatedusershouldhaveaccesstosecuredresources.ThisappusesCanCanfor authorization,torestrictaccesstopagesthatshouldonlybeviewedbyanadministrator.Cancanisbyfarthemostpopulargemusedto implementauthorization(seetheRailsAuthorizationcategoryonTheRubyToolboxsite).TheauthorofCanCan,RyanBates,offersa RailsCastonAuthorizationwithCanCantoshowhowtouseit. Therearemanywaystoimplementauthorizationinawebapplication.CanCanoffersanarchitecturethatcentralizesallauthorizationrules (permissionsorabilities)inasinglelocation,theCanCan A b i l i t y class.Foradiscussionofthebenefitsofusingasingle,consolidated locationforthepermissions,seethearticleDontDoRoleBasedAuthorizationChecksDoActivityBasedChecks. CanCanprovidesamechanismforlimitingaccessatthelevelofcontrollerandcontrollermethodandexpectsyoutosetpermissionsbasedon userattributesyoudefine.CanCandoesntprovidedefaultuserattributessuchasuserrolesyoumustimplementthisoutsideofCanCan.There aremanywaystoimplementrolebasedauthorizationforusewithCanCan.Forthisexample,weuseFlorentMonbillardsRolifygemtocreatea Rolemodel,addmethodstoaUsermodel,andgenerateamigrationforarolestable.

SetUpCanCan
CanCanprovidesaRailsgeneratortocreatetheCanCan
$ r a i l s g e n e r a t e c a n c a n : a b i l i t y A b i l i t y class.Runthegeneratortocreatethefileapp/models/ability.rb:

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

7/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

Editthefileapp/models/ability.rbtodefineasimpleruleforgrantingpermissiontoanadministratortoaccessanypage:
c l a s s A b i l i t y i n c l u d e C a n C a n : : A b i l i t y

d e f i n i t i a l i z e ( u s e r ) u s e r | | = U s e r . n e w # g u e s t u s e r ( n o t l o g g e d i n ) i f u s e r . h a s _ r o l e ? : a d m i n c a n : m a n a g e , : a l l e n d e n d e n d

Rulesdefinedinthe Notethatthe

A b i l i t y classcanbecomequitecomplex.SeetheCanCanwikiDefiningAbilitiesfordetails.

u s e r . h a s _ r o l e ? methoddoesntyetexist.WelladdthemethodwhenwesetupRolify.

ConfigureCanCanExceptionHandling
Ifuserauthorizationfails,a authorizationexceptions.
C a n C a n : : A c c e s s D e n i e d exceptionwillberaised.SeetheCanCanwikiExceptionHandlingforwaystohandle

Forthisexample,wellhandlethe C a n C a n : : A c c e s s D e n i e d exceptionintheApplicationController.Wellsetanerrormessageandredirecttothe homepage.Modifythefileapp/controllers/application_controller.rblikethis:


c l a s s A p p l i c a t i o n C o n t r o l l e r < A c t i o n C o n t r o l l e r : : B a s e p r o t e c t _ f r o m _ f o r g e r y r e s c u e _ f r o m C a n C a n : : A c c e s s D e n i e d d o | e x c e p t i o n | r e d i r e c t _ t o r o o t _ p a t h , : a l e r t = > e x c e p t i o n . m e s s a g e e n d e n d

SetUpUserRoles
WellusetheRolifygemtoimplementuserroles.RolifyprovidesaRailsgeneratortocreateaRolemodel,addmethodstoaUsermodel,and generateamigrationforarolestable.Runthecommand:
$ r a i l s g e n e r a t e r o l i f y : r o l e

IfyoureusingMongoidwiththeMongoDBdatastore,addparameterstothecommand:
$ r a i l s g e n e r a t e r o l i f y : r o l e R o l e U s e r m o n g o i d

Thegeneratorwillinserta
app/models/role.rb config/initializers/rolify.rb

r o l i f y methodinapp/models/users.rbanditwillcreateseveralfiles:

db/migrate/rolify_create_roles.rb

Theapp/models/role.rblookslikethis:
c l a s s R o l e < A c t i v e R e c o r d : : B a s e h a s _ a n d _ b e l o n g s _ t o _ m a n y : u s e r s , : j o i n _ t a b l e = > : u s e r s _ r o l e s b e l o n g s _ t o : r e s o u r c e , : p o l y m o r p h i c = > t r u e e n d

ThesefewstepswithCanCanandRolifyimplementrolebasedauthorizationinourapplication.Wellusetheauthorizationoptionsprovidedby CanCanandRolifywhenweaddanadministrativepagewithcorrespondinglinks.

CustomizetheApplication
TheCustomizetheApplicationstepintherails3deviserspeccucumbertutorialisidentical.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

8/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

EnableUserstoHaveNames
Bydefault,Deviseusesanemailaddresstoidentifyusers.Welladdanameattributeaswell.Yourapplicationmaynotrequireauserto provideaname.ButshowingyouhowtoaddanamewillhelpyouseewhatyouneedtodoifyoudecidetomakechangestothedefaultDevise usermodel. DevisecreatedamigrationfiletoestablishtheschemafortheSQLitedatabasewithamigrationfilenamedsomethinglike db/migrate/xxxxxxx_devise_create_users.rb.Wewontmodifythemigrationfile.Insteadwelladdanadditionalmigrationthataddsthename fieldtotheUserrecord.
r a i l s g e n e r a t e m i g r a t i o n A d d N a m e T o U s e r s n a m e : s t r i n g

Runthemigrationandpreparethetestdatabasetopickupthenamefield:
$ b u n d l e e x e c r a k e d b : m i g r a t e $ b u n d l e e x e c r a k e d b : t e s t : p r e p a r e

Ifyouwish,youcanmodifytheusermodeltovalidatethepresenceanduniquenessofthenameattribute.Modifythefileapp/models/user.rb andadd:
v a l i d a t e s _ p r e s e n c e _ o f : n a m e v a l i d a t e s _ u n i q u e n e s s _ o f : n a m e , : e m a i l , : c a s e _ s e n s i t i v e = > f a l s e

Thiswillallowuserstobecreated(oredited)withanameattribute.Whenauseriscreated,anameandemailaddressmustbepresentand mustbeunique(notusedbefore).NotethatDevise(bydefault)willcheckthattheemailaddressandpasswordarenotblankandthattheemail addressisunique. Youllalsowanttopreventmalicioushackersfromcreatingfakewebformsthatwouldallowchangingofpasswordsthroughthemass assignmentoperationsofupdate_attributes(attrs)andnew(attrs).Devisealreadyaddedthistothemodels/user.rbfile:


a t t r _ a c c e s s i b l e : e m a i l , : p a s s w o r d , : p a s s w o r d _ c o n f i r m a t i o n , : r e m e m b e r _ m e

butyoullneedtoaddthenameattribute:
a t t r _ a c c e s s i b l e : n a m e , : e m a i l , : p a s s w o r d , : p a s s w o r d _ c o n f i r m a t i o n , : r e m e m b e r _ m e

IfyouvechosentocreatetheapplicationwiththeDeviseConfirmablemodule,alsoadd

: c o n f i r m e d _ a t:

a t t r _ a c c e s s i b l e : n a m e , : e m a i l , : p a s s w o r d , : p a s s w o r d _ c o n f i r m a t i o n , : r e m e m b e r _ m e , : c o n f i r m e d _ a t

CreateCustomizedViewsforUserRegistration(ERB)

Deviseprovidesacontrollerandviewsforregisteringusers.Itiscalledtheregisterablemodule.Thecontrollerandviewsarehiddeninthe Devisegemsowedontneedtocreateanything.However,becausewewantouruserstoprovideanamewhenregistering,wewillcreate customviewsforcreatingandeditingauser.OurcustomviewswilloverridetheDevisegemdefaults. First,tocopyallthedefaultDeviseviewstoyourapplication,run


r a i l sg e n e r a t ed e v i s e : v i e w s

Thiswillgenerateasetofviewsinthedirectoryapp/views/devise/. Next,modifytheviewstocreateandeditusers. Addthefollowingcodetoeachfile: app/views/devise/registrations/edit.html.erb


< p > < % = f . l a b e l : n a m e % > < b r / > < % = f . t e x t _ f i e l d : n a m e % > < / p >

app/views/devise/registrations/new.html.erb
< p > < % = f . l a b e l : n a m e % > < b r / >

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

9/19

19/06/2013
< % = f . t e x t _ f i e l d : n a m e % > < / p >

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

Wedonotneedtoaddacontrollerwithmethodstocreateanewuseroreditordeleteauser.Weusetheexistingregisterablemodulefrom Devisewhichprovidesacontrollerwithmethodstocreate,editordeleteauser. NotethatDevisesdefaultbehaviourallowsanyloggedinusertoeditordeletehisorherownrecord(butnooneelses).Whenyouaccessthe editpageyouareeditingjustyourinfo,andnotinfoofotherusers.

CreateCustomizedViewsforUserRegistration(Haml)
IfyouareusingHaml,DevisedoesnotgenerateviewsforHaml(itdidbeforeDevise1.2seeDeviseissue878).SeeHowToCreateHamland SlimViewsfromtheDevisewiki. IfyouareusingHaml,youcangeneratetheERBfilesusing r a i l sg e n e r a t ed e v i s e : v i e w s andthenconvertthemusingtheonlinetool Html2Haml.Youllneedtoremovethe.erbfilesandreplacethemwithapp/views/devise/registrations/edit.html.hamland app/views/devise/registrations/new.html.haml.

CreateaHomePage
TheCreateaHomePagestepintherails3deviserspeccucumbertutorialisidentical.

RemovetheDefaultHomePage
Deletethedefaulthomepagefromyourapplication:
$r mp u b l i c / i n d e x . h t m l

CreateaHomeControllerandView
Createthefirstpageoftheapplication.UsetheRailsgeneratecommandtocreateahomecontrollerandaviews/home/indexpage.Specify n o c o n t r o l l e r s p e c s toavoidoverwritingtheRSpecfilesyouvealreadydownloaded.
$r a i l sg e n e r a t ec o n t r o l l e rh o m ei n d e xn o c o n t r o l l e r s p e c s

Ifyoureusingthedefaulttemplateengine,youllfindanerbfilewithplaceholdercontent: app/views/home/index.html.erb Next,setaroutetoyourhomepage.Editthefileconfig/routes.rbandreplace:


g e t" h o m e / i n d e x "

with
a u t h e n t i c a t e d : u s e r d o r o o t : t o = > ' h o m e # i n d e x ' e n d

r o o t : t o = > " h o m e # i n d e x "

Ifyouexaminethiscode,youllseethatauthenticatedusers(thosewhohaveanaccountandareloggedin)willseethehome/indexpageasthe applicationroot(orhome)page.Andallotherusers(thosewhodonthaveanaccountorwhoarenotloggedin)willseethesamehomepage. Theredundancyservesadidacticpurpose:Ifyoudecideyouwantuserstoseeadifferentpagewhentheylogin,younowknowexactlywhere tochangeit. Bydefault,Devisewillredirecttotheroot_pathaftersuccessfulsigninorsignout.Itiseasytochangetheroot_pathasshowninthe config/routes.rbfile.Alternatively,youcanoverridetheDevisemethods a f t e r _ s i g n _ i n _ p a t h _ f o r and a f t e r _ s i g n _ o u t _ p a t h _ f o r as describedintheDevisewikiarticleHowToRedirecttoaSpecificPage.

TesttheApp
Youcancheckthatyourapprunsproperlybyenteringthecommand
$r a i l ss e r v e r

Toseeyourapplicationinaction,openabrowserwindowandnavigatetohttp://localhost:3000/.Youshouldseeyournewhomepage. StoptheserverwithControlC.

DisplayUsersontheHomePage

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

10/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

TheDisplayUsersontheHomePagestepintherails3deviserspeccucumbertutorialisidentical. Modifythefileapp/controllers/home_controller.rbandadd:
d e f i n d e x @ u s e r s = U s e r . a l l e n d

Modifythefileapp/views/home/index.html.erbandadd:
< h 3 > H o m e < / h 3 > < % @ u s e r s . e a c h d o | u s e r | % > < p > U s e r : < % = u s e r . n a m e % > < / p > < % e n d % >

Thiscodeisnotappropriatefordeploymentinarealapplication.Youlikelywillnotwanttodisplayalistofusersonthehomepage.However,itis convenientforourexample.

CreateaDefaultUser
SetUpaDatabaseSeedFile
TheSetUpaDatabaseSeedFilestepintherails3deviserspeccucumbertutorialisverysimilar.Hereweaddcodetomakethefirstuseran administrator. Youllwanttosetupadefaultusersoyoucantesttheapp.Modifythefiledb/seeds.rbbyadding:
p u t s ' S E T T I N G U P D E F A U L T U S E R L O G I N ' u s e r = U s e r . c r e a t e ! : n a m e = > ' F i r s t U s e r ' , : e m a i l = > ' u s e r @ e x a m p l e . c o m ' , : p a s s w o r d = > ' p l e a s e ' , : p a s s w o r d _ c o n f i r m a t i o n = > ' p l e a s e ' p u t s ' N e w u s e r c r e a t e d : ' < < u s e r . n a m e u s e r 2 = U s e r . c r e a t e ! : n a m e = > ' S e c o n d U s e r ' , : e m a i l = > ' u s e r 2 @ e x a m p l e . c o m ' , : p a s s w o r d = > ' p l e a s e ' , : p a s s w o r d _ c o n f i r m a t i o n = > ' p l e a s e ' p u t s ' N e w u s e r c r e a t e d : ' < < u s e r 2 . n a m e u s e r . a d d _ r o l e : a d m i n

IfyouvechosentocreatetheapplicationwiththeDeviseConfirmablemodule,addthefield
p u t s ' S E T T I N G U P D E F A U L T U S E R L O G I N '

c o n f i r m e d _ a t:

u s e r = U s e r . c r e a t e ! : n a m e = > ' F i r s t U s e r ' , : e m a i l = > ' u s e r @ e x a m p l e . c o m ' , : p a s s w o r d = > ' p l e a s e ' , : p a s s w o r d _ c o n f i r m a t i o n = > ' p l e a s e ' , : c o n f i r m e d _ a t = > D a t e T i m e . n o w p u t s ' N e w u s e r c r e a t e d : ' < < u s e r . n a m e u s e r 2 = U s e r . c r e a t e ! : n a m e = > ' S e c o n d U s e r ' , : e m a i l = > ' u s e r 2 @ e x a m p l e . c o m ' , : p a s s w o r d = > ' p l e a s e ' , : p a s s w o r d _ c o n f i r m a t i o n = > ' p l e a s e ' , : c o n f i r m e d _ a t = > D a t e T i m e . n o w p u t s ' N e w u s e r c r e a t e d : ' < < u s e r 2 . n a m e u s e r . a d d _ r o l e : a d m i n

Youcanchangethevaluesforname,email,andpasswordasyouwish.

SeedtheDatabase
Addthedefaultusertothedatabasebyrunningthecommand:
$b u n d l ee x e cr a k ed b : s e e d

Ifyouneedto,youcanrun

$b u n d l ee x e cr a k ed b : r e s e t todropandthenrecreatethedatabaseusingyourseeds.rbfile.

IfthetaskfailswithValidationfailed:Namecantbeblankyoushouldcheckthatthefilemodels/user.rballowsthenameattributetobemass updated:
a t t r _ a c c e s s i b l e : n a m e , : e m a i l , : p a s s w o r d , : p a s s w o r d _ c o n f i r m a t i o n , : r e m e m b e r _ m e

TesttheApp
Atthispoint,youmaywanttoknowifthedefaultuserhasbeensavedtothedatabase.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

11/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

Youcancheckthatyourapprunsproperlybyenteringthecommand
$r a i l ss e r v e r

Toseeyourapplicationinaction,openabrowserwindowandnavigatetohttp://localhost:3000/.Youshouldseeyournewhomepage. StoptheserverwithControlC.

AddLinkstoUsersontheHomePage
TheAddLinkstoUsersontheHomePagestepintherails3deviserspeccucumbertutorialisidentical. Youvealreadymodifiedthefileapp/controllers/home_controller.rbtoincludethis:
d e f i n d e x @ u s e r s = U s e r . a l l e n d

Nowmodifythefileapp/views/home/index.html.erbtolooklikethis:
< h 3 > H o m e < / h 3 > < % @ u s e r s . e a c h d o | u s e r | % > < p > U s e r : < % = l i n k _ t o u s e r . n a m e , u s e r % > < / p > < % e n d % >

Thiscodeisnotappropriatefordeploymentinarealapplication.Youlikelywillnotwanttodisplayalistofusersonthehomepage.However,itis convenientforourexample. Thelinkstotheusersprofilepagewillnotyetworkinthenextsectionwellcreateauserscontroller,routes,andviews.

SetUptheUsersController,Routes,andViews
TheSetUptheUsersController,Views,andRoutesstepintherails3deviserspeccucumbertutorialisverysimilar.Herewesetupthe UsersControllertodemonstrateuseofauthorizationinalaterstep.

CreateaUsersController
UsetheRailsgeneratecommandtocreateauserscontrollerandaviews/user/showpage.Youcanspecify youvealreadydownloadedRSpecfilesfortheexampleapplication.
$r a i l sg e n e r a t ec o n t r o l l e ru s e r si n d e xs h o wn o c o n t r o l l e r s p e c s n o c o n t r o l l e r s p e c s if

Notethatusersispluralwhenyoucreatethecontroller.

SetUptheUsersRoutes
Thefileconfig/routes.rbhasalreadybeenmodifiedtoinclude:
g e t " u s e r s / i n d e x " g e t " u s e r s / s h o w "

Removethatandchangetheroutesto:
r o o t : t o = > " h o m e # i n d e x " d e v i s e _ f o r : u s e r s r e s o u r c e s : u s e r s , : o n l y = > [ : s h o w , : i n d e x ]

Importantnote:The

d e v i s e _ f o r: u s e r s routemustbeplacedabove r e s o u r c e s: u s e r s ,: o n l y= >[ : s h o w ,: i n d e x ].

SetUptheUsers#ShowPage
Modifythefileapp/views/users/show.html.erbandadd:
< p > U s e r : < % = @ u s e r . n a m e % > < / p > < p > E m a i l : < % = @ u s e r . e m a i l i f @ u s e r . e m a i l % > < / p >

Inatypicalapplication,thispagemightprovideadditionaldetailsabouttheusersaccount.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

12/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

SetUptheUsers#IndexPage
Forthepurposesofourexample,thispagewillbeaccessibleonlytoadministrators.Itwilldisplayalistofallusersoftheapplication. Modifythefileapp/views/users/index.html.erbandadd:
< u l c l a s s = " u s e r s " > < % @ u s e r s . e a c h d o | u s e r | % > < l i > < % = l i n k _ t o u s e r . n a m e , u s e r % > s i g n e d u p < % = u s e r . c r e a t e d _ a t . t o _ d a t e % > < / l i > < % e n d % > < / u l >

Wewanttorestrictaccesstothispage,theUsers#indexpageathttp://localhost:3000/users.Inthenextsection,wewillsetupauthorizationso thepageisaccessibleonlytoadministrators.

SetUpaDemonstrationofCanCan
TheSetUpaDemonstrationofDevisestepintherails3deviserspeccucumbertutorialisverysimilar.Hereweaddcodetolimitaccesstothe i n d e x methodoftheUsersController. YoullwanttoseehowCanCanisusedtolimitaccesstoonlytheadministrator.

FirstAuthorizationExample:UsersControllerwithCanCan@authorize!
Modifythefileapp/controllers/users_controller.rblikethis:
c l a s s U s e r s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r b e f o r e _ f i l t e r : a u t h e n t i c a t e _ u s e r !

d e f i n d e x a u t h o r i z e ! : i n d e x , @ u s e r , : m e s s a g e = > ' N o t a u t h o r i z e d a s a n a d m i n i s t r a t o r . ' @ u s e r s = U s e r . a l l e n d

d e f s h o w @ u s e r = U s e r . f i n d ( p a r a m s [ : i d ] ) e n d

e n d

OnlyonelineofcodeisneededtolimitaccesstotheUsers#indexpageat http://localhost:3000/users:
a u t h o r i z e ! : i n d e x , @ u s e r , : m e s s a g e = > ' N o t a u t h o r i z e d a s a n a d m i n i s t r a t o r . '

TheCanCan a u t h o r i z e ! methodwillchecktheCanCan A b i l i t y classdefinitiontodetermineiftheuserhaspermissiontoexecutethe i n d e x method.Wevepreviouslysetaruleinthe A b i l i t y classdefinitionthatgivesauserinanadministratorroletheabilitytoexecuteall methods:


i f u s e r . h a s _ r o l e ? : a d m i n c a n : m a n a g e , : a l l e n d

Noruleispresentforotherusers,sobydefault,otherusersarerestrictedfromexecutingthe

i n d e x method.

ThisapproachisthemostobviouswaytoimplementauthorizationusingCanCan.However,CanCanoffersconveniencemethodsthatcan eliminatesuperfluouscontrollercodeinsomeapplications.ThenextexampleshowshowtouseCanCanconveniencemethodstoreducethe amountofcodeinyourcontrollers.

SecondAuthorizationExample:UsersControllerwithCanCanload_and_authorize_resource
CanCanprovidesaconveniencemethod
a u t h o r i z e _ r e s o u r c e thatappliesthe a u t h o r i z e ! methodtoeveryactioninthecontroller.Another

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

13/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps
u s e r s=U s e r . a l l

conveniencemethod l o a d _ r e s o u r c e queriesthedatabaseandloadstheresourcesrequiredbyeachaction(forexample, forthe i n d e x action).Athirdconveniencemethodcombinesthetwoas l o a d _ a n d _ a u t h o r i z e _ r e s o u r c e. Using


l o a d _ a n d _ a u t h o r i z e _ r e s o u r c e ,youcansetupthefileapp/controllers/users_controller.rblikethis:

c l a s s U s e r s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r b e f o r e _ f i l t e r : a u t h e n t i c a t e _ u s e r ! l o a d _ a n d _ a u t h o r i z e _ r e s o u r c e : o n l y = > : i n d e x

d e f s h o w @ u s e r = U s e r . f i n d ( p a r a m s [ : i d ] ) e n d

e n d

The

i n d e x actiondoesnotneedtobedeclaredbecauseRailsprovidesitbydefault.

Ifanonadministratortriestoviewtheathttp://localhost:3000/usersheorshewillberedirectedtothehomepage(asspecifiedbythe r e s c u e _ f r o mC a n C a n : : A c c e s s D e n i e d methodintheApplicationController)andwillseeCanCansgenericexceptionmessage,Youarenot authorizedtoaccessthispage.YoucancustomizetheexceptionmessageintheApplicationController,ifyouwish. Somedeveloperswilllikethisapproachotherswillfeelitdriesupcodeattheexpenseofintroducinglayersofblackmagic.Ifyoupreferamore explicitapproach,thenextexampleshowshowtoimplementsimplerolebasedauthorizationwithoutusingCanCanatall.

ThirdAuthorizationExample:UsersControllerwithoutCanCan
ThepurportedbenefitofusingCanCanistheadvantageofmaintainingauthorizationrulesinonelocation,the matteroftasteyoumayprefertoconfineauthorizationcodetoonlythecontrollersthatneedit.
A b i l i t y class.Thismaybea

HereisanexampleoflimitingaccesstotheUsers#indexpageusingonlymethodsprovidedbytheRolifygem.CanCanisnotused.
c l a s s U s e r s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r b e f o r e _ f i l t e r : a u t h e n t i c a t e _ u s e r ! b e f o r e _ f i l t e r : o n l y _ a l l o w _ a d m i n , : o n l y = > [ : i n d e x ] d e f i n d e x @ u s e r s = U s e r . a l l e n d

d e f s h o w @ u s e r = U s e r . f i n d ( p a r a m s [ : i d ] ) e n d

p r i v a t e

d e f o n l y _ a l l o w _ a d m i n r e d i r e c t _ t o r o o t _ p a t h , : a l e r t = > ' N o t a u t h o r i z e d a s a n a d m i n i s t r a t o r . ' u n l e s s c u r r e n t _ u s e r . h a s _ r o l e ? : a d m i n e n d

e n d

Ifmultiplecontrollerswillusethe method.

o n l y _ a l l o w _ a d m i n method,itcanbemovedtotheApplicationControllersoallcontrollerswillinheritthe

IncontrasttoCanCan,alltheauthorizationlogicisdefinedinthecontroller.Forasmallapplication,thisapproachissimplerandlessconfusing. YoumayfindthisapproachpreferabletousingCanCan,ifyourapplicationonlyrequiressimplerolebasedauthorization.However,foralargeor complexapplicationwithmultiplerolesandmanyconstrainedactivities,CanCanoffersbetterseparationofconcerns.

CreateanApplicationLayout
Railswillusethelayoutdefinedinthefileapp/views/layouts/application.html.erbasadefaultforrenderinganypage.IfyouareusingHaml,the filewillbeapp/views/layouts/application.html.haml. Youllwanttoaddnavigationlinks,includeflashmessagesforerrorsandnotifications,andapplyCSSstyling.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

14/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

ThistutorialshowscodeusingERB,thedefaultRailstemplatinglanguage.IfyouprefertouseHaml,seethedetailedguideRailsDefault ApplicationLayoutforHTML5.

NavigationLinks
Youlllikelyneednavigationlinksoneverypageofyourwebapplication.YoullwantalinkforHome.YoullwantlinksforLogin,Logout,andSign Up.AndauserwhoisanadministratorshouldseealinkforAdmin. Youcanaddnavigationlinksdirectlytoyourapplicationlayoutfilebutmanydevelopersprefertocreateapartialtemplateapartialtobetter organizethedefaultapplicationlayout. Createthefileapp/views/layouts/_navigation.html.erbforthenavigationlinks:
< % = l i n k _ t o " R a i l s 3 B o o t s t r a p D e v i s e C a n c a n " , r o o t _ p a t h , : c l a s s = > ' b r a n d ' % > < u l c l a s s = " n a v " > < % i f u s e r _ s i g n e d _ i n ? % > < l i > < % = l i n k _ t o ( ' L o g o u t ' , d e s t r o y _ u s e r _ s e s s i o n _ p a t h , : m e t h o d = > ' d e l e t e ' ) % > < / l i > < % e l s e % > < l i > < % = l i n k _ t o ( ' L o g i n ' , n e w _ u s e r _ s e s s i o n _ p a t h ) % > < / l i > < % e n d % > < % i f u s e r _ s i g n e d _ i n ? % > < l i > < % = l i n k _ t o ( ' E d i t a c c o u n t ' , e d i t _ u s e r _ r e g i s t r a t i o n _ p a t h ) % > < / l i > < % i f c u r r e n t _ u s e r . h a s _ r o l e ? : a d m i n % > < l i > < % = l i n k _ t o ( ' A d m i n ' , u s e r s _ p a t h ) % > < / l i > < % e n d % > < % e l s e % > < l i > < % = l i n k _ t o ( ' S i g n u p ' , n e w _ u s e r _ r e g i s t r a t i o n _ p a t h ) % > < / l i > < % e n d % > < / u l >

Noticethecondition < %i fc u r r e n t _ u s e r . h a s _ r o l e ?: a d m i n% > thatusesa displayonlyiftheuserisanadministrator.

h a s _ r o l e ? methodprovidedbytheRolifygem.TheAdminlinkwill

FlashMessages
Railsprovidesastandardconventiontodisplayalerts(includingerrormessages)andothernotices(includingsuccessmessages),calledRails flashmessages(asinflashmemory,nottobeconfusedwiththeAdobeFlashproprietarywebdevelopmentplatform). Youcanincludecodetodisplayflashmessagesdirectlyinyourapplicationlayoutfileoryoucancreateapartial. Createapartialforflashmessagesinapp/views/layouts/_messages.html.erblikethis:
< % f l a s h . e a c h d o | n a m e , m s g | % > < d i v c l a s s = " a l e r t a l e r t < % = n a m e = = : n o t i c e ? " s u c c e s s " : " e r r o r " % > " > < a c l a s s = " c l o s e " d a t a d i s m i s s = " a l e r t " > & # 2 1 5 < / a > < % = c o n t e n t _ t a g : d i v , m s g , : i d = > " f l a s h _ # { n a m e } " i f m s g . i s _ a ? ( S t r i n g ) % > < / d i v > < % e n d % >

Railsuses

: n o t i c e and : a l e r t asflashmessagekeys.TwitterBootstrapprovidesabaseclass . a l e r t withadditionalclasses

. a l e r t s u c c e s s and . a l e r t e r r o r (seetheBootstrapdocumentationonalerts).AbitofparsingisrequiredtogetaRailsnoticemessageto

bestyledwiththeTwitterBootstrapalertsuccessstyle.Anyothermessage,includingaRailsalertmessage,willbestyledwiththeTwitter Bootstrapalerterrorstyle.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

15/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

TwitterBootstrapprovidesajQuerypluginnamedbootstrapalertthatmakesiteasytodismissflashmessageswithaclick.Thedatadismiss propertydisplaysanxthatenablestheclosefunctionality.NotethatTwitterBootstrapusestheHTMLentity&#215insteadofthekeyboard letterx. Bydefault,TwitterBootstrapappliesagreenbackgroundto . a l e r t s u c c e s s andaredbackgroundto . a l e r t e r r o r .TwitterBootstrap providesathirdclass . a l e r t i n f o withabluebackground.Withalittlehacking,itspossibletocreateaRailsflashmessagewithacustom name,suchas : i n f o ,thatwilldisplaywiththeBootstrap . a l e r t i n f o class.However,itswisetostickwiththeRailsconventionofusing onlyalertandnotice.

CSSStylingwithSASS
Itsagoodideatorenametheapp/assets/stylesheets/application.cssfileasapp/assets/stylesheets/application.css.scss. ThiswillallowyoutousetheadvantagesoftheSASSsyntaxandfeaturesforyourapplicationstylesheet.FormoreontheadvantagesofSASS andhowtouseit,seetheSASSBasicsRailsCastfromRyanBates.

CSSStylingwithTwitterBootstrap
TwitterBootstrapandotherCSSfrontendframeworks(suchasZurbFoundation)aretoolkitsthatprovidethekindofstructureandconvention thatmakeRailspopularforserverside(backend)development.YoucanuseTwitterBootstraptoquicklyaddattractiveCSSstylingtoyour application.IfyouvegeneratedyourappfromanapplicationtemplateintheRailsAppsApplicationTemplatesrepository,thescriptwillofferto installTwitterBootstraporotherCSSfrontendframeworksandsetupyourdefaultapplicationlayoutaccordingly. SeveraloptionsareavailableforinstallingTwitterBootstrapinaRailsapplication.TwitterBootstrapcanbeinstalledusingeitheritsnativeLESS CSSlanguageortheSASSlanguagethatisthedefaultforCSSfilesinRails.SeethearticleTwitterBootstrap,Less,andSass:Understanding YourOptionsforRails3.1.SASSisadefaultforCSSdevelopmentinRailssoIrecommendyouinstallThomasMcDonaldsbootstrapsass gem. InyourGemfile,youvealreadyadded:
g e m ' b o o t s t r a p s a s s '

andpreviouslyrun

$b u n d l ei n s t a l l.

IncludetheTwitterBootstrapJavascriptfilesbymodifyingthefileapp/assets/javascripts/application.js:
/ / = r e q u i r e j q u e r y / / = r e q u i r e j q u e r y _ u j s / / = r e q u i r e b o o t s t r a p / / = r e q u i r e _ t r e e .

Next,importtheTwitterBootstrapCSSfiles.Youcanmodifytheapp/assets/stylesheets/application.css.scssfiletoimportBootstrap. However,Irecommendaddinganewfileapp/assets/stylesheets/bootstrap_and_overrides.css.scssfile.YoumaywishtomodifytheTwitter BootstrapCSSrulesyoucandosointheapplication.css.scssfilebutplacingchangestoTwitterBootstrapCSSrulesinthe bootstrap_and_overrides.css.scssfilewillkeepyourCSSbetterorganized. Thefileapp/assets/stylesheets/bootstrap_and_overrides.css.scssisautomaticallyincludedandcompiledintoyourRailsapplication.cssfile bythe * =r e q u i r e _ t r e e . statementintheapp/assets/stylesheets/application.css.scssfile. Addthefileapp/assets/stylesheets/bootstrap_and_overrides.css.scss:


/ / S e t t h e c o r r e c t s p r i t e p a t h s $ i c o n S p r i t e P a t h : i m a g e u r l ( ' g l y p h i c o n s h a l f l i n g s . p n g ' ) $ i c o n W h i t e S p r i t e P a t h : i m a g e u r l ( ' g l y p h i c o n s h a l f l i n g s w h i t e . p n g ' ) @ i m p o r t " b o o t s t r a p " b o d y { p a d d i n g t o p : 6 0 p x } @ i m p o r t " b o o t s t r a p r e s p o n s i v e "

ThefilewillimportbothbasicBootstrapCSSrulesandtheBootstraprulesforresponsivedesign(allowingthelayouttoresizeforvariousdevices andsecreensizes). TheCSSrule


b o d y{p a d d i n g t o p :6 0 p x ; } appliesanadditionalCSSruletoaccommodatetheBootstrapblackbarheadingcreatedbythe

n a v b a r f i x e d t o pc l a s s inthe h e a d e r taginthelayoutbelow.

Finally,toprovideanexampleofaddingaCSSrulethatwillbeusedoneverypageofyourapplication,thefollowingcodecreatesanicegraybox asabackgroundtopagecontent.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

16/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

Addthistoyourapp/assets/stylesheets/application.css.scssfileforagraybackground:
. c o n t e n t { b a c k g r o u n d c o l o r : # e e e p a d d i n g : 2 0 p x m a r g i n : 0 2 0 p x / * n e g a t i v e i n d e n t t h e a m o u n t o f t h e p a d d i n g t o m a i n t a i n t h e g r i d s y s t e m * / w e b k i t b o r d e r r a d i u s : 0 0 6 p x 6 p x m o z b o r d e r r a d i u s : 0 0 6 p x 6 p x b o r d e r r a d i u s : 0 0 6 p x 6 p x w e b k i t b o x s h a d o w : 0 1 p x 2 p x r g b a ( 0 , 0 , 0 , . 1 5 ) m o z b o x s h a d o w : 0 1 p x 2 p x r g b a ( 0 , 0 , 0 , . 1 5 ) b o x s h a d o w : 0 1 p x 2 p x r g b a ( 0 , 0 , 0 , . 1 5 ) }

DefaultApplicationLayoutwithTwitterBootstrap
GeneratinganewRailsapplicationwiththe r a i l sn e w commandwillcreateadefaultapplicationlayoutinthefile app/views/layouts/application.html.erb.Modifythefiletoaddnavigationlinks,includeflashmessages,andapplyCSSstyling.Twitter Bootstrapprovidesadditionalelementsforamorecomplexpagelayout. UsethecodebelowtoincorporaterecommendationsfromthearticleHTML5BoilerplateforRailsDevelopers. Replacethecontentsofthefileapp/views/layouts/application.html.erbwiththis:
< ! d o c t y p e h t m l > < h t m l > < h e a d > < m e t a c h a r s e t = " u t f 8 " > < m e t a h t t p e q u i v = " X U A C o m p a t i b l e " c o n t e n t = " I E = e d g e , c h r o m e = 1 " > < m e t a n a m e = " v i e w p o r t " c o n t e n t = " w i d t h = d e v i c e w i d t h , i n i t i a l s c a l e = 1 . 0 " > < t i t l e > < % = c o n t e n t _ f o r ? ( : t i t l e ) ? y i e l d ( : t i t l e ) : " M y a p p " % > < / t i t l e > < m e t a n a m e = " d e s c r i p t i o n " c o n t e n t = " " > < m e t a n a m e = " a u t h o r " c o n t e n t = " " > < % = s t y l e s h e e t _ l i n k _ t a g " a p p l i c a t i o n " , : m e d i a = > " a l l " % > < % = j a v a s c r i p t _ i n c l u d e _ t a g " a p p l i c a t i o n " % > < % = c s r f _ m e t a _ t a g s % > < % = y i e l d ( : h e a d ) % > < / h e a d > < b o d y > < h e a d e r c l a s s = " n a v b a r n a v b a r f i x e d t o p " > < n a v c l a s s = " n a v b a r i n n e r " > < d i v c l a s s = " c o n t a i n e r " > < % = r e n d e r ' l a y o u t s / n a v i g a t i o n ' % > < / d i v > < / n a v > < / h e a d e r > < d i v i d = " m a i n " r o l e = " m a i n " > < d i v c l a s s = " c o n t a i n e r " > < d i v c l a s s = " c o n t e n t " > < d i v c l a s s = " r o w " > < d i v c l a s s = " s p a n 1 2 " > < % = r e n d e r ' l a y o u t s / m e s s a g e s ' % > < % = y i e l d % > < / d i v > < / d i v > < f o o t e r > < / f o o t e r > < / d i v > < / d i v > < ! ! e n d o f . c o n t a i n e r > < / d i v > < ! ! e n d o f # m a i n > < / b o d y >

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

17/19

19/06/2013
< / h t m l >

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

OptionsandImprovements
Yourdefaultapplicationlayoutdefinesthelookandfeelofyourapplication.Younowhavethebasicswithnavigationlinks,messagesforalerts andnotices,andCSSstylingusingTwitterBootstrap. Theresmuchmoreyoucando.Foranadvancedexample,seetheRailsApprailsprelaunchsignupexampleapp.Therailsprelaunchsignup tutorialshowshowyoucanuseTwitterBootstraptoaddamodalwindowandAJAXforasignupformforaWeb2.0application.Whenthe visitorsubmitstheform,themodalwindowchangestodisplayathankyoumessage(oranerrormessage)withoutapagerefresh.

Cleanup
SeveralunneededfilesaregeneratedintheprocessofcreatinganewRailsapplication. Additionally,youmaywanttopreventsearchenginesfromindexingyourwebsiteifyouvedeployeditpubliclywhilestillindevelopment. SeeinstructionsforcleaningupunneededfilesinRailsandbanningspiders.

TesttheApp
Youcancheckthatyourapprunsproperlybyenteringthecommand
$r a i l ss e r v e r

Toseeyourapplicationinaction,openabrowserwindowandnavigatetohttp://localhost:3000/.Youshouldseethedefaultuserlistedonthe homepage.Whenyouclickontheusersname,youshouldberequiredtologinbeforeseeingtheusersdetailpage. Tosigninasthefirstuser(theadministrator),(unlessyouvechangedit)use


email:user@example.com password:please

YoullseeanavigationlinkforAdmin.Clickingthelinkwilldisplayapagewithalistofusersat http://localhost:3000/users. Tosigninastheseconduser,(unlessyouvechangedit)use


email:user2@example.com password:please

TheseconduserwillnotseetheAdminnavigationlinkandwillnotbeabletoaccessthepageat http://localhost:3000/users. StoptheserverwithControlC.

DeploytoHeroku
Herokuprovideslowcost,easilyconfiguredRailsapplicationhosting.Foryourconvenience,seeTutorial:RailsonHeroku.

Conclusion
ThisconcludesthetutorialforcreatingaRubyonRailswebapplicationthatusesDeviseandaddsCanCanandTwitterBootstrap.

Credits
DanielKehoeimplementedtheapplicationandwrotethetutorial. Wasthisusefultoyou?Followrails_appsonTwitterandtweetsomepraise.Idlovetoknowyouwerehelpedoutbythetutorial. Anyissues?PleasecreateanIssueonGitHub.

Comments
Isthishelpful?Please"like"below.Questionorsuggestion?Pleaseaddacommentbelow.Gotacorrectionoraddition?Youcaneditthispage onthewikiorcreateaGitHubissuetoalertme.

WewereunabletoloadDisqus.Ifyouareamoderatorpleaseseeourtroubleshootingguide.

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

18/19

19/06/2013

Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps

WewereunabletoloadDisqus.Ifyouareamoderatorpleaseseeourtroubleshootingguide.

Credits
DanielKehoeinitiatedtheRailsAppsProject. ThankstoChristopherDellfordesign contributions.

Contributions
Corrections?Additions?Youcaneditthis pageonthewiki.

Lastedit
byDanielKehoe,2012062211:09:54

file:///home/egor/Desktop/Rails Tutorial for Devise with CanCan and Twitter Bootstrap RailsApps.html

19/19

Вам также может понравиться