Advanced Rails Recipes
Mike Clark and the Rails Commun i t y
The Pragmatic Bookshelf
Raleigh, North Carolina Dallas, Texas
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 designa tions 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. Howeve r, 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 s oftware 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 tran smit-
ted, in any form, or by any means, ele ctronic, 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.
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
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-Sear ch with Sphinx . . . . . . . . . . . . . . . . . 132
27. Solr-Power Your Search . . . . . . . . . . . . . . . . . . 140
Part V—Design Recipes 151
28. Freshen Up Your Models w i th 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