Learning Rails Simon St.Laurent, Edd Dumbill, and Eric J Gruber Beijing • Cambridge • Farnham • Kưln • Sebastopol • Tokyo Learning Rails by Simon St.Laurent, Edd Dumbill, and Eric J Gruber Copyright © 2012 Simon St.Laurent, Edd Dumbill, Eric J Gruber All rights reserved Printed in the United States of America Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472 O’Reilly books may be purchased for educational, business, or sales promotional use Online editions are also available for most titles (http://my.safaribooksonline.com) For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com Editor: Simon St.Laurent Production Editor: Iris Febres Proofreader: Jasmine Perez Indexer: Lucie Haskins Cover Designer: Karen Montgomery Interior Designer: David Futato Illustrators: Robert Romano, Rebecca Demarest, and Jessamyn Read July 2012: First Edition Revision History for the First Edition: 2012-07-11 First release See http://oreilly.com/catalog/errata.csp?isbn=9781449309336 for release details Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc Learning Rails 3, the image of the tarpans, and related trade dress are trademarks of O’Reilly Media, Inc Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trademark claim, the designations have been printed in caps or initial caps While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein ISBN: 978-1-449-30933-6 [M] 1342467902 Table of Contents Preface xi Starting Up Ruby on Rails If You Run Windows, You’re Lucky Getting Started at the Command Line Starting Up Rails Test Your Knowledge Quiz Answers 9 Rails on the Web 11 Creating Your Own View What Are All Those Folders? Adding Some Data How Hello World Works Adding Logic to the View Test Your Knowledge Quiz Answers 11 14 16 18 20 22 22 22 Adding Web Style 23 I Want My CSS! Specifying Stylesheets Creating a Layout for a Controller Choosing a Layout from a Controller Sharing Template Data with the Layout Setting a Default Page Test Your Knowledge Quiz Answers 23 28 29 31 33 34 36 36 36 iii Managing Data Flow: Controllers and Models 37 Getting Started, Greeting Guests Application Flow Keeping Track: A Simple Guestbook Connecting to a Database Through a Model Connecting the Controller to the Model Finding Data with ActiveRecord Test Your Knowledge Quiz Answers 37 42 44 44 47 52 54 54 54 Accelerating Development with Scaffolding and REST 57 A First Look at Scaffolding REST and Controller Best Practices Websites and Web Applications Toward a Cleaner Approach Examining a RESTful Controller Index: An Overview of Data Show: Just One Row of Data New: A Blank Set of Data Fields Edit: Hand Me That Data, Please Create: Save Something New Put This Updated Record In Destroy It Escaping the REST Prison Test Your Knowledge Quiz Answers 57 61 61 63 64 69 71 71 72 72 74 75 76 76 76 77 Presenting Models with Forms 79 More Than a Name on a Form Generating HTML Forms with Scaffolding Form as a Wrapper Creating Text Fields and Text Areas Labels Creating Checkboxes Creating Radio Buttons Creating Selection Lists Dates and Times Creating Helper Methods Test Your Knowledge Quiz Answers iv | Table of Contents 79 80 84 87 89 90 91 93 95 97 100 100 100 Strengthening Models with Validation 103 Without Validation The Original Model The Power of Declarative Validation Managing Secrets Customizing the Message Limiting Choices Testing Format with Regular Expressions Seen It All Before Numbers Only A Place on the Calendar Testing for Presence Beyond Simple Declarations Test It Only If Do It Yourself Test Your Knowledge Quiz Answers 103 106 106 109 109 111 112 112 113 114 115 115 115 116 117 117 117 Improving Forms 119 Adding a Picture by Uploading a File File Upload Forms Model and Migration Changes Results Standardizing Your Look with Form Builders Supporting Your Own Field Types Adding Automation Integrating Form Builders and Styles Test Your Knowledge Quiz Answers 119 120 120 126 129 130 132 134 137 137 138 Developing Model Relationships 139 Connecting Awards to Students Establishing the Relationship Supporting the Relationship Guaranteeing a Relationship Connecting Students to Awards Removing Awards When Students Disappear Counting Awards for Students Nesting Awards in Students Changing the Routing Changing the Controller 140 140 141 145 146 146 147 148 149 150 Table of Contents | v Changing the Award Views Connecting the Student Views Is Nesting Worth It? Many-to-Many: Connecting Students to Courses Creating Tables Connecting the Models Adding to the Controllers Adding Routing Supporting the Relationship Through Views What’s Missing? Test Your Knowledge Quiz Answers 153 156 158 159 159 161 162 164 164 172 172 172 173 10 Managing Databases with Migrations 175 What Migrations Offer You Migration Basics Migration Files Running Migrations Forward and Backward Inside Migrations Working with Tables Data Types Working with Columns Indexes Other Opportunities Test Your Knowledge Quiz Answers 175 176 177 178 180 181 181 183 183 184 185 185 185 11 Debugging 187 Creating Your Own Debugging Messages Raising Exceptions Logging Working with Rails from the Console The Ruby Debugger Test Your Knowledge Quiz Answers 187 188 188 190 195 199 199 199 12 Testing 201 Test Mode Setting Up a Test Database with Fixtures Unit Testing vi | Table of Contents 201 202 206 Functional Testing Calling Controllers Testing Responses Dealing with Nested Resources Integration Testing Beyond the Basics Test Your Knowledge Quiz Answers 212 214 215 216 218 220 221 221 221 13 Sessions and Cookies 223 Getting Into and Out of Cookies Storing Data Between Sessions Test Your Knowledge Quiz Answers 223 230 235 235 235 14 Users and Authentication 237 Installation Storing Identities Storing User Data Wiring OmniAuth into the Application Classifying Users More Options Test Your Knowledge Quiz Answers 237 239 239 240 248 255 256 256 256 15 Routing 257 Creating Routes to Interpret URIs Specifying Routes with match Globbing Regular Expressions and Routing A Domain Default with root Named Routes Mapping Resources Nesting Resources Route Order and Priority Checking the Map Generating URIs from Views and Controllers Pointing url_for in the Right Direction Adding Options Infinite Possibilities 258 258 260 261 261 262 263 264 265 265 266 266 267 267 Table of Contents | vii Test Your Knowledge Quiz Answers 268 268 268 16 From CSS to SASS 271 Getting Started Sassy Style Variables Mixins Nesting Making Everything Work Together Becoming Sassier Test Your Knowledge Quiz Answers 271 272 272 274 275 276 279 280 280 280 17 Managing Assets and Bundles 281 The Junk Drawer Sprockets Dissecting The Pipeline Putting It All Together Bundler Test Your Knowledge Quiz Answers 281 282 283 283 286 290 290 290 18 Sending Code to the Browser: JavaScript and CoffeeScript 291 Sending JavaScript to the Browser Simplifying with CoffeeScript Have Some Sugar with your CoffeeScript Converting to CoffeeScript Test Your Knowledge Quiz Answers 292 293 295 297 298 298 298 19 Mail in Rails 299 Sending Mail Messages Receiving Mail Setup Processing Messages Test Your Knowledge Quiz Answers viii | Table of Contents 299 304 305 305 308 308 308 specifying stylesheets, 28 CSV (comma-separated values), 357 Cucumber testing framework, 201, 220 curly braces {} arguments specifying attributes, 90 blocks of code in, 28, 325 CoffeeScript and, 295 CVS (Concurrent Versioning System), 357 Cygwin, D data adding to controllers, 16–18 finding with ActiveRecord, 52–54 rendering, 44, 364 retrieving from models, 49–51 storing between sessions, 230–234 storing using cookies, 230–234 storing using models, 47–49 storing with OmniAuth, 239 viewing data being sent, 51 Data Definition Language (DDL), 175 data flow getting started example, 37–41 keeping track of, 44–51 process overview, 42 data types, 79–80, 181–183 data validation (see validation) database.yml file, xvi, 202 databases connecting through models, 44–47 deployment considerations, 311 extending models beyond, 122–125 managing with migrations, 175–186 removing NULLs from, 49 test, 202–206 :date type, 79, 181 dates and times in forms, 95–97 :datetime type, 79, 181 datetime_select method, 96 date_select method, 96 db folder, 15, 366 db:create task, 179 db:drop task, 179 db:migrate task, 47, 49, 178 db:reset task, 179 db:rollback task, 47, 49, 179 DDL (Data Definition Language), 175 debug method, 51, 187 374 | Index debugging creating debugging messages, 187 logging, 188 raising exceptions, 188 Ruby debuggeg, 195–199 working from console, 190–194 DebugHelper class, 187 :decimal type, 79, 181 declarative validation, 106–109 def keyword, 16 default domain, setting, 261 default pages, setting, 34 :default parameter (data types), 182 delete method, 193, 214 DELETE requests (HTTP) functionality, 62, 63, 357 RESTful controller example, 67 delimiters, ERb supported, 17 deployment considerations for, 310–313 defined, 357 destroy method before and after methods for, 123 functionality, 75 RESTful controller example, 67 development mode, 201, 310, 357 development.log file, 188 development.rb file, 202 DHH (David Heinemeier Hansson), 281, 357 :disabled parameter (date and time methods), 96 discard method (flash messaging), 235 :discard_day parameter (date and time methods), 96 distinct method, 184 div element, 108 doc folder, 15 DOM (Document Object Model), 357 :domain option (cookie object), 229 Domain Specific Languages (DSLs), 267, 317 domain, default, 261 drop_table method, 181, 184 DRY principle, 27, 132, 357 DSLs (Domain Specific Languages), 267, 317 duck typing, 316, 357 dynamic finders, 54 dynamic scaffolds, 357 dynamic typing, 316, 357 E Edge Rails, 357 edit method functionality, 72 RESTful controller example, 66 else statement, 296, 328 elsif statement, 329 email messages receiving, 304–308 sending, 299–304 Embedded Ruby (ERb) defined, 358 delimiters supported, 17 end keyword, 16 END statement, 333 :end_year parameter (date and time methods), 96 EngineYard Rails Installer, 2, environment.rb file, 202 equal_to parameter (validates_numericality_of method), 113 ERb (Embedded Ruby) defined, 358 delimiters supported, 17 erb file extension, 13 :error key (flash messaging), 235 :error parameter (assert_response method), 215 Erubis (Ruby impllementation), 358 escaping regular expressions, 346 even parameter (validates_numericality_of method), 113 exceptions defined, 358 raising in debugging, 188 execute method, 185 exit command (irb session), 191 :expires option (cookie object), 229 Extensible HTML (XHTML), 368 Extensible Markup Language (XML), 368 F Factory Girl gem, 201, 221 files, uploading to forms, 119–129 filters, defined, 358 filter_parameter_logging method, 190 find method :all parameter, 52, 70, 142 :first parameter, 52 :id value, 52, 71, 75 :last parameter, 52 retrieving records with, 52–54 find_by_sql method, 342 Firebug plug-in, 358 :first parameter (find method), 52 fixtures defined, 202, 358 setting up test databases with, 202–206 flash messaging defined, 358 discard method, 235 keep method, 235 now method, 235 session state and, 234 :float type, 79, 181 flunk method, 208 folders, list of commonly used, 14 for statement, 20–21, 332 foreign keys, 338 form builders automating building with, 132–134 building reusable form components, 130– 132 defined, 358 integrating with styles, 134–137 standardizing look with, 129 form element action attribute, 86 class attribute, 86 creating, 84 id attribute, 86 format, testing with regular expressions, 112 FormBuilder class, 324 FormHelper module (ActionView), 86 forms adding pictures to, 119–129 checkboxes in, 90 creating helper methods, 97–100 data types supported, 79–80 dates and times in, 95–97 generating with scaffolding, 80–84 labels in, 89 radio buttons in, 91–93 selection lists in, 93 standardizing with form builders, 129–137 text fields and text areas in, 87–88 uploading files to, 119–129 Index | 375 as wrappers, 84–87 form_for method :builder parameter, 87, 131 file uploads with, 120 functionality, 84–87 :remote parameter, 87 :url parameter, 86 usage example, 83, 325 form_tag method, 39, 168 fragments, defined, 358 freezing applications, 358 from method, 53 functional testing calling controllers, 214 nested resources and, 216–217 process overview, 212–214 testing responses, 215–216 G gem install rails command, gem install sqlite3 command, gem install validates_existence command, 145 gem list command, gem server command, gemfile.lock file, 287 gems authentication, 237 debugging, 195 defined, 358 managing, 286–290 testing, 201, 221 generate program (see rails generate commands) get method, 193, 214 GET requests (HTTP) functionality, 61–63, 359 RESTful controller example, 66 Git application, 311, 359 Github website, 311, 359 globbing, 260 GMT (Greenwich Mean Time), 367 granularity, data, 340 greater_than parameter (validates_numericality_of method), 113 greater_than_or_equal_to parameter (validates_numericality_of method), 113 greedy operators, 350 376 | Index Greenwich Mean Time (GMT), 367 group method, 53 groups in regular expressions, 349 guestbooks managing data flow example, 37, 44–51 scaffolding example, 57–61 H h method, 359 Hansson, David Heinemeier, 281, 357 hashes defined, 322, 359 variables and, 321–322 has_and_belongs_to_many method, 161, 172 has_many method functionality, 140 :through parameter, 161, 172 usage example, 146 head element csrf_meta_tag method in, 25 javascript_include_tag method in, 25 linking stylesheets from, 24 stylesheet_link_tag method in, 25 HEAD requests (HTTP), 63, 359 Hello World programs CSS and, 23–28 how they work, 18–20 helper methods building reusable form components, 130 creating, 97–100 defined, 359 hidden_field method, 88 :host option (url_for method), 267 HTML (HyperText Markup Language) additional information, 23 defined, 359 HTML forms (see forms) html_safe property, 20, 99 HTTP (HyperText Transfer Protocol), 359 HTTP requests defined, 364 functional testing and, 214 routing, 43 HTTP responses defined, 364 testing, 215–216 HTTP sessions cookies and, 223–229 defined, 365 storing data between, 230–234 HTTPS (HyperText Transfer Protocol over Secure Socket Layer), 360 :http_only option (cookie object), 229 Hunt, Andy, 363 HyperText Markup Language (HTML) additional information, 23 defined, 359 HyperText Transfer Protocol (HTTP), 359 HyperText Transfer Protocol over Secure Socket Layer (HTTPS), 360 I id (identifying value), 360 id attribute form element, 86 text areas and text fields, 88 :id value (find method), 52, 71, 75 idempotent defined, 360 HTTP requests as, 62 identities, storing, 239 :if parameter (validation methods), 115 if statement, 296, 328 @import directive, 277, 284 :in parameter (validates_inclusion_of method), 111, 114 include method, 53 :include_blank parameter (date and time methods), 96 :include_seconds parameter (date and time methods), 97 index method adding logic to, 16 functionality, 69–70 RESTful controller example, 66 setting up variables, 19 index.html.erb file, 24 indexes, managing, 183 index_name_for_remove method, 184 inheritance (