Advanced Rails Recipes
Total Page:16
File Type:pdf, Size:1020Kb
Prepared exclusively for Andrew Rudenko Advanced Rails Recipes Mike Clark and the Rails Community The Pragmatic Bookshelf Raleigh, North Carolina Dallas, Texas Prepared exclusively for Andrew Rudenko Many of the designations used by manufacturers and sellers to distinguish their prod- ucts are claimed as trademarks. Where those designations appear in this book, and The Pragmatic Programmers, LLC was aware of a trademark claim, the designations have been printed in initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer, Pragmatic Programming, Pragmatic Bookshelf and the linking g device are trademarks of The Pragmatic Programmers, LLC. Every precaution was taken in the preparation of this book. However, the publisher assumes no responsibility for errors or omissions, or for damages that may result from the use of information (including program listings) contained herein. Our Pragmatic courses, workshops, and other products can help you and your team create better software and have more fun. For more information, as well as the latest Pragmatic titles, please visit us at http://www.pragprog.com Copyright © 2008 Mike Clark. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmit- ted, in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior consent of the publisher. Printed in the United States of America. ISBN-10: 0-9787392-2-1 ISBN-13: 978-0-9787392-2-5 Printed on acid-free paper with 50% recycled, 15% post-consumer content. P1.0 printing, April 2008 Version: 2008-5-1 Prepared exclusively for Andrew Rudenko Contents 1 Introduction 8 1.1 What Makes a Good Recipe Book? ............ 8 1.2 What Makes This an Advanced Recipe Book? ...... 9 1.3 Who’s It For? ......................... 9 1.4 Who’s Talking? ....................... 10 1.5 What Version Do You Need? ................ 10 1.6 Resources .......................... 10 1.7 Acknowledgments ...................... 11 1.8 Tags and Thumb Tabs ................... 12 Part I—REST and Routes Recipes 13 1. Create a RESTful Resource ................ 14 2. Add Your Own RESTful Actions .............. 20 3. Nest Resources to Scope Access .............. 24 4. Toggle Attributes with Ajax ................ 30 5. Authenticate REST Clients ................. 33 6. Respond to Custom Formats ............... 39 7. Catch All 404s ........................ 43 Part II—Database Recipes 46 8. Add Foreign Key Constraints ............... 47 9. Write Custom Validations ................. 51 10. Take Advantage of Master/Slave Databases ....... 54 11. Siphon Off SQL Queries .................. 57 12. Use Fixtures for Canned Datasets ............ 61 Part III—User-Interface Recipes 64 13. Handle Multiple Models in One Form .......... 65 14. Replace In-View Raw JavaScript ............. 72 15. Validate Required Form Fields Inline ........... 74 16. Create Multistep Wizards ................. 78 Prepared exclusively for Andrew Rudenko CONTENTS 5 17. Customize Error Messages ................. 87 18. Upload Images with Thumbnails ............. 89 19. Decouple JavaScript with Low Pro ............ 99 20. Format Dates and Times .................. 106 21. Support an iPhone Interface ................ 109 Part IV—Search Recipes 115 22. Improve SEO with Dynamic Metatags .......... 116 23. Build a Site Map ....................... 119 24. Find Stuff (Quick and Dirty) ................ 124 25. Search Text with Ferret .................. 127 26. Ultra-Search with Sphinx ................. 132 27. Solr-Power Your Search .................. 140 Part V—Design Recipes 151 28. Freshen Up Your Models with Scope ........... 152 29. Create Meaningful Relationships Through Proxies . 157 30. Keep Forms DRY and Flexible ............... 160 31. Prevent Train Wrecks .................... 166 32. Simplify Controllers with a Presenter ........... 169 Part VI—Integration Recipes 174 33. Process Credit Card Payments .............. 175 34. Play Nice with Facebook .................. 187 35. Mark Locations on a Google Map ............. 189 36. Tunnel Back to Your Application ............. 196 Part VII—Console Snacks 200 37. Write Console Methods ................... 201 38. Log to the Console ...................... 203 39. Play in the Sandbox ..................... 205 40. Access Helpers ........................ 206 41. Shortcut the Console .................... 207 Part VIII—Asynchronous-Processing Recipes 209 42. Send Lightweight Messages ................ 210 43. Off-Load Long-Running Tasks to BackgrounDRb . 214 44. Process Asynchronous, State-Based Workflows . 222 Report erratum Prepared exclusively for Andrew Rudenko this copy is (P1.0 printing, April 2008) CONTENTS 6 Part IX—E-mail Recipes 228 45. Validate E-mail Addresses ................. 229 46. Receive E-mail Reliably via POP or IMAP ......... 232 47. Send E-mail via Gmail ................... 238 48. Keep E-mail Addresses Up-to-Date ............ 239 Part X—Testing Recipes 244 49. Maintain Fixtures Without Frustration .......... 245 50. Describe Behavior from the Outside In with RSpec . 249 51. Test First with Shoulda ................... 256 52. Write Domain-Specific RSpec Matchers ......... 261 53. Write Custom Testing Tasks ................ 265 54. Test JavaScript with Selenium .............. 267 55. Mock Models with FlexMock ................ 272 56. Track Test Coverage with rcov ............... 276 57. Automatically Validate HTML ............... 279 58. Mock with a Safety Net ................... 282 59. Drive a Feature Top-Down with Integration Tests . 284 Part XI—Performance and Scalability Recipes 288 60. Cache Data Easily ...................... 289 61. Look Up Constant Data Efficiently ............ 293 62. Profile in the Browser .................... 299 63. Cache Up with the Big Guys ................ 303 64. Dynamically Update Cached Pages ............ 310 65. Use DTrace for Profiling .................. 313 Part XII—Security Recipes 320 66. Constrain Access to Sensitive Data ............ 321 67. Encrypt Sensitive Data ................... 323 68. Flip On SSL ......................... 329 Part XIII—Deployment and Capistrano Recipes 333 69. Upload Custom Maintenance Pages ........... 334 70. Generate Custom Error (404 and 500) Pages . 338 71. Write Config Files on the Fly ................ 342 72. Create New Environments ................. 344 73. Run Multistage Deployments ............... 347 74. Safeguard the Launch Codes ............... 350 Report erratum Prepared exclusively for Andrew Rudenko this copy is (P1.0 printing, April 2008) CONTENTS 7 75. Automate Periodic Tasks .................. 351 76. Preserve Files Between Deployments ........... 356 77. Segregate Page Cache Storage with Nginx ........ 358 78. Load Balance Around Your Mongrels’ Health . 362 79. Respond to Remote Capistrano Prompts ......... 368 80. Monitor (and Repair) Processes with Monit ....... 370 Part XIV—Big-Picture Recipes 373 81. Manage Plug-in Versions .................. 374 82. Fail Early ........................... 377 83. Give Users Their Own Subdomain ............ 379 84. Customize and Analyze Log Files ............. 384 A Bibliography 389 Index 390 Report erratum Prepared exclusively for Andrew Rudenko this copy is (P1.0 printing, April 2008) Chapter 1 Introduction 1.1 What Makes a Good Recipe Book? If you and I were building a Rails application together and you leaned over and asked me, “Hey, how do I upload a file to S3 in the background without tying up the web request?” the last thing you want to hear is the theory of networking and messaging systems. Instead, I’d just say, “Push the filename on a message queue, write a Rake task that pops messages off the queue in a loop, and use the S3 library to upload the file.” And then we’d sit together and code it up. That’s what this recipe book is all about, except you’re sitting next to more than fifty “great chefs” in the Rails community. These folks know how to make (and teach you how to make) things to help your Rails application really shine. All these recipes are extracted directly from their work on real-world projects. It’s all about skipping the trial and error and jumping straight to a good solution that works on your first try. Sometimes it’s even about making things you never imagined you could make. Good recipe books also teach you techniques and describe why certain things work and others don’t. Sometimes they even teach you about new tools. But they teach these skills within the context and with the end goal of making something—not just to teach them. After working through these recipes, you should walk away with a new level of Rails understanding along with an impressive list of success- fully implemented new features. Prepared exclusively for Andrew Rudenko WHAT MAKES THIS AN ADVANCED RECIPE BOOK? 9 1.2 What Makes This an Advanced Recipe Book? Sushi is a treat for the eyes, as much as it’s a treat for my taste buds. The sushi chefs behind the bar of my favorite local spot take great pride in making not only delicious dishes but exquisite-looking ones as well. And they seem to derive a great deal of satisfaction when their creations are enjoyed by me—a hungry programmer. Their goal isn’t to have me stumble away from the table stuffed to the gills but instead to have me leave pleasantly satisfied by the entire experience. My goal for this book is similar. I don’t want to load you up with heaps of cryptic, overly clever code that sits heavy in your application. That’s not what being advanced is about. It’s actually the