forked from mhartl/rails_tutorial_translation_2nd_ed
-
Notifications
You must be signed in to change notification settings - Fork 1
/
sign-up.html
2067 lines (1295 loc) · 206 KB
/
sign-up.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>sign-up</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-7" href="sign-up.html#top" class="heading"><span class="number">Chapter 7</span> Sign up</a></h1>
<p>Now that we have a working User model, it’s time to add an ability few websites can live without: letting users sign up for the site. We’ll use an HTML <em>form</em> to submit user signup information to our application in <a class="ref" href="sign-up.html#sec-signup_form">Section 7.2</a>, which will then be used to create a new user and save its attributes to the database in <a class="ref" href="sign-up.html#sec-signup_success">Section 7.4</a>. At the end of the signup process, it’s important to render a profile page with the newly created user’s information, so we’ll begin by making a page for <em>showing</em> users, which will serve as the first step toward implementing the REST architecture for users (<a class="ref" href="a-demo-app.html#sec-mvc_in_action">Section 2.2.2</a>). As usual, we’ll write tests as we develop, extending the theme of using RSpec and Capybara to write succinct and expressive integration tests.</p>
<p>In order to make a user profile page, we need to have a user in the database, which introduces a chicken-and-egg problem: how can the site have a user before there is a working signup page? Happily, this problem has already been solved: in <a class="ref" href="modeling-users.html#sec-creating_a_user">Section 6.3.5</a>, we created a User record by hand using the Rails console. If you skipped that section, you should go there now and complete it before proceeding.</p>
<p>If you’re following along with version control, make a topic branch as usual:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> git checkout master
<span class="gp">$</span> git checkout -b sign-up
</pre></div>
</div>
<div class="label" id="sec-showing_users"></div>
<h2><a id="sec-7_1" href="sign-up.html#sec-showing_users" class="heading"><span class="number">7.1</span> Showing users</a></h2>
<p>In this section, we’ll take the first steps toward the final profile by making a page to display a user’s name and profile photo, as indicated by the mockup in <a class="ref" href="sign-up.html#fig-profile_mockup_profile_name">Figure 7.1</a>.<sup class="footnote" id="fnref-7_1"><a href="#fn-7_1">1</a></sup> Our eventual goal for the user profile pages is to show the user’s profile image, basic user data, and a list of microposts, as mocked up in <a class="ref" href="sign-up.html#fig-profile_mockup">Figure 7.2</a>.<sup class="footnote" id="fnref-7_2"><a href="#fn-7_2">2</a></sup> (<a class="ref" href="sign-up.html#fig-profile_mockup">Figure 7.2</a> has our first example of <em>lorem ipsum</em> text, which has a <a href="http://www.straightdope.com/columns/read/2290/what-does-the-filler-text-lorem-ipsum-mean">fascinating story</a> that you should definitely read about some time.) We’ll complete this task, and with it the sample application, in <a class="ref" href="following-users.html#top">Chapter 11</a>.</p>
<div class="label" id="fig-profile_mockup_profile_name"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/profile_mockup_profile_name_bootstrap.png" alt="profile_mockup_profile_name_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.1: </span><span class="description">A mockup of the user profile made in this section. <a href="http://railstutorial.org/images/figures/profile_mockup_profile_name_bootstrap-full.png">(full size)</a></span></div></div>
<div class="label" id="fig-profile_mockup"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/profile_mockup_bootstrap.png" alt="profile_mockup_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.2: </span><span class="description">A mockup of our best guess at the final profile page. <a href="http://railstutorial.org/images/figures/profile_mockup_bootstrap-full.png">(full size)</a></span></div></div>
<div class="label" id="sec-rails_environments"></div>
<h3><a id="sec-7_1_1" href="sign-up.html#sec-rails_environments" class="heading"><span class="number">7.1.1</span> Debug and Rails environments</a></h3>
<p>The profiles in this section will be the first truly dynamic pages in our application. Although the view will exist as a single page of code, each profile will be customized using information retrieved from the site’s database. As preparation for adding dynamic pages to our sample application, now is a good time to add some debug information to our site layout (<a class="ref" href="sign-up.html#code-rails_debug">Listing 7.1</a>). This displays some useful information about each page using the built-in <code>debug</code> method and <code>params</code> variable (which we’ll learn more about in <a class="ref" href="sign-up.html#sec-a_users_resource">Section 7.1.2</a>).</p>
<div class="label" id="code-rails_debug"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.1.</span> <span class="description">Adding some debug information to the 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"><body></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/header'</span> <span class="cp">%></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
<span class="cp"><%=</span> <span class="k">yield</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">render</span> <span class="s1">'layouts/footer'</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="n">debug</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="k">if</span> <span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">development?</span> <span class="cp">%></span>
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</pre></div>
</div></div>
<p>To make the debug output look nice, we’ll add some rules to the custom stylesheet created in <a class="ref" href="filling-in-the-layout.html#top">Chapter 5</a>, as shown in <a class="ref" href="sign-up.html#code-mixin_and_debug">Listing 7.2</a>.</p>
<div class="label" id="code-mixin_and_debug"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.2.</span> <span class="description">Adding code for a pretty debug box, including a Sass mixin. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">@import</span> <span class="s2">"bootstrap"</span><span class="p">;</span>
<span class="cm">/* mixins, variables, etc. */</span>
<span class="nv">$grayMediumLight</span><span class="o">:</span> <span class="mh">#eaeaea</span><span class="p">;</span>
<span class="k">@mixin</span><span class="nf"> box_sizing</span> <span class="p">{</span>
<span class="na">-moz-box-sizing</span><span class="o">:</span> <span class="no">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
<span class="na">-webkit-box-sizing</span><span class="o">:</span> <span class="no">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
<span class="na">box-sizing</span><span class="o">:</span> <span class="no">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="o">/*</span> <span class="nt">miscellaneous</span> <span class="o">*/</span>
<span class="nc">.debug_dump</span> <span class="p">{</span>
<span class="na">clear</span><span class="o">:</span> <span class="no">both</span><span class="p">;</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
<span class="na">margin-top</span><span class="o">:</span> <span class="mi">45</span><span class="kt">px</span><span class="p">;</span>
<span class="k">@include</span><span class="nd"> box_sizing</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div></div>
<p>This introduces the Sass <em>mixin</em> facility, in this case called <code>box_sizing</code>. A mixin allows a group of CSS rules to be packaged up and used for multiple elements, converting</p>
<div class="code"><div class="highlight"><pre><span class="nc">.debug_dump</span> <span class="p">{</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="o">@</span><span class="nt">include</span> <span class="nt">box_sizing</span><span class="o">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>to</p>
<div class="code"><div class="highlight"><pre><span class="nc">.debug_dump</span> <span class="p">{</span>
<span class="na">.</span>
<span class="na">.</span>
<span class="na">.</span>
<span class="na">-moz-box-sizing</span><span class="o">:</span> <span class="no">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
<span class="na">-webkit-box-sizing</span><span class="o">:</span> <span class="no">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
<span class="na">box-sizing</span><span class="o">:</span> <span class="no">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>We’ll put this mixin to use again in <a class="ref" href="sign-up.html#sec-using_form_for">Section 7.2.2</a>. The result in the case of the debug box is shown in <a class="ref" href="sign-up.html#fig-home_page_with_debug_2nd_ed">Figure 7.3</a>.</p>
<div class="label" id="fig-home_page_with_debug_2nd_ed"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/home_page_with_debug_2nd_ed.png" alt="home_page_with_debug_2nd_ed" /></span></div><div class="caption"><span class="header">Figure 7.3: </span><span class="description">The sample application Home page (<a href="http://localhost:3000/">/</a>) with debug information. <a href="http://railstutorial.org/images/figures/home_page_with_debug_2nd_ed-full.png">(full size)</a></span></div></div>
<p>The debug output in <a class="ref" href="sign-up.html#fig-home_page_with_debug_2nd_ed">Figure 7.3</a> gives potentially useful information about the page being rendered:</p>
<div class="code"><div class="highlight"><pre><span class="nn">---</span>
<span class="l-Scalar-Plain">controller</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">static_pages</span>
<span class="l-Scalar-Plain">action</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">home</span>
</pre></div>
</div>
<p>This is a YAML<sup class="footnote" id="fnref-7_3"><a href="#fn-7_3">3</a></sup> representation of <code>params</code>, which is basically a hash, and in this case identifies the controller and action for the page. We’ll see another example in <a class="ref" href="sign-up.html#sec-a_users_resource">Section 7.1.2</a></p>
<p>Since we don’t want to display debug information to users of a deployed application, <a class="ref" href="sign-up.html#code-rails_debug">Listing 7.1</a> uses</p>
<div class="code"><div class="highlight"><pre><span class="k">if</span> <span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">development?</span>
</pre></div>
</div>
<p>to restrict the debug information to the <em>development environment</em>, which is one of three environments defined by default in Rails (<a class="ref" href="sign-up.html#sidebar-rails_environments">Box 7.1</a>).<sup class="footnote" id="fnref-7_4"><a href="#fn-7_4">4</a></sup> In particular, <code>Rails.env.development?</code> is <code>true</code> only in a development environment, so the Embedded Ruby</p>
<div class="code"><div class="highlight"><pre><span class="cp"><%=</span> <span class="n">debug</span><span class="p">(</span><span class="n">params</span><span class="p">)</span> <span class="k">if</span> <span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">development?</span> <span class="cp">%></span>
</pre></div>
</div>
<p>won’t be inserted into production applications or tests. (Inserting the debug information into tests probably wouldn’t do any harm, but it probably wouldn’t do any good, either, so it’s best to restrict the debug display to development only.)</p>
<div class="label" id="sidebar-rails_environments"></div>
<div class="sidebar"><span class="title"><span class="header">Box 7.1.</span><span class="description">Rails environments</span></span>
<p>Rails comes equipped with three environments: <tt>test</tt>, <tt>development</tt>, and <tt>production</tt>. The default environment for the Rails console is <tt>development</tt>:</p>
<pre class="verbatim"> $ rails console
Loading development environment
>> Rails.env
=> "development"
>> Rails.env.development?
=> true
>> Rails.env.test?
=> false</pre>
<p>As you can see, Rails provides a <tt>Rails</tt> object with an <tt>env</tt> attribute and associated environment boolean methods, so that, for example, <tt>Rails.env.test?</tt> returns <tt>true</tt> in a test environment and <tt>false</tt> otherwise.</p>
<p>If you ever need to run a console in a different environment (to debug a test, for example), you can pass the environment as a parameter to the <tt>console</tt> script:</p>
<pre class="verbatim"> $ rails console test
Loading test environment
>> Rails.env
=> "test"
>> Rails.env.test?
=> true</pre>
<p>As with the console, <tt>development</tt> is the default environment for the local Rails server, but you can also run it in a different environment:</p>
<pre class="verbatim"> $ rails server --environment production</pre>
<p>If you view your app running in production, it won’t work without a production database, which we can create by running <tt>rake db:migrate</tt> in production:</p>
<pre class="verbatim"> $ bundle exec rake db:migrate RAILS_ENV=production</pre>
<p>(I find it confusing that the console, server, and migrate commands specify non-default environments in three mutually incompatible ways, which is why I bothered showing all three.)</p>
<p>By the way, if you have deployed your sample app to Heroku, you can see its environment using the <tt>heroku</tt> command, which provides its own (remote) console:</p>
<pre class="verbatim"> $ heroku run console
Ruby console for yourapp.herokuapp.com
>> Rails.env
=> "production"
>> Rails.env.production?
=> true</pre>
<p>Naturally, since Heroku is a platform for production sites, it runs each application in a production environment.</p>
</div>
<div class="label" id="sec-a_users_resource"></div>
<h3><a id="sec-7_1_2" href="sign-up.html#sec-a_users_resource" class="heading"><span class="number">7.1.2</span> A Users resource</a></h3>
<p>At the end of <a class="ref" href="modeling-users.html#top">Chapter 6</a>, we created a new user in the database. As seen in <a class="ref" href="modeling-users.html#sec-creating_a_user">Section 6.3.5</a>, this user has id <code>1</code>, and our goal now is to make a page to display this user’s information. We’ll follow the conventions of the REST architecture favored in Rails applications (<a class="ref" href="a-demo-app.html#sidebar-REST">Box 2.2</a>), which means representing data as <em>resources</em> that can be created, shown, updated, or destroyed—four actions corresponding to the four fundamental operations <tt>POST</tt>, <tt>GET</tt>, <tt>PUT</tt>, and <tt>DELETE</tt> defined by the <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">HTTP standard</a> (<a class="ref" href="static-pages.html#sidebar-get_etc">Box 3.2</a>).</p>
<p>When following REST principles, resources are typically referenced using the resource name and a unique identifier. What this means in the context of users—which we’re now thinking of as a Users <em>resource</em>—is that we should view the user with id <code>1</code> by issuing a <tt>GET</tt> request to the URI /users/1. Here the <code>show</code> action is <em>implicit</em> in the type of request—when Rails’ REST features are activated, <tt>GET</tt> requests are automatically handled by the <code>show</code> action.</p>
<p>We saw in <a class="ref" href="a-demo-app.html#sec-a_user_tour">Section 2.2.1</a> that the page for a user with id <code>1</code> has URI /users/1. Unfortunately, visiting that URI right now just gives an error (<a class="ref" href="sign-up.html#fig-profile_routing_error">Figure 7.4</a>).</p>
<div class="label" id="fig-profile_routing_error"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/profile_routing_error.png" alt="profile_routing_error" /></span></div><div class="caption"><span class="header">Figure 7.4: </span><span class="description">The error page for /users/1. <a href="http://railstutorial.org/images/figures/profile_routing_error-full.png">(full size)</a></span></div></div>
<p>We can get the REST-style URI to work by adding a single line to our routes file (<code>config/routes.rb</code>):</p>
<div class="code"><div class="highlight"><pre><span class="n">resources</span> <span class="ss">:users</span>
</pre></div>
</div>
<p>The result appears in <a class="ref" href="sign-up.html#code-users_resource">Listing 7.3</a>.</p>
<div class="label" id="code-users_resource"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.3.</span> <span class="description">Adding a Users resource to the routes file. <br /> <code>config/routes.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="ss">SampleApp::Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span>
<span class="n">resources</span> <span class="ss">:users</span>
<span class="n">root</span> <span class="ss">to:</span> <span class="s1">'static_pages#home'</span>
<span class="n">match</span> <span class="s1">'/signup'</span><span class="p">,</span> <span class="ss">to:</span> <span class="s1">'users#new'</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>You might have noticed that <a class="ref" href="sign-up.html#code-users_resource">Listing 7.3</a> removes the line</p>
<div class="code"><div class="highlight"><pre><span class="n">get</span> <span class="s2">"users/new"</span>
</pre></div>
</div>
<p>last seen in <a class="ref" href="filling-in-the-layout.html#code-signup_route">Listing 5.32</a>. This is because <code>resources :users</code> doesn’t just add a working /users/1 URI; it endows our sample application with <em>all</em> the actions needed for a RESTful Users resource,<sup class="footnote" id="fnref-7_5"><a href="#fn-7_5">5</a></sup> along with a large number of named routes (<a class="ref" href="filling-in-the-layout.html#sec-named_routes">Section 5.3.3</a>) for generating user URIs. The resulting correspondence of URIs, actions, and named routes is shown in <a class="ref" href="sign-up.html#table-RESTful_users">Table 7.1</a>. (Compare to <a class="ref" href="a-demo-app.html#table-demo_RESTful_users">Table 2.2</a>.) Over the course of the next three chapters, we’ll cover all of the other entries in <a class="ref" href="sign-up.html#table-RESTful_users">Table 7.1</a> as we fill in all the actions necessary to make Users a fully RESTful resource.</p>
<div class="label" id="table-RESTful_users"></div>
<div class="table"><div class="center">
<table class="tabular"><tr><th class="align_left"><strong>HTTP request</strong></th><th class="align_left"><strong>URI</strong></th><th class="align_left"><strong>Action</strong></th><th class="align_left"><strong>Named route</strong></th><th class="align_left"><strong>Purpose</strong></th></tr><tr class="top_bar"><td class="align_left"><tt>GET</tt></td><td class="align_left">/users</td><td class="align_left"><code>index</code></td><td class="align_left"><code>users_path</code></td><td class="align_left">page to list all users</td></tr><tr><td class="align_left"><tt>GET</tt></td><td class="align_left">/users/1</td><td class="align_left"><code>show</code></td><td class="align_left"><code>user_path(user)</code></td><td class="align_left">page to show user</td></tr><tr><td class="align_left"><tt>GET</tt></td><td class="align_left">/users/new</td><td class="align_left"><code>new</code></td><td class="align_left"><code>new_user_path</code></td><td class="align_left">page to make a new user (signup)</td></tr><tr><td class="align_left"><tt>POST</tt></td><td class="align_left">/users</td><td class="align_left"><code>create</code></td><td class="align_left"><code>users_path</code></td><td class="align_left">create a new user</td></tr><tr><td class="align_left"><tt>GET</tt></td><td class="align_left">/users/1/edit</td><td class="align_left"><code>edit</code></td><td class="align_left"><code>edit_user_path(user)</code></td><td class="align_left">page to edit user with id <code>1</code></td></tr><tr><td class="align_left"><tt>PUT</tt></td><td class="align_left">/users/1</td><td class="align_left"><code>update</code></td><td class="align_left"><code>user_path(user)</code></td><td class="align_left">update user</td></tr><tr><td class="align_left"><tt>DELETE</tt></td><td class="align_left">/users/1</td><td class="align_left"><code>destroy</code></td><td class="align_left"><code>user_path(user)</code></td><td class="align_left">delete user</td></tr></table></div><div class="caption"><span class="header">Table 7.1: </span><span class="description">RESTful routes provided by the Users resource in <a class="ref" href="sign-up.html#code-users_resource">Listing 7.3</a>.</span></div></div>
<p>With the code in <a class="ref" href="sign-up.html#code-users_resource">Listing 7.3</a>, the routing works, but there’s still no page there (<a class="ref" href="sign-up.html#fig-user_show_unknown_action_31">Figure 7.5</a>). To fix this, we’ll begin with a minimalist version of the profile page, which we’ll flesh out in <a class="ref" href="sign-up.html#sec-a_gravatar_image">Section 7.1.4</a>.</p>
<div class="label" id="fig-user_show_unknown_action_31"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/user_show_unknown_action_31.png" alt="user_show_unknown_action_31" /></span></div><div class="caption"><span class="header">Figure 7.5: </span><span class="description">The URI /users/1 with routing but no page. <a href="http://railstutorial.org/images/figures/user_show_unknown_action_31-full.png">(full size)</a></span></div></div>
<p>We’ll use the standard Rails location for showing a user, which is <code>app/views/users/show.html.erb</code>. Unlike the <code>new.html.erb</code> view, which we created with the generator in <a class="ref" href="filling-in-the-layout.html#code-generate_users_controller">Listing 5.28</a>, the <code>show.html.erb</code> file doesn’t currently exist, so you’ll have to create it by hand, filling it with the content shown in <a class="ref" href="sign-up.html#code-stub_user_view">Listing 7.4</a>.</p>
<div class="label" id="code-stub_user_view"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.4.</span> <span class="description">A stub view for showing user information. <br /> <code>app/views/users/show.html.erb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="cp"><%=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">name</span> <span class="cp">%></span>, <span class="cp"><%=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">email</span> <span class="cp">%></span>
</pre></div>
</div></div>
<p>This view uses Embedded Ruby to display the user’s name and email address, assuming the existence of an instance variable called <code>@user</code>. Of course, eventually the real user show page will look very different, and won’t display the email address publicly.</p>
<p>In order to get the user show view to work, we need to define an <code>@user</code> variable in the corresponding <code>show</code> action in the Users controller. As you might expect, we use the <code>find</code> method on the User model (<a class="ref" href="modeling-users.html#sec-finding_user_objects">Section 6.1.4</a>) to retrieve the user from the database, as shown in <a class="ref" href="sign-up.html#code-user_show_action">Listing 7.5</a>.</p>
<div class="label" id="code-user_show_action"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.5.</span> <span class="description">The Users controller with a <code>show</code> action. <br /> <code>app/controllers/users_controller.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">UsersController</span> <span class="o"><</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">show</span>
<span class="vi">@user</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">new</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>Here we’ve used <code>params</code> to retrieve the user id. When we make the appropriate request to the Users controller, <code>params[:id]</code> will be the user id <tt>1</tt>, so the effect is the same as the <code>find</code> method</p>
<div class="code"><div class="highlight"><pre><span class="no">User</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>we saw in <a class="ref" href="modeling-users.html#sec-finding_user_objects">Section 6.1.4</a>. (Technically, <code>params[:id]</code> is the string <code>"1"</code>, but <code>find</code> is smart enough to convert this to an integer.)</p>
<p>With the user view and action defined, the URI <a href="http://localhost:3000/users/1">/users/1</a> works perfectly (<a class="ref" href="sign-up.html#fig-user_show_rails_3">Figure 7.6</a>). Note that the debug information in <a class="ref" href="sign-up.html#fig-user_show_rails_3">Figure 7.6</a> confirms the value of <code>params[:id]</code>:</p>
<div class="code"><div class="highlight"><pre><span class="nn">---</span>
<span class="l-Scalar-Plain">action</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">show</span>
<span class="l-Scalar-Plain">controller</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">users</span>
<span class="l-Scalar-Plain">id</span><span class="p-Indicator">:</span> <span class="s">'1'</span>
</pre></div>
</div>
<p>This is why the code</p>
<div class="code"><div class="highlight"><pre><span class="no">User</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
</pre></div>
</div>
<p>in <a class="ref" href="sign-up.html#code-user_show_action">Listing 7.5</a> finds the user with id <tt>1</tt>.</p>
<div class="label" id="fig-user_show_rails_3"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/user_show_bootstrap.png" alt="user_show_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.6: </span><span class="description">The user show page at <a href="http://localhost:3000/users/1">/users/1</a> after adding a Users resource. <a href="http://railstutorial.org/images/figures/user_show_bootstrap-full.png">(full size)</a></span></div></div>
<div class="label" id="sec-tests_with_factories"></div>
<h3><a id="sec-7_1_3" href="sign-up.html#sec-tests_with_factories" class="heading"><span class="number">7.1.3</span> Testing the user show page (with factories)</a></h3>
<p>Now that we have a minimal working profile, it’s time to start working on the version mocked up in <a class="ref" href="sign-up.html#fig-profile_mockup_profile_name">Figure 7.1</a>. As with the creation of static pages (<a class="ref" href="static-pages.html#top">Chapter 3</a>) and the User model (<a class="ref" href="modeling-users.html#top">Chapter 6</a>), we’ll proceed using test-driven development.</p>
<p>Recall from <a class="ref" href="filling-in-the-layout.html#sec-signup_url">Section 5.4.2</a> that we have elected to use integration tests for the pages associated with the Users resource. In the case of the signup page, our test first visits the <code>signup_path</code> and then checks for the right <code>h1</code> and <code>title</code> tags, as seen in <a class="ref" href="filling-in-the-layout.html#code-user_pages_spec">Listing 5.31</a> and reproduced in <a class="ref" href="sign-up.html#code-initial_signup_test">Listing 7.6</a>. (Note that we’ve omitted the <code>full_title</code> helper from <a class="ref" href="filling-in-the-layout.html#sec-pretty_rspec">Section 5.3.4</a> since the full title is already adequately tested there.)</p>
<div class="label" id="code-initial_signup_test"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.6.</span> <span class="description">A recap of the initial User pages spec. <br /> <code>spec/requests/user_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">"User pages"</span> <span class="k">do</span>
<span class="n">subject</span> <span class="p">{</span> <span class="n">page</span> <span class="p">}</span>
<span class="n">describe</span> <span class="s2">"signup page"</span> <span class="k">do</span>
<span class="n">before</span> <span class="p">{</span> <span class="n">visit</span> <span class="n">signup_path</span> <span class="p">}</span>
<span class="n">it</span> <span class="p">{</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="s1">'Sign up'</span><span class="p">)</span> <span class="p">}</span>
<span class="n">it</span> <span class="p">{</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="s1">'Sign up'</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>To test the user show page, we’ll need a User model object so that the code in the <code>show</code> action (<a class="ref" href="sign-up.html#code-user_show_action">Listing 7.5</a>) has something to find:</p>
<div class="code"><div class="highlight"><pre><span class="n">describe</span> <span class="s2">"profile page"</span> <span class="k">do</span>
<span class="c1"># Code to make a user variable</span>
<span class="n">before</span> <span class="p">{</span> <span class="n">visit</span> <span class="n">user_path</span><span class="p">(</span><span class="n">user</span><span class="p">)</span> <span class="p">}</span>
<span class="n">it</span> <span class="p">{</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="n">user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="p">}</span>
<span class="n">it</span> <span class="p">{</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="n">user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
</pre></div>
</div>
<p>where we need to fill in the comment with the appropriate code. This uses the <code>user_path</code> named route (<a class="ref" href="sign-up.html#table-RESTful_users">Table 7.1</a>) to generate the path to the show page for the given user. It then tests that the <code>h1</code> and <code>title</code> tags both contain the user’s name.</p>
<p>In order to make the necessary User model object, we could use Active Record to create a user with <code>User.create</code>, but experience shows that user <em>factories</em> are a more convenient way to define user objects and insert them in the database. We’ll be using the factories generated by <a href="http://github.com/thoughtbot/factory_girl">Factory Girl</a>, a Ruby gem produced by the good people at <a href="http://thoughtbot.com/">thoughtbot</a>. As with RSpec, Factory Girl defines a domain-specific language in Ruby, in this case specialized for defining Active Record objects. The syntax is simple, relying on Ruby blocks and custom methods to define the attributes of the desired object. For cases such as the one in this chapter, the advantage over Active Record may not be obvious, but we’ll use more advanced features of factories in future chapters. For example, in <a class="ref" href="updating-showing-and-deleting-users.html#sec-pagination">Section 9.3.3</a> it will be important to create a sequence of users with unique email addresses, and factories make it easy to do this.</p>
<p>As with other Ruby gems, we can install Factory Girl by adding a line to the <code>Gemfile</code> used by Bundler (<a class="ref" href="sign-up.html#code-gemfile_factory_girl">Listing 7.7</a>). (Since Factory Girl is only needed in the tests, we’ve put it in the <code>:test</code> group.)</p>
<div class="label" id="code-gemfile_factory_girl"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.7.</span> <span class="description">Adding Factory Girl to the <code>Gemfile</code>.</span> </div>
<div class="code"><div class="highlight"><pre><span class="n">source</span> <span class="s1">'https://rubygems.org'</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="n">group</span> <span class="ss">:test</span> <span class="k">do</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="n">gem</span> <span class="s1">'factory_girl_rails'</span><span class="p">,</span> <span class="s1">'4.1.0'</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>Then install as usual:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle install
</pre></div>
</div>
<p>We’ll put all our Factory Girl factories in the file <code>spec/factories.rb</code>, which automatically gets loaded by RSpec. The code needed to make a User factory appears in <a class="ref" href="sign-up.html#code-user_factory">Listing 7.8</a>.</p>
<div class="label" id="code-user_factory"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.8.</span> <span class="description">A factory to simulate User model objects. <br /> <code>spec/factories.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="no">FactoryGirl</span><span class="o">.</span><span class="n">define</span> <span class="k">do</span>
<span class="n">factory</span> <span class="ss">:user</span> <span class="k">do</span>
<span class="nb">name</span> <span class="s2">"Michael Hartl"</span>
<span class="n">email</span> <span class="s2">"michael@example.com"</span>
<span class="n">password</span> <span class="s2">"foobar"</span>
<span class="n">password_confirmation</span> <span class="s2">"foobar"</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>By passing the symbol <code>:user</code> to the <code>factory</code> command, we tell Factory Girl that the subsequent definition is for a User model object.</p>
<p>With the definition in <a class="ref" href="sign-up.html#code-user_factory">Listing 7.8</a>, we can create a User factory in the tests using the <code>let</code> command (<a class="ref" href="modeling-users.html#sidebar-let">Box 6.3</a>) and the <code>FactoryGirl</code> method supplied by Factory Girl:</p>
<div class="code"><div class="highlight"><pre><span class="n">let</span><span class="p">(</span><span class="ss">:user</span><span class="p">)</span> <span class="p">{</span> <span class="no">FactoryGirl</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:user</span><span class="p">)</span> <span class="p">}</span>
</pre></div>
</div>
<p>The final result appears in <a class="ref" href="sign-up.html#code-user_show_page_test">Listing 7.9</a>.</p>
<div class="label" id="code-user_show_page_test"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.9.</span> <span class="description">A test for the user show page. <br /> <code>spec/requests/user_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">"User pages"</span> <span class="k">do</span>
<span class="n">subject</span> <span class="p">{</span> <span class="n">page</span> <span class="p">}</span>
<span class="n">describe</span> <span class="s2">"profile page"</span> <span class="k">do</span>
<span class="n">let</span><span class="p">(</span><span class="ss">:user</span><span class="p">)</span> <span class="p">{</span> <span class="no">FactoryGirl</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:user</span><span class="p">)</span> <span class="p">}</span>
<span class="n">before</span> <span class="p">{</span> <span class="n">visit</span> <span class="n">user_path</span><span class="p">(</span><span class="n">user</span><span class="p">)</span> <span class="p">}</span>
<span class="n">it</span> <span class="p">{</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="n">user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="p">}</span>
<span class="n">it</span> <span class="p">{</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="n">user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="p">}</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>You should verify at this point that the test suite is red:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rspec spec/
</pre></div>
</div>
<p>We can get the tests to green with the code in <a class="ref" href="sign-up.html#code-name_title_and_heading">Listing 7.10</a>.</p>
<div class="label" id="code-name_title_and_heading"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.10.</span> <span class="description">Adding a title and heading for the user profile page. <br /> <code>app/views/users/show.html.erb</code></span> </div>
<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="vi">@user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="cp">%></span>
<span class="nt"><h1></span><span class="cp"><%=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">name</span> <span class="cp">%></span><span class="nt"></h1></span>
</pre></div>
</div></div>
<p>Running the tests again should confirm that the test in <a class="ref" href="sign-up.html#code-user_show_page_test">Listing 7.9</a> is passing:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rspec spec/
</pre></div>
</div>
<p>One thing you will quickly notice when running tests with Factory Girl is that they are <em>slow</em>. The reason is not Factory Girl’s fault, and in fact it is a <em>feature</em>, not a bug. The issue is that the BCrypt algorithm used in <a class="ref" href="modeling-users.html#sec-an_encrypted_password">Section 6.3.1</a> to create a secure password hash is slow by design: BCrypt’s slow speed is part of what makes it so hard to attack. Unfortunately, this means that creating users can bog down the test suite; happily, there is an easy fix. BCrypt uses a <em>cost factor</em> to control how computationally costly it is to create the secure hash. The default value is designed for security, not for speed, which is perfect for production applications, but in tests our needs are reversed: we want <em>fast</em> tests, and don’t care at all about the security of the test users’ password hashes. The solution is to add a few lines to the test configuration file, <code>config/environments/test.rb</code>, redefining the cost factor from its secure default value to its fast minimum value, as shown in <a class="ref" href="sign-up.html#code-test_bcrypt_cost_factor">Listing 7.11</a>. Even for a small test suite, the gains in speed from this step can be considerable, and I strongly recommend including <a class="ref" href="sign-up.html#code-test_bcrypt_cost_factor">Listing 7.11</a> in your <code>test.rb</code>.</p>
<div class="label" id="code-test_bcrypt_cost_factor"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.11.</span> <span class="description">Redefining the BCrypt cost factor in a test environment. <br /> <code>config/environments/test.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="ss">SampleApp::Application</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="c1"># Speed up tests by lowering BCrypt's cost function.</span>
<span class="nb">require</span> <span class="s1">'bcrypt'</span>
<span class="n">silence_warnings</span> <span class="k">do</span>
<span class="ss">BCrypt::Engine</span><span class="o">::</span><span class="no">DEFAULT_COST</span> <span class="o">=</span> <span class="ss">BCrypt::Engine</span><span class="o">::</span><span class="no">MIN_COST</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<div class="label" id="sec-a_gravatar_image"></div>
<h3><a id="sec-7_1_4" href="sign-up.html#sec-a_gravatar_image" class="heading"><span class="number">7.1.4</span> A Gravatar image and a sidebar</a></h3>
<p>Having defined a basic user page in the previous section, we’ll now flesh it out a little with a profile image for each user and the first cut of the user sidebar. When making views, we’ll focus on the visual appearance and not worry too much about the exact structure of the page, which means that (at least for now) we won’t be writing tests. When we come to more error-prone aspects of view, such as pagination (<a class="ref" href="updating-showing-and-deleting-users.html#sec-pagination">Section 9.3.3</a>), we’ll resume test-driven development.</p>
<p>We’ll start by adding a “globally recognized avatar”, or <a href="http://gravatar.com/">Gravatar</a>, to the user profile.<sup class="footnote" id="fnref-7_6"><a href="#fn-7_6">6</a></sup> Originally created by Tom Preston-Werner (cofounder of <a href="http://github.com/">GitHub</a>) and later acquired by <a href="http://automattic.com/">Automattic</a> (the makers of <a href="http://wordpress.com/">WordPress</a>), Gravatar is a free service that allows users to upload images and associate them with email addresses they control. Gravatars are a convenient way to include user profile images without going through the trouble of managing image upload, cropping, and storage; all we need to do is construct the proper Gravatar image URI using the user’s email address and the corresponding Gravatar image will automatically appear.<sup class="footnote" id="fnref-7_7"><a href="#fn-7_7">7</a></sup></p>
<p>Our plan is to define a <code>gravatar_for</code> helper function to return a Gravatar image for a given user, as shown in <a class="ref" href="sign-up.html#code-user_show_view_with_gravatar">Listing 7.12</a>.</p>
<div class="label" id="code-user_show_view_with_gravatar"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.12.</span> <span class="description">The user show view with name and Gravatar. <br /> <code>app/views/users/show.html.erb</code></span> </div>
<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="vi">@user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="cp">%></span>
<span class="nt"><h1></span>
<span class="cp"><%=</span> <span class="n">gravatar_for</span> <span class="vi">@user</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">name</span> <span class="cp">%></span>
<span class="nt"></h1></span>
</pre></div>
</div></div>
<p>You can verify at this point that the test suite is failing:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rspec spec/
</pre></div>
</div>
<p>Because the <code>gravatar_for</code> method is undefined, the user show view is currently broken. (Catching errors of this nature is perhaps the most useful aspect of view specs. This is why having <em>some</em> test of the view, even a minimalist one, is so important.)</p>
<p>By default, methods defined in any helper file are automatically available in any view, but for convenience we’ll put the <code>gravatar_for</code> method in the file for helpers associated with the Users controller. As <a href="http://en.gravatar.com/site/implement/hash/">noted at the Gravatar home page</a>, Gravatar URIs are based on an <a href="http://en.wikipedia.org/wiki/MD5">MD5 hash</a> of the user’s email address. In Ruby, the MD5 hashing algorithm is implemented using the <code>hexdigest</code> method, which is part of the <code>Digest</code> library:</p>
<div class="code"><div class="highlight"><pre><span class="gp">>> </span><span class="n">email</span> <span class="o">=</span> <span class="s2">"MHARTL@example.COM"</span><span class="o">.</span>
<span class="gp">>> </span><span class="ss">Digest::MD5</span><span class="o">::</span><span class="n">hexdigest</span><span class="p">(</span><span class="n">email</span><span class="o">.</span><span class="n">downcase</span><span class="p">)</span>
<span class="go">=> "1fda4469bcbec3badf5418269ffc5968" </span>
</pre></div>
</div>
<p>Since email addresses are case-insensitive (<a class="ref" href="modeling-users.html#sec-format_validation">Section 6.2.4</a>) but MD5 hashes are not, we’ve used the <code>downcase</code> method to ensure that the argument to <code>hexdigest</code> is all lower-case. The resulting <code>gravatar_for</code> helper appears in <a class="ref" href="sign-up.html#code-gravatar_for_helper">Listing 7.13</a>.</p>
<div class="label" id="code-gravatar_for_helper"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.13.</span> <span class="description">Defining a <code>gravatar_for</code> helper method. <br /> <code>app/helpers/users_helper.rb</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="k">module</span> <span class="nn">UsersHelper</span>
<span class="c1"># Returns the Gravatar (http://gravatar.com/) for the given user.</span>
<span class="k">def</span> <span class="nf">gravatar_for</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="n">gravatar_id</span> <span class="o">=</span> <span class="ss">Digest::MD5</span><span class="o">::</span><span class="n">hexdigest</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">email</span><span class="o">.</span><span class="n">downcase</span><span class="p">)</span>
<span class="n">gravatar_url</span> <span class="o">=</span> <span class="s2">"https://secure.gravatar.com/avatar/</span><span class="si">#{</span><span class="n">gravatar_id</span><span class="si">}</span><span class="s2">"</span>
<span class="n">image_tag</span><span class="p">(</span><span class="n">gravatar_url</span><span class="p">,</span> <span class="ss">alt:</span> <span class="n">user</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="ss">class:</span> <span class="s2">"gravatar"</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
</div></div>
<p>The code in <a class="ref" href="sign-up.html#code-gravatar_for_helper">Listing 7.13</a> returns an image tag for the Gravatar with a <code>"gravatar"</code> class and alt text equal to the user’s name (which is especially convenient for sight-impaired users using a screen reader). You can confirm that the test suite is now passing:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rspec spec/
</pre></div>
</div>
<p>The profile page appears as in <a class="ref" href="sign-up.html#fig-profile_with_gravatar">Figure 7.7</a>, which shows the default Gravatar image, which appears because <code>user@example.com</code> is an invalid email address (the <a href="http://example.com/">example.com</a> domain is reserved for examples).</p>
<div class="label" id="fig-profile_with_gravatar"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/profile_with_gravatar_bootstrap.png" alt="profile_with_gravatar_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.7: </span><span class="description">The user profile page <a href="http://localhost:3000/users/1">/users/1</a> with the default Gravatar. <a href="http://railstutorial.org/images/figures/profile_with_gravatar_bootstrap-full.png">(full size)</a></span></div></div>
<p>To get our application to display a custom Gravatar, we’ll use <code>update_attributes</code> (<a class="ref" href="modeling-users.html#sec-updating_user_objects">Section 6.1.5</a>) to update the user in the database:</p>
<div class="code"><div class="highlight"><pre><span class="go">$ rails console</span>
<span class="gp">>> </span><span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">first</span>
<span class="gp">>> </span><span class="n">user</span><span class="o">.</span><span class="n">update_attributes</span><span class="p">(</span><span class="nb">name</span><span class="p">:</span> <span class="s2">"Example User"</span><span class="p">,</span>
<span class="gp">?> </span> <span class="ss">email:</span> <span class="s2">"example@railstutorial.org"</span><span class="p">,</span>
<span class="gp">?> </span> <span class="ss">password:</span> <span class="s2">"foobar"</span><span class="p">,</span>
<span class="gp">?> </span> <span class="ss">password_confirmation:</span> <span class="s2">"foobar"</span><span class="p">)</span>
<span class="go">=> true</span>
</pre></div>
</div>
<p>Here we’ve assigned the user the email address <code>example@railstutorial.org</code>, which I’ve associated with the Rails Tutorial logo, as seen in <a class="ref" href="sign-up.html#fig-profile_custom_gravatar">Figure 7.8</a>.</p>
<div class="label" id="fig-profile_custom_gravatar"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/profile_custom_gravatar_bootstrap.png" alt="profile_custom_gravatar_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.8: </span><span class="description">The user show page with a custom Gravatar. <a href="http://railstutorial.org/images/figures/profile_custom_gravatar_bootstrap-full.png">(full size)</a></span></div></div>
<p>The last element needed to complete the mockup from <a class="ref" href="sign-up.html#fig-profile_mockup_profile_name">Figure 7.1</a> is the initial version of the user sidebar. We’ll implement it using the <code>aside</code> tag, which is used for content (such as sidebars) that complements the rest of the page but can also stand alone. We include <code>row</code> and <code>span4</code> classes, which are both part of Bootstrap. The code for the modified user show page appears in <a class="ref" href="sign-up.html#code-user_show_with_sidebar">Listing 7.14</a>.</p>
<div class="label" id="code-user_show_with_sidebar"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.14.</span> <span class="description">Adding a sidebar to the user <code>show</code> view. <br /> <code>app/views/users/show.html.erb</code></span> </div>
<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="vi">@user</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="cp">%></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"row"</span><span class="nt">></span>
<span class="nt"><aside</span> <span class="na">class=</span><span class="s">"span4"</span><span class="nt">></span>
<span class="nt"><section></span>
<span class="nt"><h1></span>
<span class="cp"><%=</span> <span class="n">gravatar_for</span> <span class="vi">@user</span> <span class="cp">%></span>
<span class="cp"><%=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">name</span> <span class="cp">%></span>
<span class="nt"></h1></span>
<span class="nt"></section></span>
<span class="nt"></aside></span>
<span class="nt"></div></span>
</pre></div>
</div></div>
<p>With the HTML elements and CSS classes in place, we can style the profile page (including the sidebar and the Gravatar) with the SCSS shown in <a class="ref" href="sign-up.html#code-sidebar_css">Listing 7.15</a>. (Note the nesting of the table CSS rules, which works only because of the Sass engine used by the asset pipeline.) The resulting page is shown in <a class="ref" href="sign-up.html#fig-user_show_sidebar_css">Figure 7.9</a>.</p>
<div class="label" id="code-sidebar_css"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.15.</span> <span class="description">SCSS for styling the user show page, including the sidebar. <br /> <code>app/assets/stylesheets/custom.css.scss</code></span> </div>
<div class="code"><div class="highlight"><pre><span class="nc">.</span>
<span class="nc">.</span>
<span class="nc">.</span>
<span class="o">/*</span> <span class="nt">sidebar</span> <span class="o">*/</span>
<span class="nt">aside</span> <span class="p">{</span>
<span class="nt">section</span> <span class="p">{</span>
<span class="na">padding</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span> <span class="mi">0</span><span class="p">;</span>
<span class="na">border-top</span><span class="o">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="no">solid</span> <span class="nv">$grayLighter</span><span class="p">;</span>
<span class="k">&</span><span class="nd">:first-child</span> <span class="p">{</span>
<span class="na">border</span><span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
<span class="na">padding-top</span><span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">span</span> <span class="p">{</span>
<span class="na">display</span><span class="o">:</span> <span class="no">block</span><span class="p">;</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">3</span><span class="kt">px</span><span class="p">;</span>
<span class="na">line-height</span><span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">h1</span> <span class="p">{</span>
<span class="na">font-size</span><span class="o">:</span> <span class="mi">1</span><span class="mf">.4</span><span class="kt">em</span><span class="p">;</span>
<span class="na">text-align</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">letter-spacing</span><span class="o">:</span> <span class="mi">-1</span><span class="kt">px</span><span class="p">;</span>
<span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">3</span><span class="kt">px</span><span class="p">;</span>
<span class="na">margin-top</span><span class="o">:</span> <span class="mi">0</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nc">.gravatar</span> <span class="p">{</span>
<span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
<span class="na">margin-right</span><span class="o">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div></div>
<div class="label" id="fig-user_show_sidebar_css"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/user_show_sidebar_css_bootstrap.png" alt="user_show_sidebar_css_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.9: </span><span class="description">The user show page <a href="http://localhost:3000/users/1">/users/1</a> with a sidebar and CSS. <a href="http://railstutorial.org/images/figures/user_show_sidebar_css_bootstrap-full.png">(full size)</a></span></div></div>
<div class="label" id="sec-signup_form"></div>
<h2><a id="sec-7_2" href="sign-up.html#sec-signup_form" class="heading"><span class="number">7.2</span> Signup form</a></h2>
<p>Now that we have a working (though not yet complete) user profile page, we’re ready to make a signup form for our site. We saw in <a class="ref" href="filling-in-the-layout.html#fig-new_signup_page">Figure 5.9</a> (shown again in <a class="ref" href="sign-up.html#fig-blank_signup_page_recap">Figure 7.10</a>) that the signup page is currently blank: useless for signing up new users. The goal of this section is to start changing this sad state of affairs by producing the signup form mocked up in <a class="ref" href="sign-up.html#fig-signup_mockup">Figure 7.11</a>.</p>
<div class="label" id="fig-blank_signup_page_recap"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/new_signup_page_bootstrap.png" alt="new_signup_page_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.10: </span><span class="description">The current state of the signup page <a href="http://localhost:3000/signup">/signup</a>. <a href="http://railstutorial.org/images/figures/new_signup_page_bootstrap-full.png">(full size)</a></span></div></div>
<div class="label" id="fig-signup_mockup"></div>
<div class="figure"><div class="center"><span class="graphic"><img src="images/figures/signup_mockup_bootstrap.png" alt="signup_mockup_bootstrap" /></span></div><div class="caption"><span class="header">Figure 7.11: </span><span class="description">A mockup of the user signup page. <a href="http://railstutorial.org/images/figures/signup_mockup_bootstrap-full.png">(full size)</a></span></div></div>
<p>Since we’re about to add the ability to create new users through the web, let’s remove the user created at the console in <a class="ref" href="modeling-users.html#sec-creating_a_user">Section 6.3.5</a>. The cleanest way to do this is to reset the database with the <code>db:reset</code> Rake task:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rake db:reset
</pre></div>
</div>
<p>After resetting the database, on some systems the test database needs to be re-prepared as well:</p>
<div class="code"><div class="highlight"><pre><span class="gp">$</span> bundle <span class="nb">exec </span>rake db:test:prepare
</pre></div>
</div>
<p>Finally, on some systems you might have to restart the web server (using <tt>Ctrl-C</tt>) for the changes to take effect.<sup class="footnote" id="fnref-7_8"><a href="#fn-7_8">8</a></sup></p>
<div class="label" id="sec-tests_for_user_signup"></div>
<h3><a id="sec-7_2_1" href="sign-up.html#sec-tests_for_user_signup" class="heading"><span class="number">7.2.1</span> Tests for user signup</a></h3>
<p>In the days before powerful web frameworks with full testing capabilities, testing was often painful and error-prone. For example, to test a signup page manually, we would have to visit the page in a browser and then submit alternately invalid and valid data, verifying in each case that the application’s behavior was correct. Moreover, we would have to remember to repeat the process any time the application changed. With RSpec and Capybara, we will be able to write expressive tests to automate tasks that used to have to be done by hand.</p>
<p>We’ve already seen how Capybara supports an intuitive web-navigation syntax. So far, we’ve mostly used <code>visit</code> to visit particular pages, but Capybara can do a lot more, including filling in the kind of fields we see in <a class="ref" href="sign-up.html#fig-signup_mockup">Figure 7.11</a> and clicking on the button. The syntax looks like this:</p>
<div class="code"><div class="highlight"><pre><span class="n">visit</span> <span class="n">signup_path</span>
<span class="n">fill_in</span> <span class="s2">"Name"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"Example User"</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="n">click_button</span> <span class="s2">"Create my account"</span>
</pre></div>
</div>
<p>Our goal now is to write tests for the right behavior given invalid and valid signup information. Because these tests are fairly advanced, we’ll build them up piece by piece. If you want to see how they work (including which file to put them in), you can skip ahead to <a class="ref" href="sign-up.html#code-basic_signup_tests">Listing 7.16</a>.</p>
<p>Our first task is to test for a failing signup form, and we can simulate the submission of invalid data by visiting the page and clicking the button using <code>click_button</code>:</p>
<div class="code"><div class="highlight"><pre><span class="n">visit</span> <span class="n">signup_path</span>
<span class="n">click_button</span> <span class="s2">"Create my account"</span>
</pre></div>
</div>
<p>This is equivalent to visiting the signup page and submitting blank signup information (which is invalid). Similarly, to simulate the submission of valid data, we fill in valid information using <code>fill_in</code>:</p>
<div class="code"><div class="highlight"><pre><span class="n">visit</span> <span class="n">signup_path</span>
<span class="n">fill_in</span> <span class="s2">"Name"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"Example User"</span>
<span class="n">fill_in</span> <span class="s2">"Email"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"user@example.com"</span>
<span class="n">fill_in</span> <span class="s2">"Password"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"foobar"</span>
<span class="n">fill_in</span> <span class="s2">"Confirmation"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"foobar"</span>
<span class="n">click_button</span> <span class="s2">"Create my account"</span>
</pre></div>
</div>
<p>The purpose of our tests is to verify that clicking the signup button results in the correct behavior, creating a new user when the information is valid and not creating a user when it’s invalid. The way to do this is to check the <em>count</em> of users, and under the hood our tests will use the <code>count</code> method available on every Active Record class, including <code>User</code>:</p>
<div class="code"><div class="highlight"><pre><span class="go">$ rails console</span>
<span class="gp">>> </span><span class="no">User</span><span class="o">.</span><span class="n">count</span>
<span class="go">=> 0</span>
</pre></div>
</div>
<p>Here <code>User.count</code> is <code>0</code> because we reset the database at the beginning of this section.</p>
<p>When submitting invalid data, we expect the user count not to change; when submitting valid data, we expect it to change by 1. We can express this in RSpec by combining the <code>expect</code> method with either the <code>to</code> method or the <code>not_to</code> method. We’ll start with the invalid case since it is simpler; we visit the signup path and click the button, and we expect it <em>not to</em> change the user count:</p>
<div class="code"><div class="highlight"><pre><span class="n">visit</span> <span class="n">signup_path</span>
<span class="n">expect</span> <span class="p">{</span> <span class="n">click_button</span> <span class="s2">"Create my account"</span> <span class="p">}</span><span class="o">.</span><span class="n">not_to</span> <span class="n">change</span><span class="p">(</span><span class="no">User</span><span class="p">,</span> <span class="ss">:count</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that, as indicated by the curly braces, <code>expect</code> wraps <code>click_button</code> in a block (<a class="ref" href="rails-flavored-ruby.html#sec-blocks">Section 4.3.2</a>). This is for the benefit of the <code>change</code> method, which takes as arguments an object and a symbol and then calculates the result of calling that symbol as a method on the object both before and after the block. In other words, the code</p>
<div class="code"><div class="highlight"><pre><span class="n">expect</span> <span class="p">{</span> <span class="n">click_button</span> <span class="s2">"Create my account"</span> <span class="p">}</span><span class="o">.</span><span class="n">not_to</span> <span class="n">change</span><span class="p">(</span><span class="no">User</span><span class="p">,</span> <span class="ss">:count</span><span class="p">)</span>
</pre></div>
</div>
<p>calculates</p>
<div class="code"><div class="highlight"><pre><span class="no">User</span><span class="o">.</span><span class="n">count</span>
</pre></div>
</div>
<p>before and after the execution of</p>
<div class="code"><div class="highlight"><pre><span class="n">click_button</span> <span class="s2">"Create my account"</span>
</pre></div>
</div>
<p>In the present case, we want the given code <em>not</em> to change the count, which we express using the <code>not_to</code> method. In effect, by enclosing the button click in a block we are able to replace</p>
<div class="code"><div class="highlight"><pre><span class="n">initial</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">count</span>
<span class="n">click_button</span> <span class="s2">"Create my account"</span>
<span class="n">final</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">count</span>
<span class="n">initial</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="n">final</span>
</pre></div>
</div>
<p>with the single line</p>
<div class="code"><div class="highlight"><pre><span class="n">expect</span> <span class="p">{</span> <span class="n">click_button</span> <span class="s2">"Create my account"</span> <span class="p">}</span><span class="o">.</span><span class="n">not_to</span> <span class="n">change</span><span class="p">(</span><span class="no">User</span><span class="p">,</span> <span class="ss">:count</span><span class="p">)</span>
</pre></div>
</div>
<p>which reads like natural language and is much more compact.</p>
<p>The case of valid data is similar, but instead of verifying that the user count doesn’t change, we check that clicking the button changes the count by 1:</p>
<div class="code"><div class="highlight"><pre><span class="n">visit</span> <span class="n">signup_path</span>
<span class="n">fill_in</span> <span class="s2">"Name"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"Example User"</span>
<span class="n">fill_in</span> <span class="s2">"Email"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"user@example.com"</span>
<span class="n">fill_in</span> <span class="s2">"Password"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"foobar"</span>
<span class="n">fill_in</span> <span class="s2">"Confirmation"</span><span class="p">,</span> <span class="ss">with:</span> <span class="s2">"foobar"</span>
<span class="n">expect</span> <span class="k">do</span>
<span class="n">click_button</span> <span class="s2">"Create my account"</span>
<span class="k">end</span><span class="o">.</span><span class="n">to</span> <span class="n">change</span><span class="p">(</span><span class="no">User</span><span class="p">,</span> <span class="ss">:count</span><span class="p">)</span><span class="o">.</span><span class="n">by</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>This uses the <code>to</code> method because we expect a click on the signup button with valid data <em>to</em> change the user count by one.</p>
<p>Combining the two cases with the appropriate <code>describe</code> blocks and pulling the common code into <code>before</code> blocks yields good basic tests for signing up users, as shown in <a class="ref" href="sign-up.html#code-basic_signup_tests">Listing 7.16</a>. Here we’ve factored out the common text for the submit button using the <code>let</code> method to define a <code>submit</code> variable.</p>
<div class="label" id="code-basic_signup_tests"></div>
<div class="codelisting">
<div class="listing"><span class="header">Listing 7.16.</span> <span class="description">Good basic tests for signing up users. <br /> <code>spec/requests/user_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">"User pages"</span> <span class="k">do</span>