forked from mhartl/rails_tutorial_translation_2nd_ed
-
Notifications
You must be signed in to change notification settings - Fork 1
/
rails-flavored-ruby.html
1680 lines (1118 loc) · 167 KB
/
rails-flavored-ruby.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<title>rails-flavored-ruby</title>
<link rel="stylesheet" href="pygments.css" type="text/css" />
<link rel="stylesheet" href="polytexnic.css" type="text/css" />
</head>
<body>
<div id="book">
<h1 class="title">Ruby on Rails Tutorial </h1>
<h1 class="subtitle"> Learn Web Development with Rails</h1>
<h2 class="author">Michael Hartl</h2>
<h2 class="contents">Contents</h2>
<div id="table_of_contents"><ol><li class="chapter"><a href="beginning.html#top"><span class="number">Chapter 1</span> From zero to deploy</a></li><li><ol><li class="section"><a href="beginning.html#sec-introduction"><span class="number">1.1</span> Introduction</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-comments_for_various_readers"><span class="number">1.1.1</span> Comments for various readers</a></li><li class="subsection"><a href="beginning.html#sec-1_1_2"><span class="number">1.1.2</span> “Scaling” Rails</a></li><li class="subsection"><a href="beginning.html#sec-conventions"><span class="number">1.1.3</span> Conventions in this book</a></li></ol></li><li class="section"><a href="beginning.html#sec-up_and_running"><span class="number">1.2</span> Up and running</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-development_tools"><span class="number">1.2.1</span> Development environments</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-1_2_1_1">IDEs</a></li><li class="subsubsection"><a href="beginning.html#sec-1_2_1_2">Text editors and command lines</a></li><li class="subsubsection"><a href="beginning.html#sec-1_2_1_3">Browsers</a></li><li class="subsubsection"><a href="beginning.html#sec-1_2_1_4">A note about tools</a></li></ol></li><li class="subsection"><a href="beginning.html#sec-rubygems"><span class="number">1.2.2</span> Ruby, RubyGems, Rails, and Git</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-rails_installer_windows">Rails Installer (Windows)</a></li><li class="subsubsection"><a href="beginning.html#sec-install_git">Install Git</a></li><li class="subsubsection"><a href="beginning.html#sec-install_ruby">Install Ruby</a></li><li class="subsubsection"><a href="beginning.html#sec-install_rubygems">Install RubyGems</a></li><li class="subsubsection"><a href="beginning.html#sec-install_rails">Install Rails</a></li></ol></li><li class="subsection"><a href="beginning.html#sec-the_first_application"><span class="number">1.2.3</span> The first application</a></li><li class="subsection"><a href="beginning.html#sec-bundler"><span class="number">1.2.4</span> Bundler</a></li><li class="subsection"><a href="beginning.html#sec-rails_server"><span class="number">1.2.5</span> <tt>rails server</tt></a></li><li class="subsection"><a href="beginning.html#sec-mvc"><span class="number">1.2.6</span> Model-view-controller (MVC)</a></li></ol></li><li class="section"><a href="beginning.html#sec-version_control"><span class="number">1.3</span> Version control with Git</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-git_setup"><span class="number">1.3.1</span> Installation and setup</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-1_3_1_1">First-time system setup</a></li><li class="subsubsection"><a href="beginning.html#sec-1_3_1_2">First-time repository setup</a></li></ol></li><li class="subsection"><a href="beginning.html#sec-adding_and_committing"><span class="number">1.3.2</span> Adding and committing</a></li><li class="subsection"><a href="beginning.html#sec-1_3_3"><span class="number">1.3.3</span> What good does Git do you?</a></li><li class="subsection"><a href="beginning.html#sec-github"><span class="number">1.3.4</span> GitHub</a></li><li class="subsection"><a href="beginning.html#sec-git_commands"><span class="number">1.3.5</span> Branch, edit, commit, merge</a></li><li><ol><li class="subsubsection"><a href="beginning.html#sec-git_branch">Branch</a></li><li class="subsubsection"><a href="beginning.html#sec-git_edit">Edit</a></li><li class="subsubsection"><a href="beginning.html#sec-git_commit">Commit</a></li><li class="subsubsection"><a href="beginning.html#sec-git_merge">Merge</a></li><li class="subsubsection"><a href="beginning.html#sec-git_push">Push</a></li></ol></li></ol></li><li class="section"><a href="beginning.html#sec-deploying"><span class="number">1.4</span> Deploying</a></li><li><ol><li class="subsection"><a href="beginning.html#sec-heroku_setup"><span class="number">1.4.1</span> Heroku setup</a></li><li class="subsection"><a href="beginning.html#sec-heroku_step_one"><span class="number">1.4.2</span> Heroku deployment, step one</a></li><li class="subsection"><a href="beginning.html#sec-1_4_3"><span class="number">1.4.3</span> Heroku deployment, step two</a></li><li class="subsection"><a href="beginning.html#sec-heroku_commands"><span class="number">1.4.4</span> Heroku commands</a></li></ol></li><li class="section"><a href="beginning.html#sec-beginning_conclusion"><span class="number">1.5</span> Conclusion</a></li></ol></li><li class="chapter"><a href="a-demo-app.html#top"><span class="number">Chapter 2</span> A demo app</a></li><li><ol><li class="section"><a href="a-demo-app.html#sec-planning_the_application"><span class="number">2.1</span> Planning the application</a></li><li><ol><li class="subsection"><a href="a-demo-app.html#sec-modeling_demo_users"><span class="number">2.1.1</span> Modeling demo users</a></li><li class="subsection"><a href="a-demo-app.html#sec-modeling_demo_microposts"><span class="number">2.1.2</span> Modeling demo microposts</a></li></ol></li><li class="section"><a href="a-demo-app.html#sec-demo_users_resource"><span class="number">2.2</span> The Users resource</a></li><li><ol><li class="subsection"><a href="a-demo-app.html#sec-a_user_tour"><span class="number">2.2.1</span> A user tour</a></li><li class="subsection"><a href="a-demo-app.html#sec-mvc_in_action"><span class="number">2.2.2</span> MVC in action</a></li><li class="subsection"><a href="a-demo-app.html#sec-weaknesses_of_this_users_resource"><span class="number">2.2.3</span> Weaknesses of this Users resource</a></li></ol></li><li class="section"><a href="a-demo-app.html#sec-microposts_resource"><span class="number">2.3</span> The Microposts resource</a></li><li><ol><li class="subsection"><a href="a-demo-app.html#sec-a_micropost_microtour"><span class="number">2.3.1</span> A micropost microtour</a></li><li class="subsection"><a href="a-demo-app.html#sec-putting_the_micro_in_microposts"><span class="number">2.3.2</span> Putting the <em>micro</em> in microposts</a></li><li class="subsection"><a href="a-demo-app.html#sec-demo_user_has_many_microposts"><span class="number">2.3.3</span> A user <tt>has_many</tt> microposts</a></li><li class="subsection"><a href="a-demo-app.html#sec-inheritance_hierarchies"><span class="number">2.3.4</span> Inheritance hierarchies</a></li><li class="subsection"><a href="a-demo-app.html#sec-deploying_the_demo_app"><span class="number">2.3.5</span> Deploying the demo app</a></li></ol></li><li class="section"><a href="a-demo-app.html#sec-2_4"><span class="number">2.4</span> Conclusion</a></li></ol></li><li class="chapter"><a href="static-pages.html#top"><span class="number">Chapter 3</span> Mostly static pages</a></li><li><ol><li class="section"><a href="static-pages.html#sec-static_pages"><span class="number">3.1</span> Static pages</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-truly_static_pages"><span class="number">3.1.1</span> Truly static pages</a></li><li class="subsection"><a href="static-pages.html#sec-static_pages_with_rails"><span class="number">3.1.2</span> Static pages with Rails</a></li></ol></li><li class="section"><a href="static-pages.html#sec-first_tests"><span class="number">3.2</span> Our first tests</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-TDD"><span class="number">3.2.1</span> Test-driven development</a></li><li class="subsection"><a href="static-pages.html#sec-adding_a_page"><span class="number">3.2.2</span> Adding a page</a></li><li><ol><li class="subsubsection"><a href="static-pages.html#sec-red">Red</a></li><li class="subsubsection"><a href="static-pages.html#sec-green">Green</a></li><li class="subsubsection"><a href="static-pages.html#sec-refactor">Refactor</a></li></ol></li></ol></li><li class="section"><a href="static-pages.html#sec-slightly_dynamic_pages"><span class="number">3.3</span> Slightly dynamic pages</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-testing_a_title_change"><span class="number">3.3.1</span> Testing a title change</a></li><li class="subsection"><a href="static-pages.html#sec-passing_title_tests"><span class="number">3.3.2</span> Passing title tests</a></li><li class="subsection"><a href="static-pages.html#sec-embedded_ruby"><span class="number">3.3.3</span> Embedded Ruby</a></li><li class="subsection"><a href="static-pages.html#sec-layouts"><span class="number">3.3.4</span> Eliminating duplication with layouts</a></li></ol></li><li class="section"><a href="static-pages.html#sec-static_pages_conclusion"><span class="number">3.4</span> Conclusion</a></li><li class="section"><a href="static-pages.html#sec-static_pages_exercises"><span class="number">3.5</span> Exercises</a></li><li class="section"><a href="static-pages.html#sec-advanced_setup"><span class="number">3.6</span> Advanced setup</a></li><li><ol><li class="subsection"><a href="static-pages.html#sec-eliminating_bundle_exec"><span class="number">3.6.1</span> Eliminating <tt>bundle exec</tt></a></li><li><ol><li class="subsubsection"><a href="static-pages.html#sec-rvm_bundler_integration">RVM Bundler integration</a></li><li class="subsubsection"><a href="static-pages.html#sec-binstubs">binstubs</a></li></ol></li><li class="subsection"><a href="static-pages.html#sec-guard"><span class="number">3.6.2</span> Automated tests with Guard</a></li><li class="subsection"><a href="static-pages.html#sec-spork"><span class="number">3.6.3</span> Speeding up tests with Spork</a></li><li><ol><li class="subsubsection"><a href="static-pages.html#sec-spork_and_guard">Guard with Spork</a></li></ol></li><li class="subsection"><a href="static-pages.html#sec-tests_inside_sublime_text"><span class="number">3.6.4</span> Tests inside Sublime Text</a></li></ol></li></ol></li><li class="chapter"><a href="rails-flavored-ruby.html#top"><span class="number">Chapter 4</span> Rails-flavored Ruby</a></li><li><ol><li class="section"><a href="rails-flavored-ruby.html#sec-motivation"><span class="number">4.1</span> Motivation</a></li><li class="section"><a href="rails-flavored-ruby.html#sec-strings_and_methods"><span class="number">4.2</span> Strings and methods</a></li><li><ol><li class="subsection"><a href="rails-flavored-ruby.html#sec-comments"><span class="number">4.2.1</span> Comments</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-strings"><span class="number">4.2.2</span> Strings</a></li><li><ol><li class="subsubsection"><a href="rails-flavored-ruby.html#sec-printing">Printing</a></li><li class="subsubsection"><a href="rails-flavored-ruby.html#sec-single_quoted_strings">Single-quoted strings</a></li></ol></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-objects_and_message_passing"><span class="number">4.2.3</span> Objects and message passing</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-method_definitions"><span class="number">4.2.4</span> Method definitions</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-back_to_the_title_helper"><span class="number">4.2.5</span> Back to the title helper</a></li></ol></li><li class="section"><a href="rails-flavored-ruby.html#sec-other_data_structures"><span class="number">4.3</span> Other data structures</a></li><li><ol><li class="subsection"><a href="rails-flavored-ruby.html#sec-arrays_and_ranges"><span class="number">4.3.1</span> Arrays and ranges</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-blocks"><span class="number">4.3.2</span> Blocks</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-hashes_and_symbols"><span class="number">4.3.3</span> Hashes and symbols</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-css_revisited"><span class="number">4.3.4</span> CSS revisited</a></li></ol></li><li class="section"><a href="rails-flavored-ruby.html#sec-ruby_classes"><span class="number">4.4</span> Ruby classes</a></li><li><ol><li class="subsection"><a href="rails-flavored-ruby.html#sec-constructors"><span class="number">4.4.1</span> Constructors</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-a_class_of_our_own"><span class="number">4.4.2</span> Class inheritance</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-modifying_built_in_classes"><span class="number">4.4.3</span> Modifying built-in classes</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-a_controller_class"><span class="number">4.4.4</span> A controller class</a></li><li class="subsection"><a href="rails-flavored-ruby.html#sec-a_user_class"><span class="number">4.4.5</span> A user class</a></li></ol></li><li class="section"><a href="rails-flavored-ruby.html#sec-conclusion"><span class="number">4.5</span> Conclusion</a></li><li class="section"><a href="rails-flavored-ruby.html#sec-exercises"><span class="number">4.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="filling-in-the-layout.html#top"><span class="number">Chapter 5</span> Filling in the layout</a></li><li><ol><li class="section"><a href="filling-in-the-layout.html#sec-structure"><span class="number">5.1</span> Adding some structure</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-adding_to_the_layout"><span class="number">5.1.1</span> Site navigation</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-custom_css"><span class="number">5.1.2</span> Bootstrap and custom CSS</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-partials"><span class="number">5.1.3</span> Partials</a></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-sass_and_the_asset_pipeline"><span class="number">5.2</span> Sass and the asset pipeline</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-the_asset_pipeline"><span class="number">5.2.1</span> The asset pipeline</a></li><li><ol><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_1">Asset directories</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_2">Manifest files</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_3">Preprocessor engines</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_1_4">Efficiency in production</a></li></ol></li><li class="subsection"><a href="filling-in-the-layout.html#sec-sass"><span class="number">5.2.2</span> Syntactically awesome stylesheets</a></li><li><ol><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_2_1">Nesting</a></li><li class="subsubsection"><a href="filling-in-the-layout.html#sec-5_2_2_2">Variables</a></li></ol></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-layout_links"><span class="number">5.3</span> Layout links</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-route_tests"><span class="number">5.3.1</span> Route tests</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-rails_routes"><span class="number">5.3.2</span> Rails routes</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-named_routes"><span class="number">5.3.3</span> Named routes</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-pretty_rspec"><span class="number">5.3.4</span> Pretty RSpec</a></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-user_signup"><span class="number">5.4</span> User signup: A first step</a></li><li><ol><li class="subsection"><a href="filling-in-the-layout.html#sec-users_controller"><span class="number">5.4.1</span> Users controller</a></li><li class="subsection"><a href="filling-in-the-layout.html#sec-signup_url"><span class="number">5.4.2</span> Signup URI</a></li></ol></li><li class="section"><a href="filling-in-the-layout.html#sec-layout_conclusion"><span class="number">5.5</span> Conclusion</a></li><li class="section"><a href="filling-in-the-layout.html#sec-layout_exercises"><span class="number">5.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="modeling-users.html#top"><span class="number">Chapter 6</span> Modeling users</a></li><li><ol><li class="section"><a href="modeling-users.html#sec-user_model"><span class="number">6.1</span> User model</a></li><li><ol><li class="subsection"><a href="modeling-users.html#sec-database_migrations"><span class="number">6.1.1</span> Database migrations</a></li><li class="subsection"><a href="modeling-users.html#sec-the_model_file"><span class="number">6.1.2</span> The model file</a></li><li><ol><li class="subsubsection"><a href="modeling-users.html#sec-model_annotation">Model annotation</a></li><li class="subsubsection"><a href="modeling-users.html#sec-accessible_attributes">Accessible attributes</a></li></ol></li><li class="subsection"><a href="modeling-users.html#sec-creating_user_objects"><span class="number">6.1.3</span> Creating user objects</a></li><li class="subsection"><a href="modeling-users.html#sec-finding_user_objects"><span class="number">6.1.4</span> Finding user objects</a></li><li class="subsection"><a href="modeling-users.html#sec-updating_user_objects"><span class="number">6.1.5</span> Updating user objects</a></li></ol></li><li class="section"><a href="modeling-users.html#sec-user_validations"><span class="number">6.2</span> User validations</a></li><li><ol><li class="subsection"><a href="modeling-users.html#sec-initial_user_tests"><span class="number">6.2.1</span> Initial user tests</a></li><li class="subsection"><a href="modeling-users.html#sec-presence_validation"><span class="number">6.2.2</span> Validating presence</a></li><li class="subsection"><a href="modeling-users.html#sec-length_validation"><span class="number">6.2.3</span> Length validation</a></li><li class="subsection"><a href="modeling-users.html#sec-format_validation"><span class="number">6.2.4</span> Format validation</a></li><li class="subsection"><a href="modeling-users.html#sec-uniqueness_validation"><span class="number">6.2.5</span> Uniqueness validation</a></li><li><ol><li class="subsubsection"><a href="modeling-users.html#sec-the_caveat">The uniqueness caveat</a></li></ol></li></ol></li><li class="section"><a href="modeling-users.html#sec-adding_a_secure_password"><span class="number">6.3</span> Adding a secure password</a></li><li><ol><li class="subsection"><a href="modeling-users.html#sec-an_encrypted_password"><span class="number">6.3.1</span> An encrypted password</a></li><li class="subsection"><a href="modeling-users.html#sec-password_and_confirmation"><span class="number">6.3.2</span> Password and confirmation</a></li><li class="subsection"><a href="modeling-users.html#sec-user_authentication"><span class="number">6.3.3</span> User authentication</a></li><li class="subsection"><a href="modeling-users.html#sec-has_secure_password"><span class="number">6.3.4</span> User has secure password</a></li><li class="subsection"><a href="modeling-users.html#sec-creating_a_user"><span class="number">6.3.5</span> Creating a user</a></li></ol></li><li class="section"><a href="modeling-users.html#sec-6_4"><span class="number">6.4</span> Conclusion</a></li><li class="section"><a href="modeling-users.html#sec-6_5"><span class="number">6.5</span> Exercises</a></li></ol></li><li class="chapter"><a href="sign-up.html#top"><span class="number">Chapter 7</span> Sign up</a></li><li><ol><li class="section"><a href="sign-up.html#sec-showing_users"><span class="number">7.1</span> Showing users</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-rails_environments"><span class="number">7.1.1</span> Debug and Rails environments</a></li><li class="subsection"><a href="sign-up.html#sec-a_users_resource"><span class="number">7.1.2</span> A Users resource</a></li><li class="subsection"><a href="sign-up.html#sec-tests_with_factories"><span class="number">7.1.3</span> Testing the user show page (with factories)</a></li><li class="subsection"><a href="sign-up.html#sec-a_gravatar_image"><span class="number">7.1.4</span> A Gravatar image and a sidebar</a></li></ol></li><li class="section"><a href="sign-up.html#sec-signup_form"><span class="number">7.2</span> Signup form</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-tests_for_user_signup"><span class="number">7.2.1</span> Tests for user signup</a></li><li class="subsection"><a href="sign-up.html#sec-using_form_for"><span class="number">7.2.2</span> Using <tt>form_for</tt></a></li><li class="subsection"><a href="sign-up.html#sec-the_form_html"><span class="number">7.2.3</span> The form HTML</a></li></ol></li><li class="section"><a href="sign-up.html#sec-signup_failure"><span class="number">7.3</span> Signup failure</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-a_working_form"><span class="number">7.3.1</span> A working form</a></li><li class="subsection"><a href="sign-up.html#sec-signup_error_messages"><span class="number">7.3.2</span> Signup error messages</a></li></ol></li><li class="section"><a href="sign-up.html#sec-signup_success"><span class="number">7.4</span> Signup success</a></li><li><ol><li class="subsection"><a href="sign-up.html#sec-the_finished_signup_form"><span class="number">7.4.1</span> The finished signup form</a></li><li class="subsection"><a href="sign-up.html#sec-the_flash"><span class="number">7.4.2</span> The flash</a></li><li class="subsection"><a href="sign-up.html#sec-the_first_signup"><span class="number">7.4.3</span> The first signup</a></li><li class="subsection"><a href="sign-up.html#sec-deploying_to_production_with_ssl"><span class="number">7.4.4</span> Deploying to production with SSL</a></li></ol></li><li class="section"><a href="sign-up.html#sec-7_5"><span class="number">7.5</span> Conclusion</a></li><li class="section"><a href="sign-up.html#sec-signup_exercises"><span class="number">7.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="sign-in-sign-out.html#top"><span class="number">Chapter 8</span> Sign in, sign out</a></li><li><ol><li class="section"><a href="sign-in-sign-out.html#sec-signin_failure"><span class="number">8.1</span> Sessions and signin failure</a></li><li><ol><li class="subsection"><a href="sign-in-sign-out.html#sec-sessions_controller"><span class="number">8.1.1</span> Sessions controller</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signin_tests"><span class="number">8.1.2</span> Signin tests</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signin_form"><span class="number">8.1.3</span> Signin form</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-reviewing_form_submission"><span class="number">8.1.4</span> Reviewing form submission</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-rendering_with_a_flash_message"><span class="number">8.1.5</span> Rendering with a flash message</a></li></ol></li><li class="section"><a href="sign-in-sign-out.html#sec-signin_success"><span class="number">8.2</span> Signin success</a></li><li><ol><li class="subsection"><a href="sign-in-sign-out.html#sec-remember_me"><span class="number">8.2.1</span> Remember me</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-a_working_sign_in_method"><span class="number">8.2.2</span> A working <tt>sign_in</tt> method</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-current_user"><span class="number">8.2.3</span> Current user</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-changing_the_layout_links"><span class="number">8.2.4</span> Changing the layout links</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signin_upon_signup"><span class="number">8.2.5</span> Signin upon signup</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-signing_out"><span class="number">8.2.6</span> Signing out</a></li></ol></li><li class="section"><a href="sign-in-sign-out.html#sec-cucumber"><span class="number">8.3</span> Introduction to Cucumber (optional)</a></li><li><ol><li class="subsection"><a href="sign-in-sign-out.html#sec-installation_and_setup"><span class="number">8.3.1</span> Installation and setup</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-features_and_steps"><span class="number">8.3.2</span> Features and steps</a></li><li class="subsection"><a href="sign-in-sign-out.html#sec-rspec_custom_matchers"><span class="number">8.3.3</span> Counterpoint: RSpec custom matchers</a></li></ol></li><li class="section"><a href="sign-in-sign-out.html#sec-8_4"><span class="number">8.4</span> Conclusion</a></li><li class="section"><a href="sign-in-sign-out.html#sec-sign_in_out_exercises"><span class="number">8.5</span> Exercises</a></li></ol></li><li class="chapter"><a href="updating-showing-and-deleting-users.html#top"><span class="number">Chapter 9</span> Updating, showing, and deleting users</a></li><li><ol><li class="section"><a href="updating-showing-and-deleting-users.html#sec-updating_users"><span class="number">9.1</span> Updating users</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-edit_form"><span class="number">9.1.1</span> Edit form</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-unsuccessful_edits"><span class="number">9.1.2</span> Unsuccessful edits</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-successful_edits"><span class="number">9.1.3</span> Successful edits</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-authorization"><span class="number">9.2</span> Authorization</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-requiring_signed_in_users"><span class="number">9.2.1</span> Requiring signed-in users</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-requiring_the_right_user"><span class="number">9.2.2</span> Requiring the right user</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-friendly_forwarding"><span class="number">9.2.3</span> Friendly forwarding</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-showing_all_users"><span class="number">9.3</span> Showing all users</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-user_index"><span class="number">9.3.1</span> User index</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-sample_users"><span class="number">9.3.2</span> Sample users</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-pagination"><span class="number">9.3.3</span> Pagination</a></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-partial_refactoring"><span class="number">9.3.4</span> Partial refactoring</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-destroying_users"><span class="number">9.4</span> Deleting users</a></li><li><ol><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-administrative_users"><span class="number">9.4.1</span> Administrative users</a></li><li><ol><li class="subsubsection"><a href="updating-showing-and-deleting-users.html#sec-revisiting_attr_accessible">Revisiting <tt>attr_accessible</tt></a></li></ol></li><li class="subsection"><a href="updating-showing-and-deleting-users.html#sec-the_destroy_action"><span class="number">9.4.2</span> The <tt>destroy</tt> action</a></li></ol></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-updating_and_deleting_users_conclusion"><span class="number">9.5</span> Conclusion</a></li><li class="section"><a href="updating-showing-and-deleting-users.html#sec-updating_deleting_exercises"><span class="number">9.6</span> Exercises</a></li></ol></li><li class="chapter"><a href="user-microposts.html#top"><span class="number">Chapter 10</span> User microposts</a></li><li><ol><li class="section"><a href="user-microposts.html#sec-a_micropost_model"><span class="number">10.1</span> A Micropost model</a></li><li><ol><li class="subsection"><a href="user-microposts.html#sec-the_basic_model"><span class="number">10.1.1</span> The basic model</a></li><li class="subsection"><a href="user-microposts.html#sec-accessible_attribute"><span class="number">10.1.2</span> Accessible attributes and the first validation</a></li><li class="subsection"><a href="user-microposts.html#sec-user_micropost_associations"><span class="number">10.1.3</span> User/Micropost associations</a></li><li class="subsection"><a href="user-microposts.html#sec-ordering_and_dependency"><span class="number">10.1.4</span> Micropost refinements</a></li><li><ol><li class="subsubsection"><a href="user-microposts.html#sec-default_scope">Default scope</a></li><li class="subsubsection"><a href="user-microposts.html#sec-dependent_destroy">Dependent: destroy</a></li></ol></li><li class="subsection"><a href="user-microposts.html#sec-micropost_validations"><span class="number">10.1.5</span> Content validations</a></li></ol></li><li class="section"><a href="user-microposts.html#sec-showing_microposts"><span class="number">10.2</span> Showing microposts</a></li><li><ol><li class="subsection"><a href="user-microposts.html#sec-augmenting_the_user_show_page"><span class="number">10.2.1</span> Augmenting the user show page</a></li><li class="subsection"><a href="user-microposts.html#sec-sample_microposts"><span class="number">10.2.2</span> Sample microposts</a></li></ol></li><li class="section"><a href="user-microposts.html#sec-manipulating_microposts"><span class="number">10.3</span> Manipulating microposts</a></li><li><ol><li class="subsection"><a href="user-microposts.html#sec-access_control"><span class="number">10.3.1</span> Access control</a></li><li class="subsection"><a href="user-microposts.html#sec-creating_microposts"><span class="number">10.3.2</span> Creating microposts</a></li><li class="subsection"><a href="user-microposts.html#sec-a_proto_feed"><span class="number">10.3.3</span> A proto-feed</a></li><li class="subsection"><a href="user-microposts.html#sec-destroying_microposts"><span class="number">10.3.4</span> Destroying microposts</a></li></ol></li><li class="section"><a href="user-microposts.html#sec-10_4"><span class="number">10.4</span> Conclusion</a></li><li class="section"><a href="user-microposts.html#sec-micropost_exercises"><span class="number">10.5</span> Exercises</a></li></ol></li><li class="chapter"><a href="following-users.html#top"><span class="number">Chapter 11</span> Following users</a></li><li><ol><li class="section"><a href="following-users.html#sec-the_relationship_model"><span class="number">11.1</span> The Relationship model</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-a_problem_with_the_data_model"><span class="number">11.1.1</span> A problem with the data model (and a solution)</a></li><li class="subsection"><a href="following-users.html#sec-relationship_user_associations"><span class="number">11.1.2</span> User/relationship associations</a></li><li class="subsection"><a href="following-users.html#sec-relationship_validations"><span class="number">11.1.3</span> Validations</a></li><li class="subsection"><a href="following-users.html#sec-following"><span class="number">11.1.4</span> Followed users</a></li><li class="subsection"><a href="following-users.html#sec-followers"><span class="number">11.1.5</span> Followers</a></li></ol></li><li class="section"><a href="following-users.html#sec-a_web_interface_for_following_and_followers"><span class="number">11.2</span> A web interface for following users</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-sample_following_data"><span class="number">11.2.1</span> Sample following data</a></li><li class="subsection"><a href="following-users.html#sec-stats_and_a_follow_form"><span class="number">11.2.2</span> Stats and a follow form</a></li><li class="subsection"><a href="following-users.html#sec-following_and_followers_pages"><span class="number">11.2.3</span> Following and followers pages</a></li><li class="subsection"><a href="following-users.html#sec-a_working_follow_button_the_standard_way"><span class="number">11.2.4</span> A working follow button the standard way</a></li><li class="subsection"><a href="following-users.html#sec-a_working_follow_button_with_ajax"><span class="number">11.2.5</span> A working follow button with Ajax</a></li></ol></li><li class="section"><a href="following-users.html#sec-the_status_feed"><span class="number">11.3</span> The status feed</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-motivation_and_strategy"><span class="number">11.3.1</span> Motivation and strategy</a></li><li class="subsection"><a href="following-users.html#sec-a_first_feed_implementation"><span class="number">11.3.2</span> A first feed implementation</a></li><li class="subsection"><a href="following-users.html#sec-scopes_subselects_and_a_lambda"><span class="number">11.3.3</span> Subselects</a></li><li class="subsection"><a href="following-users.html#sec-the_new_status_feed"><span class="number">11.3.4</span> The new status feed</a></li></ol></li><li class="section"><a href="following-users.html#sec-following_conclusion"><span class="number">11.4</span> Conclusion</a></li><li><ol><li class="subsection"><a href="following-users.html#sec-extensions_to_the_sample_application"><span class="number">11.4.1</span> Extensions to the sample application</a></li><li><ol><li class="subsubsection"><a href="following-users.html#sec-replies">Replies</a></li><li class="subsubsection"><a href="following-users.html#sec-messaging">Messaging</a></li><li class="subsubsection"><a href="following-users.html#sec-follower_notifications">Follower notifications</a></li><li class="subsubsection"><a href="following-users.html#sec-password_reminders">Password reminders</a></li><li class="subsubsection"><a href="following-users.html#sec-signup_confirmation">Signup confirmation</a></li><li class="subsubsection"><a href="following-users.html#sec-rss_feed">RSS feed</a></li><li class="subsubsection"><a href="following-users.html#sec-rest_api">REST API</a></li><li class="subsubsection"><a href="following-users.html#sec-search">Search</a></li></ol></li><li class="subsection"><a href="following-users.html#sec-guide_to_further_resources"><span class="number">11.4.2</span> Guide to further resources</a></li></ol></li><li class="section"><a href="following-users.html#sec-following_exercises"><span class="number">11.5</span> Exercises</a></li></ol></li></ol></div>
<div id="main_content"></div>
<p> <span class="preamble">
<span id="foreword">
<strong> Foreword</strong> <br />
</span>
</span></p>
<p>My former company (CD Baby) was one of the first to loudly switch to Ruby on Rails, and then even more loudly switch back to PHP (Google me to read about the drama). This book by Michael Hartl came so highly recommended that I had to try it, and the <em>Ruby on Rails Tutorial</em> is what I used to switch back to Rails again.</p>
<p>Though I’ve worked my way through many Rails books, this is the one that finally made me “get” it. Everything is done very much “the Rails way”—a way that felt very unnatural to me before, but now after doing this book finally feels natural. This is also the only Rails book that does test-driven development the entire time, an approach highly recommended by the experts but which has never been so clearly demonstrated before. Finally, by including Git, GitHub, and Heroku in the demo examples, the author really gives you a feel for what it’s like to do a real-world project. The tutorial’s code examples are not in isolation.</p>
<p>The linear narrative is such a great format. Personally, I powered through the <em>Rails Tutorial</em> in three long days, doing all the examples and challenges at the end of each chapter. Do it from start to finish, without jumping around, and you’ll get the ultimate benefit.</p>
<p>Enjoy!</p>
<p><a href="http://sivers.org/">Derek Sivers</a> (<a href="http://sivers.org/">sivers.org</a>) <br />
<em>Founder, CD Baby</em> <br /></p>
<p> <span class="preamble">
<strong> Acknowledgments</strong> <br />
</span></p>
<p>The <em>Ruby on Rails Tutorial</em> owes a lot to my previous Rails book, <em>RailsSpace</em>, and hence to my coauthor <a href="http://aure.com/">Aurelius Prochazka</a>. I’d like to thank Aure both for the work he did on that book and for his support of this one. I’d also like to thank Debra Williams Cauley, my editor on both <em>RailsSpace</em> and the <em>Ruby on Rails Tutorial</em>; as long as she keeps taking me to baseball games, I’ll keep writing books for her.</p>
<p>I’d like to acknowledge a long list of Rubyists who have taught and inspired me over the years: David Heinemeier Hansson, Yehuda Katz, Carl Lerche, Jeremy Kemper, Xavier Noria, Ryan Bates, Geoffrey Grosenbach, Peter Cooper, Matt Aimonetti, Gregg Pollack, Wayne E. Seguin, Amy Hoy, Dave Chelimsky, Pat Maddox, Tom Preston-Werner, Chris Wanstrath, Chad Fowler, Josh Susser, Obie Fernandez, Ian McFarland, Steven Bristol, Pratik Naik, Sarah Mei, Sarah Allen, Wolfram Arnold, Alex Chaffee, Giles Bowkett, Evan Dorn, Long Nguyen, James Lindenbaum, Adam Wiggins, Tikhon Bernstam, Ron Evans, Wyatt Greene, Miles Forrest, the good people at Pivotal Labs, the Heroku gang, the thoughtbot guys, and the GitHub crew. Finally, many, many readers—far too many to list—have contributed a huge number of bug reports and suggestions during the writing of this book, and I gratefully acknowledge their help in making it as good as it can be. <br /></p>
<p> <span class="preamble">
<span id="author">
<strong> About the author</strong> <br />
</span>
</span></p>
<p><a href="http://michaelhartl.com/">Michael Hartl</a> is the author of the <a href="http://ruby.railstutorial.org/"><em>Ruby on Rails Tutorial</em></a>, the leading introduction to web development with <a href="http://rubyonrails.org/">Ruby on Rails</a>. His prior experience includes writing and developing <em>RailsSpace</em>, an extremely obsolete Rails tutorial book, and developing Insoshi, a once-popular and now-obsolete social networking platform in Ruby on Rails. In 2011, Michael received a <a href="http://rubyheroes.com/heroes">Ruby Hero Award</a> for his contributions to the Ruby community. He is a graduate of <a href="http://college.harvard.edu/">Harvard College</a>, has a <a href="http://resolver.caltech.edu/CaltechETD:etd-05222003-161626">Ph.D. in Physics</a> from <a href="http://www.caltech.edu/">Caltech</a>, and is an alumnus of the <a href="http://ycombinator.com/">Y Combinator</a> entrepreneur program. <br /></p>
<p> <span id="license" class="preamble">
<strong> Copyright and license</strong> <br />
</span></p>
<p><em>Ruby on Rails Tutorial: Learn Web Development with Rails</em>. Copyright © 2012 by Michael Hartl. All source code in the <em>Ruby on Rails Tutorial</em> is available jointly under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> and the <a href="http://people.freebsd.org/~phk/">Beerware License</a>.</p>
<div class="code"><div class="highlight"><pre>The MIT License
Copyright (c) 2012 Michael Hartl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</pre></div>
</div>
<div class="code"><div class="highlight"><pre>/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Michael Hartl wrote this code. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
</pre></div>
</div>
<div id="top"></div>
<h1 class="chapter"><a id="sec-4" href="rails-flavored-ruby.html#top" class="heading"><span class="number">Chapter 4</span> Rails-flavored Ruby</a></h1>
<p>Grounded in examples from <a class="ref" href="static-pages.html#top">Chapter 3</a>, this chapter explores some elements of Ruby important for Rails. Ruby is a big language, but fortunately the subset needed to be productive as a Rails developer is relatively small. Moreover, this subset is <em>different</em> from the usual approaches to learning Ruby, which is why, if your goal is making dynamic web applications, I recommend learning Rails first, picking up bits of Ruby along the way. To become a Rails <em>expert</em>, you need to understand Ruby more deeply, and this book gives you a good foundation for developing that expertise. As noted in <a class="ref" href="beginning.html#sec-comments_for_various_readers">Section 1.1.1</a>, after finishing the <em>Rails Tutorial</em> I suggest reading a pure Ruby book such as <a href="http://www.amazon.com/gp/product/1430223634"><em>Beginning Ruby</em></a>, <a href="http://www.amazon.com/gp/product/1933988657"><em>The Well-Grounded Rubyist</em></a>, or <a href="http://www.amazon.com/gp/product/0672328844"><em>The Ruby Way</em></a>.</p>
<p>This chapter covers a lot of material, and it’s OK not to get it all on the first pass. I’ll refer back to it frequently in future chapters.</p>
<div class="label" id="sec-motivation"></div>
<h2><a id="sec-4_1" href="rails-flavored-ruby.html#sec-motivation" class="heading"><span class="number">4.1</span> Motivation</a></h2>
<p>As we saw in the last chapter, it’s possible to develop the skeleton of a Rails application, and even start testing it, with essentially no knowledge of the underlying Ruby language. We did this by relying on the test code provided by the tutorial and addressing each error message until the test suite was passing. This situation can’t last forever, though, and we’ll open this chapter with an addition to the site that brings us face-to-face with our Ruby limitations.</p>
<p>When we last saw our new application, we had just updated our mostly static pages to use Rails layouts to eliminate duplication in our views (<a class="ref" href="rails-flavored-ruby.html#code-application_layout_redux">Listing 4.1</a>).</p>
<div class="label" id="code-application_layout_redux"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 4.1.</span> <span class="description">The sample application site layout. <br /> <code>app/views/layouts/application.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span>Ruby on Rails Tutorial Sample App | <span class="cp"><%=</span> <span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">)</span> <span class="cp">%></span><span class="nt"></title></span>
<span class="cp"><%=</span> <span class="n">stylesheet_link_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="ss">:media</span> <span class="o">=></span> <span class="s2">"all"</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">javascript_include_tag</span> <span class="s2">"application"</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">csrf_meta_tags</span> <span class="cp">%></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
</div></div>
<p>Let’s focus on one particular line in <a class="ref" href="rails-flavored-ruby.html#code-application_layout_redux">Listing 4.1</a>:</p>
<div class="code"><div class="highlight"><pre><span class="cp"><%=</span> <span class="n">stylesheet_link_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="ss">:media</span> <span class="o">=></span> <span class="s2">"all"</span> <span class="cp">%></span>
</pre></div>
</div>
<p>This uses the built-in Rails function <code>stylesheet_link_tag</code> (which you can read more about at the <a href="http://api.rubyonrails.org/v3.2.0/classes/ActionView/Helpers/AssetTagHelper/StylesheetTagHelpers.html#method-i-stylesheet_link_tag">Rails API</a>) to include <code>application.css</code> for all <a href="http://www.w3.org/TR/CSS2/media.html">media types</a> (including computer screens and printers). To an experienced Rails developer, this line looks simple, but there are at least four potentially confusing Ruby ideas: built-in Rails methods, method invocation with missing parentheses, symbols, and hashes. We’ll cover all of these ideas in this chapter.</p>
<p>In addition to coming equipped with a large number of built-in functions for use in the views, Rails also allows the creation of new ones. Such functions are called <em>helpers</em>; to see how to make a custom helper, let’s start by examining the title line from <a class="ref" href="rails-flavored-ruby.html#code-application_layout_redux">Listing 4.1</a>:</p>
<div class="code"><div class="highlight"><pre>Ruby on Rails Tutorial Sample App | <span class="cp"><%=</span> <span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">)</span> <span class="cp">%></span>
</pre></div>
</div>
<p>This relies on the definition of a page title (using <code>provide</code>) in each view, as in</p>
<div class="code"><div class="highlight"><pre><span class="cp"><%</span> <span class="n">provide</span><span class="p">(</span><span class="ss">:title</span><span class="p">,</span> <span class="s1">'Home'</span><span class="p">)</span> <span class="cp">%></span>
<span class="nt"><h1></span>Sample App<span class="nt"></h1></span>
<span class="nt"><p></span>
This is the home page for the
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"http://railstutorial.org/"</span><span class="nt">></span>Ruby on Rails Tutorial<span class="nt"></a></span>
sample application.
<span class="nt"></p></span>
</pre></div>
</div>
<p>But what if we don’t provide a title? It’s a good convention to have a <em>base title</em> we use on every page, with an optional page title if we want to be more specific. We’ve <em>almost</em> achieved that with our current layout, with one wrinkle: as you can see if you delete the <code>provide</code> call in one of the views, in the absence of a page-specific title the full title appears as follows:</p>
<div class="code"><div class="highlight"><pre>Ruby on Rails Tutorial Sample App |
</pre></div>
</div>
<p>In other words, there’s a suitable base title, but there’s also a trailing vertical bar character <code>|</code> at the end.</p>
<p>To solve the problem of a missing page title, we’ll define a custom helper called <code>full_title</code>. The <code>full_title</code> helper returns a base title, “Ruby on Rails Tutorial Sample App”, if no page title is defined, and adds a vertical bar followed by the page title if one is defined (<a class="ref" href="rails-flavored-ruby.html#code-title_helper">Listing 4.2</a>).<sup class="footnote" id="fnref-4_1"><a href="#fn-4_1">1</a></sup></p>
<div class="label" id="code-title_helper"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 4.2.</span> <span class="description">Defining a <code>full_title</code> helper. <br /> <code>app/helpers/application_helper.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">module</span> <span class="nn">ApplicationHelper</span>
<span class="c1"># Returns the full title on a per-page basis.</span>
<span class="k">def</span> <span class="nf">full_title</span><span class="p">(</span><span class="n">page_title</span><span class="p">)</span>
<span class="n">base_title</span> <span class="o">=</span> <span class="s2">"Ruby on Rails Tutorial Sample App"</span>
<span class="k">if</span> <span class="n">page_title</span><span class="o">.</span><span class="n">empty?</span>
<span class="n">base_title</span>
<span class="k">else</span>
<span class="s2">"</span><span class="si">#{</span><span class="n">base_title</span><span class="si">}</span><span class="s2"> | </span><span class="si">#{</span><span class="n">page_title</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>Now that we have a helper, we can use it to simplify our layout by replacing</p>
<div class="code"><div class="highlight"><pre><span class="nt"><title></span>Ruby on Rails Tutorial Sample App | <span class="cp"><%=</span> <span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">)</span> <span class="cp">%></span><span class="nt"></title></span>
</pre></div>
</div>
<p>with</p>
<div class="code"><div class="highlight"><pre><span class="nt"><title></span><span class="cp"><%=</span> <span class="n">full_title</span><span class="p">(</span><span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">))</span> <span class="cp">%></span><span class="nt"></title></span>
</pre></div>
</div>
<p>as seen in <a class="ref" href="rails-flavored-ruby.html#code-application_layout_full_title">Listing 4.3</a>.</p>
<div class="label" id="code-application_layout_full_title"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 4.3.</span> <span class="description">The sample application site layout. <br /> <code>app/views/layouts/application.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span><span class="cp"><%=</span> <span class="n">full_title</span><span class="p">(</span><span class="k">yield</span><span class="p">(</span><span class="ss">:title</span><span class="p">))</span> <span class="cp">%></span><span class="nt"></title></span>
<span class="cp"><%=</span> <span class="n">stylesheet_link_tag</span> <span class="s2">"application"</span><span class="p">,</span> <span class="ss">:media</span> <span class="o">=></span> <span class="s2">"all"</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">javascript_include_tag</span> <span class="s2">"application"</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">csrf_meta_tags</span> <span class="cp">%></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
</div></div>
<p>To put our helper to work, we can eliminate the unnecessary word “Home” from the Home page, allowing it to revert to the base title. We do this by first updating our test with the code in <a class="ref" href="rails-flavored-ruby.html#code-home_base_title_spec">Listing 4.4</a>, which updates the previous title test and adds one to test for the absence of the custom <code>’Home’</code> string in the title.</p>
<div class="label" id="code-home_base_title_spec"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 4.4.</span> <span class="description">Updated tests for the Home page’s title. <br /> <code>spec/requests/static_pages_spec.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nb">require</span> <span class="s1">'spec_helper'</span>
<span class="n">describe</span> <span class="s2">"Static pages"</span> <span class="k">do</span>
<span class="n">describe</span> <span class="s2">"Home page"</span> <span class="k">do</span>
<span class="n">it</span> <span class="s2">"should have the h1 'Sample App'"</span> <span class="k">do</span>
<span class="n">visit</span> <span class="s1">'/static_pages/home'</span>
<span class="n">page</span><span class="o">.</span><span class="n">should</span> <span class="n">have_selector</span><span class="p">(</span><span class="s1">'h1'</span><span class="p">,</span> <span class="ss">:text</span> <span class="o">=></span> <span class="s1">'Sample App'</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">it</span> <span class="s2">"should have the base title"</span> <span class="k">do</span>
<span class="n">visit</span> <span class="s1">'/static_pages/home'</span>
<span class="n">page</span><span class="o">.</span><span class="n">should</span> <span class="n">have_selector</span><span class="p">(</span><span class="s1">'title'</span><span class="p">,</span>
<span class="ss">:text</span> <span class="o">=></span> <span class="s2">"Ruby on Rails Tutorial Sample App"</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">it</span> <span class="s2">"should not have a custom page title"</span> <span class="k">do</span>
<span class="n">visit</span> <span class="s1">'/static_pages/home'</span>
<span class="n">page</span><span class="o">.</span><span class="n">should_not</span> <span class="n">have_selector</span><span class="p">(</span><span class="s1">'title'</span><span class="p">,</span> <span class="ss">:text</span> <span class="o">=></span> <span class="s1">'| Home'</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>See if you can figure out why we’ve added a new test instead of just altering the current one. (<em>Hint</em>: The answer is in <a class="ref" href="static-pages.html#sec-testing_a_title_change">Section 3.3.1</a>.)</p>
<p>Let’s run the test suite to verify that one test fails:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rspec spec/requests/static_pages_spec.rb
</pre></div>
</div>
<p>To get the test suite to pass, we’ll remove the <code>provide</code> line from the Home page’s view, as seen in <a class="ref" href="rails-flavored-ruby.html#code-home_page_base_title">Listing 4.5</a>.</p>
<div class="label" id="code-home_page_base_title"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 4.5.</span> <span class="description">The Home page with no custom page title. <br /> <code>app/views/static_pages/home.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nt"><h1></span>Sample App<span class="nt"></h1></span>
<span class="nt"><p></span>
This is the home page for the
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"http://railstutorial.org/"</span><span class="nt">></span>Ruby on Rails Tutorial<span class="nt"></a></span>
sample application.
<span class="nt"></p></span>
</pre></div>
</div></div>
<p>At this point the tests should pass:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rspec spec/requests/static_pages_spec.rb
</pre></div>
</div>
<p>As with the line to include the application stylesheet, the code in <a class="ref" href="rails-flavored-ruby.html#code-title_helper">Listing 4.2</a> may look simple to the eyes of an experienced Rails developer, but it’s <em>full</em> of potentially confusing Ruby ideas: modules, comments, local variable assignment, booleans, control flow, string interpolation, and return values. This chapter will cover all of these ideas as well.</p>
<div class="label" id="sec-strings_and_methods"></div>
<h2><a id="sec-4_2" href="rails-flavored-ruby.html#sec-strings_and_methods" class="heading"><span class="number">4.2</span> Strings and methods</a></h2>
<p>Our principal tool for learning Ruby will be the <em>Rails console</em>, a command-line tool for interacting with Rails applications first seen in <a class="ref" href="a-demo-app.html#sec-demo_user_has_many_microposts">Section 2.3.3</a>. The console itself is built on top of interactive Ruby (<code>irb</code>), and thus has access to the full power of the Ruby language. (As we’ll see in <a class="ref" href="rails-flavored-ruby.html#sec-a_controller_class">Section 4.4.4</a>, the console also has access to the Rails environment.) Start the console at the command line as follows:</p>
<div class="code"><div class="highlight"><pre><span class="go">$ rails console</span>
<span class="go">Loading development environment</span>
<span class="gp">>> </span>
</pre></div>
</div>
<p>By default, the console starts in a <em>development environment</em>, which is one of three separate environments defined by Rails (the others are <em>test</em> and <em>production</em>). This distinction won’t be important in this chapter, but we’ll learn more about environments in <a class="ref" href="sign-up.html#sec-rails_environments">Section 7.1.1</a>.</p>
<p>The console is a great learning tool, and you should feel free to explore—don’t worry, you (probably) won’t break anything. When using the console, type Ctrl-C if you get stuck, or Ctrl-D to exit the console altogether. Throughout the rest of this chapter, you might find it helpful to consult the <a href="http://ruby-doc.org/core-1.9.3/">Ruby API</a>. It’s packed (perhaps even <em>too</em> packed) with information; for example, to learn more about Ruby strings you can look at the Ruby API entry for the <code>String</code> class.</p>
<div class="label" id="sec-comments"></div>
<h3><a id="sec-4_2_1" href="rails-flavored-ruby.html#sec-comments" class="heading"><span class="number">4.2.1</span> Comments</a></h3>
<p>Ruby <em>comments</em> start with the pound sign <code>#</code> (also called the “hash mark” or, more poetically, the “octothorpe”) and extend to the end of the line. Ruby ignores comments, but they are useful for human readers (including, often, the original author!). In the code</p>
<div class="code"><div class="highlight"><pre> <span class="c1"># Returns the full title on a per-page basis.</span>
<span class="k">def</span> <span class="nf">full_title</span><span class="p">(</span><span class="n">page_title</span><span class="p">)</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="k">end</span>
</pre></div>
</div>
<p>the first line is a comment indicating the purpose of the subsequent function definition.</p>
<p>You don’t ordinarily include comments in console sessions, but for instructional purposes I’ll include some comments in what follows, like this:</p>
<div class="code"><div class="highlight"><pre><span class="go">$ rails console</span>
<span class="gp">>> </span><span class="mi">17</span> <span class="o">+</span> <span class="mi">42</span> <span class="c1"># Integer addition</span>
<span class="go">=> 59</span>
</pre></div>
</div>
<p>If you follow along in this section typing or copying-and-pasting commands into your own console, you can of course omit the comments if you like; the console will ignore them in any case.</p>
<div class="label" id="sec-strings"></div>
<h3><a id="sec-4_2_2" href="rails-flavored-ruby.html#sec-strings" class="heading"><span class="number">4.2.2</span> Strings</a></h3>
<p><em>Strings</em> are probably the most important data structure for web applications, since web pages ultimately consist of strings of characters sent from the server to the browser. Let’s start exploring strings with the console, this time started with <code>rails c</code>, which is a shortcut for <code>rails console</code>:</p>
<div class="code"><div class="highlight"><pre><span class="go">$ rails c</span>
<span class="gp">>> </span><span class="s2">""</span> <span class="c1"># An empty string</span>
<span class="go">=> ""</span>
<span class="gp">>> </span><span class="s2">"foo"</span> <span class="c1"># A nonempty string</span>
<span class="go">=> "foo"</span>
</pre></div>
</div>
<p>These are <em>string literals</em> (also, amusingly, called <em>literal strings</em>), created using the double quote character <code>"</code>. The console prints the result of evaluating each line, which in the case of a string literal is just the string itself.</p>
<p>We can also concatenate strings with the <code>+</code> operator:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s2">"foo"</span> <span class="o">+</span> <span class="s2">"bar"</span> <span class="c1"># String concatenation</span>
<span class="go">=> "foobar"</span>
</pre></div>
</div>
<p>Here the result of evaluating <code>"foo"</code> plus <code>"bar"</code> is the string <code>"foobar"</code>.<sup class="footnote" id="fnref-4_2"><a href="#fn-4_2">2</a></sup></p>
<p>Another way to build up strings is via <em>interpolation</em> using the special syntax <code>#{}</code>:<sup class="footnote" id="fnref-4_3"><a href="#fn-4_3">3</a></sup></p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">first_name</span> <span class="o">=</span> <span class="s2">"Michael"</span> <span class="c1"># Variable assignment</span>
<span class="go">=> "Michael"</span>
<span class="gp">>> </span><span class="s2">"</span><span class="si">#{</span><span class="n">first_name</span><span class="si">}</span><span class="s2"> Hartl"</span> <span class="c1"># String interpolation</span>
<span class="go">=> "Michael Hartl"</span>
</pre></div>
</div>
<p>Here we’ve <em>assigned</em> the value <code>"Michael"</code> to the variable <code>first_name</code> and then interpolated it into the string <code>"#{first_name} Hartl"</code>. We could also assign both strings a variable name:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">first_name</span> <span class="o">=</span> <span class="s2">"Michael"</span>
<span class="go">=> "Michael"</span>
<span class="gp">>> </span><span class="n">last_name</span> <span class="o">=</span> <span class="s2">"Hartl"</span>
<span class="go">=> "Hartl"</span>
<span class="gp">>> </span><span class="n">first_name</span> <span class="o">+</span> <span class="s2">" "</span> <span class="o">+</span> <span class="n">last_name</span> <span class="c1"># Concatenation, with a space in between</span>
<span class="go">=> "Michael Hartl"</span>
<span class="gp">>> </span><span class="s2">"</span><span class="si">#{</span><span class="n">first_name</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">last_name</span><span class="si">}</span><span class="s2">"</span> <span class="c1"># The equivalent interpolation</span>
<span class="go">=> "Michael Hartl"</span>
</pre></div>
</div>
<p>Note that the final two expressions are equivalent, but I prefer the interpolated version; having to add the single space <code>" "</code> seems a bit awkward.</p>
<div class="label" id="sec-printing"></div>
<h4><a id="sec-4_2_2_1" href="rails-flavored-ruby.html#sec-printing" class="heading">Printing</a></h4>
<p>To <em>print</em> a string, the most commonly used Ruby function is <code>puts</code> (pronounced “put ess”, for “put string”):</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="nb">puts</span> <span class="s2">"foo"</span> <span class="c1"># put string</span>
<span class="go">foo</span>
<span class="go">=> nil</span>
</pre></div>
</div>
<p>The <code>puts</code> method operates as a <em>side-effect</em>: the expression <code>puts "foo"</code> prints the string to the screen and then returns <a href="http://www.answers.com/nil">literally nothing</a>: <code>nil</code> is a special Ruby value for “nothing at all”. (In what follows, I’ll sometimes suppress the <code>=> nil</code> part for simplicity.)</p>
<p>Using <code>puts</code> automatically appends a newline character <tt class="verb">\n</tt> to the output; the related <code>print</code> method does not:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="nb">print</span> <span class="s2">"foo"</span> <span class="c1"># print string (same as puts, but without the newline)</span>
<span class="go">foo=> nil</span>
<span class="gp">>> </span><span class="nb">print</span> <span class="s2">"foo</span><span class="se">\n</span><span class="s2">"</span> <span class="c1"># Same as puts "foo"</span>
<span class="go">foo</span>
<span class="go">=> nil</span>
</pre></div>
</div>
<div class="label" id="sec-single_quoted_strings"></div>
<h4><a id="sec-4_2_2_2" href="rails-flavored-ruby.html#sec-single_quoted_strings" class="heading">Single-quoted strings</a></h4>
<p>All the examples so far have used <em>double-quoted strings</em>, but Ruby also supports <em>single-quoted</em> strings. For many uses, the two types of strings are effectively identical:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s1">'foo'</span> <span class="c1"># A single-quoted string</span>
<span class="go">=> "foo"</span>
<span class="gp">>> </span><span class="s1">'foo'</span> <span class="o">+</span> <span class="s1">'bar'</span>
<span class="go">=> "foobar"</span>
</pre></div>
</div>
<p>There’s an important difference, though; Ruby won’t interpolate into single-quoted strings:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s1">'#{foo} bar'</span> <span class="c1"># Single-quoted strings don't allow interpolation</span>
<span class="go">=> "\#{foo} bar"</span>
</pre></div>
</div>
<p>Note how the console returns values using double-quoted strings, which requires a backslash to <em>escape</em> special characters such as <code>#</code>.</p>
<p>If double-quoted strings can do everything that single-quoted strings can do, and interpolate to boot, what’s the point of single-quoted strings? They are often useful because they are truly literal, and contain exactly the characters you type. For example, the “backslash” character is special on most systems, as in the literal newline <tt class="verb">\n</tt>. If you want a variable to contain a literal backslash, single quotes make it easier:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s1">'\n'</span> <span class="c1"># A literal 'backslash n' combination</span>
<span class="go">=> "\\n"</span>
</pre></div>
</div>
<p>As with the <code>#</code> character in our previous example, Ruby needs to escape the backslash with an additional backslash; inside double-quoted strings, a literal backslash is represented with <em>two</em> backslashes. For a small example like this, there’s not much savings, but if there are lots of things to escape it can be a real help:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s1">'Newlines (\n) and tabs (\t) both use the backslash character \.'</span>
<span class="go">=> "Newlines (\\n) and tabs (\\t) both use the backslash character \\."</span>
</pre></div>
</div>
<div class="label" id="sec-objects_and_message_passing"></div>
<h3><a id="sec-4_2_3" href="rails-flavored-ruby.html#sec-objects_and_message_passing" class="heading"><span class="number">4.2.3</span> Objects and message passing</a></h3>
<p>Everything in Ruby, including strings and even <code>nil</code>, is an <em>object</em>. We’ll see the technical meaning of this in <a class="ref" href="rails-flavored-ruby.html#sec-a_class_of_our_own">Section 4.4.2</a>, but I don’t think anyone ever understood objects by reading the definition in a book; you have to build up your intuition for objects by seeing lots of examples.</p>
<p>It’s easier to describe what objects <em>do</em>, which is respond to messages. An object like a string, for example, can respond to the message <code>length</code>, which returns the number of characters in the string:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s2">"foobar"</span><span class="o">.</span><span class="n">length</span> <span class="c1"># Passing the "length" message to a string</span>
<span class="go">=> 6</span>
</pre></div>
</div>
<p>Typically, the messages that get passed to objects are <em>methods</em>, which are functions defined on those objects.<sup class="footnote" id="fnref-4_4"><a href="#fn-4_4">4</a></sup> Strings also respond to the <code>empty?</code> method:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s2">"foobar"</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">=> false</span>
<span class="gp">>> </span><span class="s2">""</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">=> true</span>
</pre></div>
</div>
<p>Note the question mark at the end of the <code>empty?</code> method. This is a Ruby convention indicating that the return value is <em>boolean</em>: <code>true</code> or <code>false</code>. Booleans are especially useful for <em>control flow</em>:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">s</span> <span class="o">=</span> <span class="s2">"foobar"</span>
<span class="gp">>> </span><span class="k">if</span> <span class="n">s</span><span class="o">.</span><span class="n">empty?</span>
<span class="gp">>> </span> <span class="s2">"The string is empty"</span>
<span class="gp">>> </span><span class="k">else</span>
<span class="gp">>> </span> <span class="s2">"The string is nonempty"</span>
<span class="gp">>> </span><span class="k">end</span>
<span class="go">=> "The string is nonempty"</span>
</pre></div>
</div>
<p>Booleans can also be combined using the <code>&&</code> (“and”), <code>||</code> (“or”), and <code>!</code> (“not”) operators:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">x</span> <span class="o">=</span> <span class="s2">"foo"</span>
<span class="go">=> "foo"</span>
<span class="gp">>> </span><span class="n">y</span> <span class="o">=</span> <span class="s2">""</span>
<span class="go">=> ""</span>
<span class="gp">>> </span><span class="nb">puts</span> <span class="s2">"Both strings are empty"</span> <span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">empty?</span> <span class="o">&&</span> <span class="n">y</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">=> nil</span>
<span class="gp">>> </span><span class="nb">puts</span> <span class="s2">"One of the strings is empty"</span> <span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">empty?</span> <span class="o">||</span> <span class="n">y</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">"One of the strings is empty"</span>
<span class="go">=> nil</span>
<span class="gp">>> </span><span class="nb">puts</span> <span class="s2">"x is not empty"</span> <span class="k">if</span> <span class="o">!</span><span class="n">x</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">"x is not empty"</span>
<span class="go">=> nil</span>
</pre></div>
</div>
<p>Since everything in Ruby is an object, it follows that <code>nil</code> is an object, so it too can respond to methods. One example is the <code>to_s</code> method that can convert virtually any object to a string:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="kp">nil</span><span class="o">.</span><span class="n">to_s</span>
<span class="go">=> ""</span>
</pre></div>
</div>
<p>This certainly appears to be an empty string, as we can verify by <em>chaining</em> the messages we pass to <code>nil</code>:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="kp">nil</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">NoMethodError: You have a nil object when you didn't expect it!</span>
<span class="go">You might have expected an instance of Array.</span>
<span class="go">The error occurred while evaluating nil.empty?</span>
<span class="gp">>> </span><span class="kp">nil</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">empty?</span> <span class="c1"># Message chaining</span>
<span class="go">=> true</span>
</pre></div>
</div>
<p>We see here that the <code>nil</code> object doesn’t itself respond to the <code>empty?</code> method, but <code>nil.to_s</code> does.</p>
<p>There’s a special method for testing for <code>nil</code>-ness, which you might be able to guess:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s2">"foo"</span><span class="o">.</span><span class="n">nil?</span>
<span class="go">=> false</span>
<span class="gp">>> </span><span class="s2">""</span><span class="o">.</span><span class="n">nil?</span>
<span class="go">=> false</span>
<span class="gp">>> </span><span class="kp">nil</span><span class="o">.</span><span class="n">nil?</span>
<span class="go">=> true</span>
</pre></div>
</div>
<p>The code</p>
<div class="code"><div class="highlight"><pre><span class="nb">puts</span> <span class="s2">"x is not empty"</span> <span class="k">if</span> <span class="o">!</span><span class="n">x</span><span class="o">.</span><span class="n">empty?</span>
</pre></div>
</div>
<p>also shows an alternate use of the <code>if</code> keyword: Ruby allows you to write a statement that is evaluated only if the statement following <code>if</code> is true. There’s a complementary <code>unless</code> keyword that works the same way:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">string</span> <span class="o">=</span> <span class="s2">"foobar"</span>
<span class="gp">>> </span><span class="nb">puts</span> <span class="s2">"The string '</span><span class="si">#{</span><span class="n">string</span><span class="si">}</span><span class="s2">' is nonempty."</span> <span class="k">unless</span> <span class="n">string</span><span class="o">.</span><span class="n">empty?</span>
<span class="go">The string 'foobar' is nonempty.</span>
<span class="go">=> nil</span>
</pre></div>
</div>
<p>It’s worth noting that the <code>nil</code> object is special, in that it is the <em>only</em> Ruby object that is false in a boolean context, apart from <code>false</code> itself:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="k">if</span> <span class="kp">nil</span>
<span class="gp">>> </span> <span class="kp">true</span>
<span class="gp">>> </span><span class="k">else</span>
<span class="gp">>> </span> <span class="kp">false</span> <span class="c1"># nil is false</span>
<span class="gp">>> </span><span class="k">end</span>
<span class="go">=> false</span>
</pre></div>
</div>
<p>In particular, all other Ruby objects are <em>true</em>, even 0:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="k">if</span> <span class="mi">0</span>
<span class="gp">>> </span> <span class="kp">true</span> <span class="c1"># 0 (and everything other than nil and false itself) is true</span>
<span class="gp">>> </span><span class="k">else</span>
<span class="gp">>> </span> <span class="kp">false</span>
<span class="gp">>> </span><span class="k">end</span>
<span class="go">=> true</span>
</pre></div>
</div>
<div class="label" id="sec-method_definitions"></div>
<h3><a id="sec-4_2_4" href="rails-flavored-ruby.html#sec-method_definitions" class="heading"><span class="number">4.2.4</span> Method definitions</a></h3>
<p>The console allows us to define methods the same way we did with the <code>home</code> action from <a class="ref" href="static-pages.html#code-static_pages_controller">Listing 3.6</a> or the <code>full_title</code> helper from <a class="ref" href="rails-flavored-ruby.html#code-title_helper">Listing 4.2</a>. (Defining methods in the console is a bit cumbersome, and ordinarily you would use a file, but it’s convenient for demonstration purposes.) For example, let’s define a function <code>string_message</code> that takes a single <em>argument</em> and returns a message based on whether the argument is empty or not:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="k">def</span> <span class="nf">string_message</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="gp">>> </span> <span class="k">if</span> <span class="n">string</span><span class="o">.</span><span class="n">empty?</span>
<span class="gp">>> </span> <span class="s2">"It's an empty string!"</span>
<span class="gp">>> </span> <span class="k">else</span>
<span class="gp">>> </span> <span class="s2">"The string is nonempty."</span>
<span class="gp">>> </span> <span class="k">end</span>
<span class="gp">>> </span><span class="k">end</span>
<span class="go">=> nil</span>
<span class="gp">>> </span><span class="nb">puts</span> <span class="n">string_message</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="go">It's an empty string!</span>
<span class="gp">>> </span><span class="nb">puts</span> <span class="n">string_message</span><span class="p">(</span><span class="s2">"foobar"</span><span class="p">)</span>
<span class="go">The string is nonempty.</span>
</pre></div>
</div>
<p>Note that Ruby functions have an <em>implicit return</em>, meaning they return the last statement evaluated—in this case, one of the two message strings, depending on whether the method’s argument <code>string</code> is empty or not. Ruby also has an explicit return option; the following function is equivalent to the one above:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="k">def</span> <span class="nf">string_message</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="gp">>> </span> <span class="k">return</span> <span class="s2">"It's an empty string!"</span> <span class="k">if</span> <span class="n">string</span><span class="o">.</span><span class="n">empty?</span>
<span class="gp">>> </span> <span class="k">return</span> <span class="s2">"The string is nonempty."</span>
<span class="gp">>> </span><span class="k">end</span>
</pre></div>
</div>
<p>The alert reader might notice at this point that the second <code>return</code> here is actually unnecessary—being the last expression in the function, the string <code>"The string is nonempty."</code> will be returned regardless of the <code>return</code> keyword, but using <code>return</code> in both places has a pleasing symmetry to it.</p>
<div class="label" id="sec-back_to_the_title_helper"></div>
<h3><a id="sec-4_2_5" href="rails-flavored-ruby.html#sec-back_to_the_title_helper" class="heading"><span class="number">4.2.5</span> Back to the title helper</a></h3>
<p>We are now in a position to understand the <code>full_title</code> helper from <a class="ref" href="rails-flavored-ruby.html#code-title_helper">Listing 4.2</a>:<sup class="footnote" id="fnref-4_5"><a href="#fn-4_5">5</a></sup></p>
<div class="code"><div class="highlight"><pre><span class="k">module</span> <span class="nn">ApplicationHelper</span>
<span class="c1"># Returns the full title on a per-page basis. # Documentation comment</span>
<span class="k">def</span> <span class="nf">full_title</span><span class="p">(</span><span class="n">page_title</span><span class="p">)</span> <span class="c1"># Method definition</span>
<span class="n">base_title</span> <span class="o">=</span> <span class="s2">"Ruby on Rails Tutorial Sample App"</span> <span class="c1"># Variable assignment</span>
<span class="k">if</span> <span class="n">page_title</span><span class="o">.</span><span class="n">empty?</span> <span class="c1"># Boolean test</span>
<span class="n">base_title</span> <span class="c1"># Implicit return</span>
<span class="k">else</span>
<span class="s2">"</span><span class="si">#{</span><span class="n">base_title</span><span class="si">}</span><span class="s2"> | </span><span class="si">#{</span><span class="n">page_title</span><span class="si">}</span><span class="s2">"</span> <span class="c1"># String interpolation</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div>
<p>These elements—function definition, variable assignment, boolean tests, control flow, and string interpolation—come together to make a compact helper method for use in our site layout. The final element is <code>module ApplicationHelper</code>: modules give us a way to package together related methods, which can then be <em>mixed in</em> to Ruby classes using <code>include</code>. When writing ordinary Ruby, you often write modules and include them explicitly yourself, but in the case of a helper module Rails handles the inclusion for us. The result is that the <code>full_title</code> method is <a href="http://catb.org/jargon/html/A/automagically.html">automagically</a> available in all our views.</p>
<div class="label" id="sec-other_data_structures"></div>
<h2><a id="sec-4_3" href="rails-flavored-ruby.html#sec-other_data_structures" class="heading"><span class="number">4.3</span> Other data structures</a></h2>
<p>Although web apps are ultimately about strings, actually <em>making</em> those strings requires using other data structures as well. In this section, we’ll learn about some Ruby data structures important for writing Rails applications.</p>
<div class="label" id="sec-arrays_and_ranges"></div>
<h3><a id="sec-4_3_1" href="rails-flavored-ruby.html#sec-arrays_and_ranges" class="heading"><span class="number">4.3.1</span> Arrays and ranges</a></h3>
<p>An array is just a list of elements in a particular order. We haven’t discussed arrays yet in the <em>Rails Tutorial</em>, but understanding them gives a good foundation for understanding hashes (<a class="ref" href="rails-flavored-ruby.html#sec-hashes_and_symbols">Section 4.3.3</a>) and for aspects of Rails data modeling (such as the <code>has_many</code> association seen in <a class="ref" href="a-demo-app.html#sec-demo_user_has_many_microposts">Section 2.3.3</a> and covered more in <a class="ref" href="user-microposts.html#sec-user_micropost_associations">Section 10.1.3</a>).</p>
<p>So far we’ve spent a lot of time understanding strings, and there’s a natural way to get from strings to arrays using the <code>split</code> method:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span> <span class="s2">"foo bar baz"</span><span class="o">.</span><span class="n">split</span> <span class="c1"># Split a string into a three-element array</span>
<span class="go">=> ["foo", "bar", "baz"]</span>
</pre></div>
</div>
<p>The result of this operation is an array of three strings. By default, <code>split</code> divides a string into an array by splitting on whitespace, but you can split on nearly anything else as well:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="s2">"fooxbarxbazx"</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'x'</span><span class="p">)</span>
<span class="go">=> ["foo", "bar", "baz"]</span>
</pre></div>
</div>
<p>As is conventional in most computer languages, Ruby arrays are <em>zero-offset</em>, which means that the first element in the array has index 0, the second has index 1, and so on:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span> <span class="o">=</span> <span class="o">[</span><span class="mi">42</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">17</span><span class="o">]</span>
<span class="go">=> [42, 8, 17]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="c1"># Ruby uses square brackets for array access.</span>
<span class="go">=> 42</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span>
<span class="go">=> 8</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span>
<span class="go">=> 17</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">[-</span><span class="mi">1</span><span class="o">]</span> <span class="c1"># Indices can even be negative!</span>
<span class="go">=> 17</span>
</pre></div>
</div>
<p>We see here that Ruby uses square brackets to access array elements.
In addition to this bracket notation, Ruby offers synonyms for some commonly accessed elements:<sup class="footnote" id="fnref-4_6"><a href="#fn-4_6">6</a></sup></p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span> <span class="c1"># Just a reminder of what 'a' is</span>
<span class="go">=> [42, 8, 17]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">first</span>
<span class="go">=> 42</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">second</span>
<span class="go">=> 8</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">last</span>
<span class="go">=> 17</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">last</span> <span class="o">==</span> <span class="n">a</span><span class="o">[-</span><span class="mi">1</span><span class="o">]</span> <span class="c1"># Comparison using ==</span>
<span class="go">=> true</span>
</pre></div>
</div>
<p>This last line introduces the equality comparison operator <code>==</code>, which Ruby shares with many other languages, along with the associated <code>!=</code> (“not equal”), etc.:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">x</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">length</span> <span class="c1"># Like strings, arrays respond to the 'length' method.</span>
<span class="go">=> 3</span>
<span class="gp">>> </span><span class="n">x</span> <span class="o">==</span> <span class="mi">3</span>
<span class="go">=> true</span>
<span class="gp">>> </span><span class="n">x</span> <span class="o">==</span> <span class="mi">1</span>
<span class="go">=> false</span>
<span class="gp">>> </span><span class="n">x</span> <span class="o">!=</span> <span class="mi">1</span>
<span class="go">=> true</span>
<span class="gp">>> </span><span class="n">x</span> <span class="o">>=</span> <span class="mi">1</span>
<span class="go">=> true</span>
<span class="gp">>> </span><span class="n">x</span> <span class="o"><</span> <span class="mi">1</span>
<span class="go">=> false</span>
</pre></div>
</div>
<p>In addition to <code>length</code> (seen in the first line above), arrays respond to a wealth of other methods:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span>
<span class="go">=> [42, 8, 17]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">sort</span>
<span class="go">=> [8, 17, 42]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">reverse</span>
<span class="go">=> [17, 8, 42]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">shuffle</span>
<span class="go">=> [17, 42, 8]</span>
<span class="gp">>> </span><span class="n">a</span>
<span class="go">=> [42, 8, 17]</span>
</pre></div>
</div>
<p>Note that none of the methods above changes <code>a</code> itself. To <em>mutate</em> the array, use the corresponding “bang” methods (so-called because the exclamation point is usually pronounced “bang” in this context):</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span>
<span class="go">=> [42, 8, 17]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">sort!</span>
<span class="go">=> [8, 17, 42]</span>
<span class="gp">>> </span><span class="n">a</span>
<span class="go">=> [8, 17, 42]</span>
</pre></div>
</div>
<p>You can also add to arrays with the <code>push</code> method or its equivalent operator, <tt class="verb"><<</tt>:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span> <span class="c1"># Pushing 6 onto an array</span>
<span class="go">=> [42, 8, 17, 6]</span>
<span class="gp">>> </span><span class="n">a</span> <span class="o"><<</span> <span class="mi">7</span> <span class="c1"># Pushing 7 onto an array</span>
<span class="go">=> [42, 8, 17, 6, 7]</span>
<span class="gp">>> </span><span class="n">a</span> <span class="o"><<</span> <span class="s2">"foo"</span> <span class="o"><<</span> <span class="s2">"bar"</span> <span class="c1"># Chaining array pushes</span>
<span class="go">=> [42, 8, 17, 6, 7, "foo", "bar"]</span>
</pre></div>
</div>
<p>This last example shows that you can chain pushes together, and also that, unlike arrays in many other languages, Ruby arrays can contain a mixture of different types (in this case, integers and strings).</p>
<p>Before we saw <code>split</code> convert a string to an array. We can also go the other way with the <code>join</code> method:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span>
<span class="go">=> [42, 8, 17, 7, "foo", "bar"]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">join</span> <span class="c1"># Join on nothing</span>
<span class="go">=> "428177foobar"</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">', '</span><span class="p">)</span> <span class="c1"># Join on comma-space</span>
<span class="go">=> "42, 8, 17, 7, foo, bar"</span>
</pre></div>
</div>
<p>Closely related to arrays are <em>ranges</em>, which can probably most easily be understood by converting them to arrays using the <code>to_a</code> method:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">9</span>
<span class="go">=> 0..9</span>
<span class="gp">>> </span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">9</span><span class="o">.</span><span class="n">to_a</span> <span class="c1"># Oops, call to_a on 9</span>
<span class="go">NoMethodError: undefined method `to_a' for 9:Fixnum</span>
<span class="gp">>> </span><span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">9</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span> <span class="c1"># Use parentheses to call to_a on the range</span>
<span class="go">=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</span>
</pre></div>
</div>
<p>Though <code>0..9</code> is a valid range, the second expression above shows that we need to add parentheses to call a method on it.</p>
<p>Ranges are useful for pulling out array elements:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">a</span> <span class="o">=</span> <span class="sx">%w[foo bar baz quux]</span> <span class="c1"># Use %w to make a string array.</span>
<span class="go">=> ["foo", "bar", "baz", "quux"]</span>
<span class="gp">>> </span><span class="n">a</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">2</span><span class="o">]</span>
<span class="go">=> ["foo", "bar", "baz"]</span>
</pre></div>
</div>
<p>Ranges also work with characters:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="p">(</span><span class="s1">'a'</span><span class="o">.</span><span class="n">.</span><span class="s1">'e'</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span>
<span class="go">=> ["a", "b", "c", "d", "e"]</span>
</pre></div>
</div>
<div class="label" id="sec-blocks"></div>
<h3><a id="sec-4_3_2" href="rails-flavored-ruby.html#sec-blocks" class="heading"><span class="number">4.3.2</span> Blocks</a></h3>
<p>Both arrays and ranges respond to a host of methods that accept <em>blocks</em>, which are simultaneously one of Ruby’s most powerful and most confusing features:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">puts</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="p">}</span>
<span class="go">2</span>
<span class="go">4</span>
<span class="go">6</span>
<span class="go">8</span>
<span class="go">10</span>
<span class="go">=> 1..5</span>
</pre></div>
</div>
<p>This code calls the <code>each</code> method on the range <code>(1..5)</code> and passes it the block <code>{ |i| puts 2 * i }</code>. The vertical bars around the variable name in <code>|i|</code> are Ruby syntax for a block variable, and it’s up to the method to know what to do with the block. In this case, the range’s <code>each</code> method can handle a block with a single local variable, which we’ve called <code>i</code>, and it just executes the block for each value in the range.</p>
<p>Curly braces are one way to indicate a block, but there is a second way as well:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="gp">?> </span> <span class="nb">puts</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span>
<span class="gp">>> </span><span class="k">end</span>
<span class="go">2</span>
<span class="go">4</span>
<span class="go">6</span>
<span class="go">8</span>
<span class="go">10</span>
<span class="go">=> 1..5</span>
</pre></div>
</div>
<p>Blocks can be more than one line, and often are. In the <em>Rails Tutorial</em> we’ll follow the common convention of using curly braces only for short one-line blocks and the <code>do..end</code> syntax for longer one-liners and for multi-line blocks:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">number</span><span class="o">|</span>
<span class="gp">?> </span> <span class="nb">puts</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">number</span>
<span class="gp">>> </span> <span class="nb">puts</span> <span class="s1">'--'</span>
<span class="gp">>> </span><span class="k">end</span>
<span class="go">2</span>
<span class="go">--</span>
<span class="go">4</span>
<span class="go">--</span>
<span class="go">6</span>
<span class="go">--</span>
<span class="go">8</span>
<span class="go">--</span>
<span class="go">10</span>
<span class="go">--</span>
<span class="go">=> 1..5</span>
</pre></div>
</div>
<p>Here I’ve used <code>number</code> in place of <code>i</code> just to emphasize that any variable name will do.</p>
<p>Unless you already have a substantial programming background, there is no shortcut to understanding blocks; you just have to see them a lot, and eventually you’ll get used to them.<sup class="footnote" id="fnref-4_7"><a href="#fn-4_7">7</a></sup> Luckily, humans are quite good at making generalizations from concrete examples; here are a few more, including a couple using the <code>map</code> method:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="mi">3</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"Betelgeuse!"</span> <span class="p">}</span> <span class="c1"># 3.times takes a block with no variables.</span>
<span class="go">"Betelgeuse!"</span>
<span class="go">"Betelgeuse!"</span>
<span class="go">"Betelgeuse!"</span>
<span class="go">=> 3</span>
<span class="gp">>> </span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span><span class="o">**</span><span class="mi">2</span> <span class="p">}</span> <span class="c1"># The ** notation is for 'power'.</span>
<span class="go">=> [1, 4, 9, 16, 25]</span>
<span class="gp">>> </span><span class="sx">%w[a b c]</span> <span class="c1"># Recall that %w makes string arrays.</span>
<span class="go">=> ["a", "b", "c"]</span>
<span class="gp">>> </span><span class="sx">%w[a b c]</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">char</span><span class="o">|</span> <span class="n">char</span><span class="o">.</span><span class="n">upcase</span> <span class="p">}</span>
<span class="go">=> ["A", "B", "C"]</span>
<span class="gp">>> </span><span class="sx">%w[A B C]</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">char</span><span class="o">|</span> <span class="n">char</span><span class="o">.</span><span class="n">downcase</span> <span class="p">}</span>
<span class="go">=> ["a", "b", "c"]</span>
</pre></div>
</div>
<p>As you can see, the <code>map</code> method returns the result of applying the given block to each element in the array or range.</p>
<p>By the way, we’re now in a position to understand the line of Ruby I threw into <a class="ref" href="beginning.html#sec-heroku_commands">Section 1.4.4</a> to generate random subdomains:</p>
<div class="code"><div class="highlight"><pre><span class="p">(</span><span class="s1">'a'</span><span class="o">.</span><span class="n">.</span><span class="s1">'z'</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">shuffle</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">7</span><span class="o">].</span><span class="n">join</span>
</pre></div>
</div>
<p>Let’s build it up step-by-step:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="p">(</span><span class="s1">'a'</span><span class="o">.</span><span class="n">.</span><span class="s1">'z'</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span> <span class="c1"># An alphabet array</span>
<span class="go">=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",</span>
<span class="go">"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]</span>
<span class="gp">>> </span><span class="p">(</span><span class="s1">'a'</span><span class="o">.</span><span class="n">.</span><span class="s1">'z'</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">shuffle</span> <span class="c1"># Shuffle it.</span>
<span class="go">=> ["c", "g", "l", "k", "h", "z", "s", "i", "n", "d", "y", "u", "t", "j", "q",</span>
<span class="go">"b", "r", "o", "f", "e", "w", "v", "m", "a", "x", "p"]</span>
<span class="gp">>> </span><span class="p">(</span><span class="s1">'a'</span><span class="o">.</span><span class="n">.</span><span class="s1">'z'</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">shuffle</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">7</span><span class="o">]</span> <span class="c1"># Pull out the first eight elements.</span>
<span class="go">=> ["f", "w", "i", "a", "h", "p", "c", "x"]</span>
<span class="gp">>> </span><span class="p">(</span><span class="s1">'a'</span><span class="o">.</span><span class="n">.</span><span class="s1">'z'</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">shuffle</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">7</span><span class="o">].</span><span class="n">join</span> <span class="c1"># Join them together to make one string.</span>
<span class="go">=> "mznpybuj"</span>
</pre></div>
</div>
<div class="label" id="sec-hashes_and_symbols"></div>
<h3><a id="sec-4_3_3" href="rails-flavored-ruby.html#sec-hashes_and_symbols" class="heading"><span class="number">4.3.3</span> Hashes and symbols</a></h3>
<p>Hashes are essentially a generalization of arrays: you can think of hashes as basically like arrays, but not limited to integer indices. (In fact, some languages, especially Perl, sometimes call hashes <em>associative arrays</em> for this reason.) Instead, hash indices, or <em>keys</em>, can be almost any object. For example, we can use strings as keys:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">user</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># {} is an empty hash.</span>
<span class="go">=> {}</span>
<span class="gp">>> </span><span class="n">user</span><span class="o">[</span><span class="s2">"first_name"</span><span class="o">]</span> <span class="o">=</span> <span class="s2">"Michael"</span> <span class="c1"># Key "first_name", value "Michael"</span>
<span class="go">=> "Michael"</span>
<span class="gp">>> </span><span class="n">user</span><span class="o">[</span><span class="s2">"last_name"</span><span class="o">]</span> <span class="o">=</span> <span class="s2">"Hartl"</span> <span class="c1"># Key "last_name", value "Hartl"</span>
<span class="go">=> "Hartl"</span>
<span class="gp">>> </span><span class="n">user</span><span class="o">[</span><span class="s2">"first_name"</span><span class="o">]</span> <span class="c1"># Element access is like arrays.</span>
<span class="go">=> "Michael"</span>
<span class="gp">>> </span><span class="n">user</span> <span class="c1"># A literal representation of the hash</span>
<span class="go">=> {"last_name"=>"Hartl", "first_name"=>"Michael"}</span>
</pre></div>
</div>
<p>Hashes are indicated with curly braces containing key-value pairs; a pair of braces with no key-value pairs—i.e., <code>{}</code>—is an empty hash. It’s important to note that the curly braces for hashes have nothing to do with the curly braces for blocks. (Yes, this can be confusing.) Although hashes resemble arrays, one important difference is that hashes don’t generally guarantee keeping their elements in a particular order.<sup class="footnote" id="fnref-4_8"><a href="#fn-4_8">8</a></sup> If order matters, use an array.</p>
<p>Instead of defining hashes one item at a time using square brackets, it’s easy to use a literal representation with keys and values separated by <code>=></code>, called a “hashrocket”:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">user</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"first_name"</span> <span class="o">=></span> <span class="s2">"Michael"</span><span class="p">,</span> <span class="s2">"last_name"</span> <span class="o">=></span> <span class="s2">"Hartl"</span> <span class="p">}</span>
<span class="go">=> {"last_name"=>"Hartl", "first_name"=>"Michael"}</span>
</pre></div>
</div>
<p>Here I’ve used the usual Ruby convention of putting an extra space at the two ends of the hash—a convention ignored by the console output. (Don’t ask me why the spaces are conventional; probably some early influential Ruby programmer liked the look of the extra spaces, and the convention stuck.)</p>
<p>So far we’ve used strings as hash keys, but in Rails it is much more common to use <em>symbols</em> instead. Symbols look kind of like strings, but prefixed with a colon instead of surrounded by quotes. For example, <code>:name</code> is a symbol. You can think of symbols as basically strings without all the extra baggage:<sup class="footnote" id="fnref-4_9"><a href="#fn-4_9">9</a></sup></p>