Tải bản đầy đủ (.pdf) (50 trang)

Ruby for Rails phần 1 pps

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (4.24 MB, 50 trang )

Ruby for Rails

Ruby for Rails
RUBY TECHNIQUES FOR RAILS DEVELOPERS
DAVID A. BLACK
MANNING
Greenwich
(74° w. long.)
For online information and ordering of this and other Manning books, please visit
www.manning.com. The publisher offers discounts on this book when ordered in
quantity. For more information, please contact:
Special Sales Department
Manning Publications Co.
209 Bruce Park Avenue Fax:(203) 661-9018
Greenwich, CT 06830 email:
©2006 Manning Publications. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
in any form or by means electronic, mechanical, photocopying, or otherwise, without
prior written permission of the publisher.
Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial
caps or all caps.
Recognizing the importance of preserving what has been written, it is Manning’s policy to have
the books they publish printed on acid-free paper, and we exert our best efforts to that end.
Manning Publications Co. Copyeditor: Liz Welch
209 Bruce Park Avenue Typesetter: Gordan Salinovic
Greenwich, CT 06830 Cover designer: Leslie Haimes
ISBN 1932394699
Printed in the United States of America


12345678910–VHG–10 090807 06
for n in nephews + nieces

which is to say: Annie, David, Elizabeth, Rebecca, and Robert,
with all my love. You’re all absolutely amazing, and I adore you.


vii
PART ITHE RUBY/RAILS LANDSCAPE 1
1 ■ How Ruby works 3
2
■ How Rails works 33
3
■ Ruby-informed Rails development 67
PART II RUBY BUILDING BLOCKS 93
4 ■ Objects and variables 95
5
■ Organizing objects with classes 121
6
■ Modules and program organization 154
7
■ The default object (self) and scope 177
8
■ Control flow techniques 206
PART III BUILT-IN CLASSES AND MODULES 231
9 ■ Built-in essentials 233
10
■ Scalar objects 257
11
■ Collections, containers, and enumerability 277

brief contents
viii BRIEF CONTENTS
12 ■ Regular expressionsand regexp-based string operations 312
13
■ Ruby dynamics 337
PART IV RAILS THROUGH RUBY,
RRRRRRRRIRUBY THROUGH RAILS 369
14 ■ (Re)modeling the R4RMusic application universe 371
15
■ Programmatically enhancing ActiveRecord models 392
16
■ Enhancing the controllers and views 422
17
■ Techniques for exploring the Rails source code 455
appendix
■ Ruby and Rails installation and resources 471
ix
contents
foreword xix
preface xxi
acknowledgments xxiii
about this book xxvi
about the cover illustration xxxii
PART 1THE RUBY/RAILS LANDSCAPE 1
1
How Ruby works 3
1.1 The mechanics of writing a Ruby program 4
Getting the preliminaries in place 5

A Ruby literacy bootstrap

guide 5

A brief introduction to method calls and Ruby objects 7
Writing and saving a sample program 8

Feeding the program to
Ruby 9

Keyboard and file input 11

One program,
multiple files 14
1.2 Techniques of interpreter invocation 15
Command-line switches 16

A closer look at
interactive Ruby interpretation with irb 20
1.3 Ruby extensions and programming libraries 21
Using standard extensions and libraries 21

Using
C extensions 22

Writing extensions and libraries 23
x CONTENTS
1.4 Anatomy of the Ruby programming environment 24
The layout of the Ruby source code 24

Navigating the
Ruby installation 25


Important standard Ruby tools
and applications 27
1.5 Summary 31
2
How Rails works 33
2.1 Inside the Rails framework 34
A framework user’s–eye view of application development 35
Introducing the MVC framework concept 36
Meet MVC in the (virtual) flesh 37
2.2 Analyzing Rails’ implementation of MVC 38
2.3 A Rails application walk-through 41
Introducing R4RMusic, the music-store application 42
Modeling the first iteration of the music-store domain 43
Identifying and programming the actions 50

Designing
the views 53

Connecting to the application 58
2.4 Tracing the lifecycle of a Rails run 59
Stage 1: server to dispatcher 61

Stage 2: dispatcher
to controller 62

Stage 3: performance of a controller
action 62

Stage 4: the fulfillment of the view 65

2.5 Summary 65
3
Ruby-informed Rails development 67
3.1 A first crack at knowing what your code does 69
Seeing Rails as a domain-specific language 70

Writing program
code with a configuration flavor 73

YAML and configuration
that’s actually programming 75
3.2 Starting to use Ruby to do more in your code 77
Adding functionality to a controller 79

Deploying the Rails helper
files 80

Adding functionality to models 82
3.3 Accomplishing application-related skills and tasks 85
Converting legacy data to ActiveRecord 85
The irb-based Rails application console 89
3.4 Summary 90
CONTENTS xi
PART 2RUBY BUILDING BLOCKS 93
4
Objects and variables 95
4.1 From “things” to objects 96
Introducing object-oriented programming 97

I, object! 98

Modeling objects more closely: the behavior of a ticket 103
4.2 The innate behaviors of an object 108
Identifying objects uniquely with the object_id method 109
Querying an object’s abilities with the respond_to? method 110
Sending messages to objects with the send method 111
4.3 Required, optional, and default-valued arguments 112
Required and optional arguments 112

Default values for
arguments 113

Order of arguments 114
4.4 Local variables and variable assignment 115
Variable assignment in depth 117

Local variables
and the things that look like them 119
4.5 Summary 120
5
Organizing objects with classes 121
5.1 Classes and instances 122
A first class 123

Instance variables and object state 126
5.2 Setter methods 130
The equal sign (=) in method names 131
ActiveRecord properties and other =-method applications 133
5.3 Attributes and the attr_* method family 136
Automating the creation of attribute handlers 137


Two (getter/
setter) for one 138

Summary of attr_* methods 139
5.4 Class methods and the Class class 140
Classes are objects too! 140

When, and why, to write a class
method 141

Class methods vs. instance methods, clarified 143
The Class class and Class.new 144
5.5 Constants up close 145
Basic usage of constants 145

Reassigning vs.
modifying constants 146
xii CONTENTS
5.6 Inheritance 148
Inheritance and Rails engineering 149

Nature vs.
nurture in Ruby objects 151
5.7 Summary 153
6
Modules and program organization 154
6.1 Basics of module creation and use 155
A module encapsulating “stack-like-ness” 157

Mixing a module

into a class 158

Leveraging the module further 160
6.2 Modules, classes, and method lookup 163
Illustrating the basics of method lookup 163

Defining the same
method more than once 166

Going up the method search path
with super 168
6.3 Class/module design and naming 170
Mix-ins and/or inheritance 171

Modular organization
in Rails source and boilerplate code 173
6.4 Summary 176
7
The default object (self) and scope 177
7.1 Understanding self, the current/default object 179
Who gets to be self, and where 179

Self as default receiver of
messages 184

Instance variables and self 186
7.2 Determining scope 188
Global scope and global variables 188

Local scope 191

Scope and resolution of constants 194
7.3 Deploying method access rules 197
Private methods 197

Private methods as ActionController
access protection 199

Protected methods 201
7.4 Writing and using top-level methods 203
Defining a top-level method 203

Predefined (built-in)
top-level methods 204
7.5 Summary 205
8
Control flow techniques 206
8.1 Conditional code execution 207
The if keyword and friends 208

Conditional modifiers 211
Case statements 211
CONTENTS xiii
8.2 Repeating actions with loops 215
Unconditional looping with the loop method 215
Conditional looping with the while and until keywords 216
Looping based on a list of values 218
8.3 Code blocks, iterators, and the yield keyword 219
The basics of yielding to a block 219

Performing multiple

iterations 222

Using different code blocks 223
More about for 223
8.4 Error handling and exceptions 225
Raising and rescuing exceptions 225

Raising exceptions
explicitly 227

Creating your own exception classes 228
8.5 Summary 230
PART 3BUILT-IN CLASSES AND MODULES 231
9
Built-in essentials 233
9.1 Ruby’s literal constructors 234
9.2 Recurrent syntactic sugar 236
Special treatment of += 237
9.3 Methods that change their receivers (or don’t) 238
Receiver-changing basics 239

bang (!) methods 240
Specialized and extended receiver-changing in
ActiveRecord objects 241
9.4 Built-in and custom to_* (conversion) methods 242
Writing your own to_* methods 243
9.5 Iterators reiterated 244
9.6 Boolean states, Boolean objects, and nil 245
True and false as states 246


true and false as objects 248
The special object nil 249
9.7 Comparing two objects 251
Equality tests 251

Comparisons and the Comparable module 252
9.8 Listing an object’s methods 253
Generating filtered and selective method lists 254
9.9 Summary 255
xiv CONTENTS
10
Scalar objects 257
10.1 Working with strings 258
String basics 258

String operations 260
Comparing strings 265
10.2 Symbols and their uses 267
Key differences between symbols and strings 267
Rails-style method arguments, revisited 268
10.3 Numerical objects 270
Numerical classes 270

Performing arithmetic operations 271
10.4 Times and dates 272
10.5 Summary 275
11
Collections, containers, and enumerability 277
11.1 Arrays and hashes compared 278
11.2 Using arrays 279

Creating a new array 279

Inserting, retrieving, and removing array
elements 280

Combining arrays with other arrays 283

Array
transformations 285

Array iteration, filtering, and querying 286
Ruby lessons from ActiveRecord collections 289
11.3 Hashes 292
Creating a new hash 293

Inserting, retrieving, and removing hash
pairs 294

Combining hashes with other hashes 296

Hash
transformations 297

Hash iteration, filtering, and querying 298
Hashes in Ruby and Rails method calls 301
11.4 Collections central: the Enumerable module 303
Gaining enumerability through each 304
Strings as Enumerables 306
11.5 Sorting collections 307
Sorting and the Comparable module 309

Defining sort order in a block 310
11.6 Summary 311
12
Regular expressionsand regexp-basedstring operations 312
12.1 What are regular expressions? 313
A word to the regex-wise 314

A further word to everyone 314
CONTENTS xv
12.2 Writing regular expressions 314
The regular expression literal constructor 315
Building a pattern 316
12.3 More on matching and MatchData 319
Capturing submatches with parentheses 319
Match success and failure 321
12.4 Further regular expression techniques 323
Quantifiers and greediness 323

Anchors and lookahead
assertions 326

Modifiers 328

Converting strings and
regular expressions to each other 329
12.5 Common methods that use regular expressions 331
String#scan 332

String#split 332


sub/sub! and
gsub/gsub! 333

grep 334
12.6 Summary 335
13
Ruby dynamics 337
13.1 The position and role of singleton classes 338
Where the singleton methods live 339

Examining and modifying a
singleton class directly 340

Singleton classes on the method lookup
path 342

Class methods in (even more) depth 345
13.2 The eval family of methods 347
eval 347

instance_eval 349

The most useful
eval: class_eval (a.k.a. module_eval) 349
13.3 Callable objects 351
Proc objects 351

Creating anonymous functions with the
lambda keyword 355


Code blocks, revisited 356

Methods
as objects 357
13.4 Callbacks and hooks 359
Intercepting unrecognized messages with method_missing 360
Trapping include operations with Module#included 361
Intercepting inheritance with Class#inherited 363
Module#const_missing 365
13.5 Overriding and adding to core functionality 365
A cautionary tale 366
13.6 Summary 367
xvi CONTENTS
PART 4RAILS THROUGH RUBY,
UUUUUUURUBY THROUGH RAILS 369
14
(Re)modeling the R4RMusic application universe 371
14.1 Tracking the capabilities of an
ActiveRecord model instance 372
An overview of model instance capabilities 373
Inherited and automatic ActiveRecord model behaviors 374
Semi-automatic behaviors via associations 378
14.2 Advancing the domain model 380
Abstracting and adding models (publisher and edition) 380
The instruments model and many-to-many relations 382
Modeling for use: customer and order 386
14.3 Summary 390
15
Programmatically enhancing ActiveRecord models 392
15.1 Soft vs. hard model enhancement 393

An example of model-enhancement contrast 394
15.2 Soft programmatic extension of models 396
Honing the Work model through soft enhancements 398

Modeling
the customer’s business 399

Fleshing out the Composer 401
Ruby vs. SQL in the development of soft enhancements 401
15.3 Hard programmatic enhancement of model
functionality 404
Prettification of string properties 404

Calculating a work’s
period 409

The remaining business of the Customer 414
15.4 Extending model functionality with class methods 419
Soft and hard class methods 419
15.5 Summary 421
16
Enhancing the controllers and views 422
16.1 Defining helper methods for view templates 424
Organizing and accessing custom helper methods 425
The custom helper methods for R4RMusic 427
CONTENTS xvii
16.2 Coding and deploying partial view templates 429
Anatomy of a master template 429

Using partials

in the welcome view template 430
16.3 Updating the main controller 436
The new face of the welcome action 436
16.4 Incorporating customer signup and login 438
The login and signup partial templates 438

Logging
in and saving the session state 439

Gate-keeping the
actions with before_filter 441

Implementing a signing-up
facility 444

Scripting customer logout 445
16.5 Processing customer orders 446
The view_cart action and template 446

Viewing and
buying an edition 448

Defining the add_to_cart
action 449

Completing the order(s) 449
16.6 Personalizing the page via dynamic code 450
From rankings to favorites 450

The favorites

feature in action 452
16.7 Summary 454
17
Techniques for exploring the Rails source code 455
17.1 Exploratory technique 1: panning for info 456
Sample info panning: belongs_to 457
17.2 Exploratory technique 2: shadowing Ruby 458
Choosing a starting point 458

Choose among forks in the
road intelligently 459

On the trail of belongs_to 460
A transliteration of belongs_to 463
17.3 Exploratory technique 3: consulting the
documentation 464
A roadmap of the online Rails API documentation 466
17.4 Summary 469
appendix Ruby and Rails installation and resources 471
index 477

xix
foreword
I can’t learn a language for the sake of it. I need to have a concrete desire to do some-
thing with it—to solve a problem or a task, to create something of value That’s how
I got into Ruby around the summer of 2003. I wanted to build a Web application and
decided this was the perfect opportunity to learn Ruby. That Web application was
Basecamp, which eventually served as the point of extraction for Rails.
Coming from PHP and Java, I remember how many of Ruby’s most wonderful
features seemed odd at first. “What is it exactly that makes blocks so special?” I

thought. “They’re just convenience for writing a line of code at the beginning and
the end.” Little did I know As I started using Ruby and extracting Rails, I quickly
wised up. Ruby is such an incredibly rich and expressive language that it’s hard to
appreciate its beauty by simply relating it to past experiences with other languages.
To create Basecamp, I needed to live and breathe Ruby. And when I did, I kept
finding aspects of the language that were exactly what I needed for the situation
at hand. Tasks that would have made my eyes roll in PHP or Java made my smile
light up as Ruby time and time again showed that programming could be simple,
fun, and outright beautiful.
As I was learning the language, I often consulted the ruby-talk mailing list. One
voice in particular seemed to know Ruby well and appeared to have the ambition
as well as the ability to help others understand it more fully. That voice belonged
to David A. Black, the author of this book.
xx FOREWORD
David clearly has an encyclopedic knowledge of Ruby. Not only does he under-
stand how to use it, but he can also explain why things are the way they are. He
connects the dots and allows you to see the bigger picture, providing the missing
piece that turns puzzle into picture. I couldn’t imagine a better person to write
Ruby for Rails. It’s a great honor to have the man who taught me so much about
Ruby now help others understand the language for use with my framework.
This is the book that everyone coming from another language to Rails should
have. To fully realize the potential of Rails, it’s crucial that you take the time to
fully understand Ruby—and with Ruby for Rails David has provided just what you
need to help you achieve that goal.


DAVID HEINEMEIER HANSSON
Creator of Ruby on Rails
Partner at 37signals
xxi

preface
When the editors at Manning asked me whether I thought the time was ripe for a
new Ruby book, and if so, what it should be about and who should write it, I
answered:
“Yes A Ruby language book purpose-written for Rails practitioners Me.”
They agreed.
I warmly welcomed the opportunity. I’d been thinking along “Ruby for Rails”
lines since I started using the Ruby on Rails framework in the Fall of 2004 (which,
by the way, makes me an almost-early adopter). Rails had been first released that
summer, and I learned about it from the presentation by David Heinemeier Hans-
son, the creator of Rails, at the 2004 International Ruby Conference.
Ruby for Rails sounds like it might mean “…as opposed to regular Ruby,” a tool
for dividing Ruby users into Rails and non-Rails camps. I saw it as the opposite:
real Ruby, regular Ruby, on its own terms, but studied primarily because of what it
can do for Rails developers. I was in a good position to understand the potential
of this approach: I’d been programming in Ruby for almost four years before I
started using Rails; and when I did start using it, I quickly gained a view of how a
deeper knowledge of Ruby could help Rails programmers achieve their goals.
An alarm went off in my head, therefore, when I saw how many budding Rails
developers were asking themselves whether it was necessary to learn Ruby in order
to use Rails. The fact that this question was the subject of disagreement and
debate surprised me. And it suggested a couple of points.
xxii PREFACE
First, there was clearly room for education about the basics: that Rails is written
in Ruby, and Rails applications are written in Ruby, so if you’re writing Rails appli-
cations, you’ve already decided to use Ruby. Second, I could see the beginnings of an
inadvertent, self-imposed quarantine on the part of these Rails developers (who
were perfectly well-intentioned, but not in possession of the full picture) and I saw
that something could and should be done about it. People were talking themselves
into living under a glass ceiling, where they could get Rails applications to run and

do some reasonably adroit things with Rails techniques and idioms, but where they
were denying themselves the chance to deploy the full power of Ruby—the lan-
guage which they were in fact already using. That needed to be addressed.
I also noticed a large number of questions in various forums (and various
forms) along the lines of “I know I’m supposed to write
belongs_to :customer,
but what is that?” A number of Rails users told me that they were able to get appli-
cations up and running by imitating and adapting lines of code from other appli-
cations, but they were finding it unsatisfying because they didn’t feel they knew
what was going on. The fact that people were having trouble understanding Rails
code in Ruby terms meant that they were not in a position to go to the next level:
using the full power of Ruby to enhance and extend the functionality of their
Rails applications.
It occurred to me that a Rails-centric Ruby language tutorial could serve the
dual roles of, first, explaining to Rails developers who didn’t yet see that Ruby and
Rails don’t reside in separate silos but, rather, enjoy a parent/child technology rela-
tionship with extremely open lines of communication; and, second, smashing the
glass ceiling that separated Rails people from using Ruby more effectively.
As the book project got under way, my goal became to explain that the learn-
ing of Ruby by a “Rails person” is an entirely additive, win-win proposition. It
doesn’t mean Rails has some deficiency that has to be compensated for by know-
ing a foreign technology. Rather, Rails has a tremendous strength—the strength
of having been written in an elegant, concise, very approachable programming
language—the implications of which for day-to-day Rails programming are impor-
tant and are a pleasure to explore.
Thus Ruby for Rails: a reaffirmation and explanation of the way things stand,
and have always stood, between the language and the framework, and an invita-
tion to shatter that glass ceiling.
xxiii
acknowledgments

This book has benefited from support of many kinds from many quarters.
At Manning Publications, assistant acquisitions editor Megan Yockey and pub-
lisher’s assistant Blaise Bace saw me ably and enthusiastically through the proposal
and contract phases of the project. I worked initially, and productively, with devel-
opment editor Doug Bennett; subsequently, for reasons of scheduling and logis-
tics, my project was reassigned to development editor Lianna Wlasiuk, who
worked with me in an intense, sustained way through the writing of the book, cou-
pling a marvelous collegiality with a gentle but firm refusal to settle for anything
other than a strong, polished product.
Review editor Karen Tegtmeyer sought, and found, specialists from both the
Ruby and Rails spheres to review the manuscript at the various prescribed phases
of partial completion—a process I like to think I became less surly about, the
more evidence I saw of how materially helpful it could be. Book designer Dottie
Marsico worked with me on the illustrations; I have Dottie to thank for my new-
found OpenOffice Draw skills as well as for her encouragement and quick respon-
siveness to questions and concerns.
As the book moved through the latter stages of preparation and into the pro-
duction stages, I had the indispensable support and help of production director
Mary Piergies, who coordinated the geographically far-flung process in a way that
brought it unity and momentum. To copy editor Tiffany Taylor I can pay no
greater tribute than to say that I quickly got into the habit of telling OpenOffice
to hide the history of changes in the document and only show me the text as it
xxiv ACKNOWLEDGMENTS
appeared after Tiffany had worked on it. I have no doubt, moreover, that several
trees owe their lives to Tiffany’s ability to trim away excess verbiage.
Technical proofreader Bruce Williams made numerous suggestions and cor-
rections which, I can assure readers, have measurably improved the readability of
the code samples as well as the text. There’s nothing like a keen second set of
eyes, and a second tester, to convince one, once and for all, that one really must
not make little changes to code after cutting-and-pasting it in….

I worked with three proofreaders. Elizabeth R. Martin, who kindly stepped in to
tide the project over during a scheduling gap, brought a sharp eye to bear on the
book’s first chapters. The balance of the manuscript was proofread by Elizabeth
Welch, on whom I have relied not only for error-catching but for constant consul-
tation in discretionary matters of typographical consistency and style. Barbara
Mirecki gave the manuscript a close, skillful final read. Katie Tennant brought a
professional’s skill and care to bear on my well-intentioned, but inevitably imper-
fect, indexing efforts. Typesetter Gordan Salinovic has worked diligently and
responsively with us to ensure a consistent, reader-friendly look.
Manning webmaster Iain Shigeoka worked behind the scenes to keep the infor-
mation flow going among the various members of the production team and me,
and quickly stepped up to help on the few occasions when glitches cropped up.
On the marketing side, Manning’s sales and marketing chief Ron Tomich and
marketing director Helen Trimes have kept the book before the Ruby/Rails pub-
lic eye and have sought my input and collaboration throughout the process. As
much as the popularity of Ruby and Rails can help, there’s no such thing as a
book that promotes itself, and Helen and Ron have been anything but compla-
cent in getting the word out.
Last but by no means least among the members of the Manning team to whom
I offer my thanks is publisher Marjan Bace, who saw the viability of this project
quickly, supported it unreservedly, and piloted it skillfully through many ups and
a sprinkling of downs. Both the book and I benefited from Marjan’s availability,
attentiveness, and mastery of the contours of the publication landscape.
I’d like to thank the reviewers of the original book proposal and all of the out-
side readers who participated in the various partial-manuscript review cycles. Many
of the comments and criticisms of the latter group had more of an impact on the
book than they themselves might have anticipated. Thanks go to Anjan Bacchu,
Christopher Bailey, Jamis Buck, Stuart Caborn, Tom Copeland, Ryan Cox, Jeff
Cunningham, Pat Dennis, Mark Eagle, Sasa Ebach, Shaun Fanning, Hal Fulton,
Benjamin Gorlick, Erik Hatcher, David Heinemeier Hansson, Jack Herrington,

Bob Hutchison, Duane Johnson, Albert Koscielny, Robert McGovern, Andrew

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×