rails 4.2.0.beta4 → 4.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +4 -4
  2. data/guides/Rakefile +3 -1
  3. data/guides/bug_report_templates/action_controller_gem.rb +2 -2
  4. data/guides/bug_report_templates/action_controller_master.rb +2 -2
  5. data/guides/source/3_0_release_notes.md +2 -2
  6. data/guides/source/4_1_release_notes.md +1 -1
  7. data/guides/source/4_2_release_notes.md +250 -225
  8. data/guides/source/_welcome.html.erb +1 -1
  9. data/guides/source/action_controller_overview.md +6 -6
  10. data/guides/source/action_mailer_basics.md +26 -11
  11. data/guides/source/action_view_overview.md +0 -1
  12. data/guides/source/active_job_basics.md +29 -23
  13. data/guides/source/active_record_postgresql.md +2 -7
  14. data/guides/source/active_record_validations.md +1 -0
  15. data/guides/source/active_support_core_extensions.md +1 -1
  16. data/guides/source/active_support_instrumentation.md +5 -5
  17. data/guides/source/asset_pipeline.md +2 -2
  18. data/guides/source/association_basics.md +0 -2
  19. data/guides/source/command_line.md +6 -15
  20. data/guides/source/configuring.md +4 -4
  21. data/guides/source/documents.yaml +0 -1
  22. data/guides/source/engines.md +26 -15
  23. data/guides/source/form_helpers.md +10 -2
  24. data/guides/source/getting_started.md +9 -9
  25. data/guides/source/rails_on_rack.md +2 -2
  26. data/guides/source/ruby_on_rails_guides_guidelines.md +1 -0
  27. data/guides/source/security.md +1 -1
  28. data/guides/source/testing.md +80 -13
  29. data/guides/source/upgrading_ruby_on_rails.md +23 -20
  30. metadata +29 -229
  31. data/guides/output/2_2_release_notes.html +0 -724
  32. data/guides/output/2_3_release_notes.html +0 -870
  33. data/guides/output/3_0_release_notes.html +0 -773
  34. data/guides/output/3_1_release_notes.html +0 -740
  35. data/guides/output/3_2_release_notes.html +0 -797
  36. data/guides/output/4_0_release_notes.html +0 -523
  37. data/guides/output/4_1_release_notes.html +0 -806
  38. data/guides/output/4_2_release_notes.html +0 -728
  39. data/guides/output/Gemfile +0 -6
  40. data/guides/output/_license.html +0 -226
  41. data/guides/output/_welcome.html +0 -233
  42. data/guides/output/action_controller_overview.html +0 -1335
  43. data/guides/output/action_mailer_basics.html +0 -928
  44. data/guides/output/action_view_overview.html +0 -1509
  45. data/guides/output/active_job_basics.html +0 -546
  46. data/guides/output/active_model_basics.html +0 -438
  47. data/guides/output/active_record_basics.html +0 -594
  48. data/guides/output/active_record_callbacks.html +0 -592
  49. data/guides/output/active_record_migrations.html +0 -1123
  50. data/guides/output/active_record_postgresql.html +0 -675
  51. data/guides/output/active_record_querying.html +0 -1796
  52. data/guides/output/active_record_validations.html +0 -1301
  53. data/guides/output/active_support_core_extensions.html +0 -3450
  54. data/guides/output/active_support_instrumentation.html +0 -1121
  55. data/guides/output/api_documentation_guidelines.html +0 -498
  56. data/guides/output/asset_pipeline.html +0 -1167
  57. data/guides/output/association_basics.html +0 -2086
  58. data/guides/output/caching_with_rails.html +0 -553
  59. data/guides/output/command_line.html +0 -791
  60. data/guides/output/configuring.html +0 -1055
  61. data/guides/output/contributing_to_ruby_on_rails.html +0 -657
  62. data/guides/output/credits.html +0 -284
  63. data/guides/output/debugging_rails_applications.html +0 -1014
  64. data/guides/output/development_dependencies_install.html +0 -478
  65. data/guides/output/engines.html +0 -1438
  66. data/guides/output/form_helpers.html +0 -1074
  67. data/guides/output/generators.html +0 -838
  68. data/guides/output/getting_started.html +0 -2092
  69. data/guides/output/i18n.html +0 -1198
  70. data/guides/output/images/akshaysurve.jpg +0 -0
  71. data/guides/output/images/belongs_to.png +0 -0
  72. data/guides/output/images/book_icon.gif +0 -0
  73. data/guides/output/images/bullet.gif +0 -0
  74. data/guides/output/images/chapters_icon.gif +0 -0
  75. data/guides/output/images/check_bullet.gif +0 -0
  76. data/guides/output/images/credits_pic_blank.gif +0 -0
  77. data/guides/output/images/csrf.png +0 -0
  78. data/guides/output/images/edge_badge.png +0 -0
  79. data/guides/output/images/favicon.ico +0 -0
  80. data/guides/output/images/feature_tile.gif +0 -0
  81. data/guides/output/images/footer_tile.gif +0 -0
  82. data/guides/output/images/fxn.png +0 -0
  83. data/guides/output/images/getting_started/article_with_comments.png +0 -0
  84. data/guides/output/images/getting_started/challenge.png +0 -0
  85. data/guides/output/images/getting_started/confirm_dialog.png +0 -0
  86. data/guides/output/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  87. data/guides/output/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
  88. data/guides/output/images/getting_started/form_with_errors.png +0 -0
  89. data/guides/output/images/getting_started/index_action_with_edit_link.png +0 -0
  90. data/guides/output/images/getting_started/new_article.png +0 -0
  91. data/guides/output/images/getting_started/new_post.png +0 -0
  92. data/guides/output/images/getting_started/post_with_comments.png +0 -0
  93. data/guides/output/images/getting_started/rails_welcome.png +0 -0
  94. data/guides/output/images/getting_started/routing_error_no_controller.png +0 -0
  95. data/guides/output/images/getting_started/routing_error_no_route_matches.png +0 -0
  96. data/guides/output/images/getting_started/show_action_for_articles.png +0 -0
  97. data/guides/output/images/getting_started/show_action_for_posts.png +0 -0
  98. data/guides/output/images/getting_started/template_is_missing_articles_new.png +0 -0
  99. data/guides/output/images/getting_started/template_is_missing_posts_new.png +0 -0
  100. data/guides/output/images/getting_started/undefined_method_post_path.png +0 -0
  101. data/guides/output/images/getting_started/unknown_action_create_for_articles.png +0 -0
  102. data/guides/output/images/getting_started/unknown_action_create_for_posts.png +0 -0
  103. data/guides/output/images/getting_started/unknown_action_new_for_articles.png +0 -0
  104. data/guides/output/images/getting_started/unknown_action_new_for_posts.png +0 -0
  105. data/guides/output/images/grey_bullet.gif +0 -0
  106. data/guides/output/images/habtm.png +0 -0
  107. data/guides/output/images/has_many.png +0 -0
  108. data/guides/output/images/has_many_through.png +0 -0
  109. data/guides/output/images/has_one.png +0 -0
  110. data/guides/output/images/has_one_through.png +0 -0
  111. data/guides/output/images/header_backdrop.png +0 -0
  112. data/guides/output/images/header_tile.gif +0 -0
  113. data/guides/output/images/i18n/demo_html_safe.png +0 -0
  114. data/guides/output/images/i18n/demo_localized_pirate.png +0 -0
  115. data/guides/output/images/i18n/demo_translated_en.png +0 -0
  116. data/guides/output/images/i18n/demo_translated_pirate.png +0 -0
  117. data/guides/output/images/i18n/demo_translation_missing.png +0 -0
  118. data/guides/output/images/i18n/demo_untranslated.png +0 -0
  119. data/guides/output/images/icons/README +0 -5
  120. data/guides/output/images/icons/callouts/1.png +0 -0
  121. data/guides/output/images/icons/callouts/10.png +0 -0
  122. data/guides/output/images/icons/callouts/11.png +0 -0
  123. data/guides/output/images/icons/callouts/12.png +0 -0
  124. data/guides/output/images/icons/callouts/13.png +0 -0
  125. data/guides/output/images/icons/callouts/14.png +0 -0
  126. data/guides/output/images/icons/callouts/15.png +0 -0
  127. data/guides/output/images/icons/callouts/2.png +0 -0
  128. data/guides/output/images/icons/callouts/3.png +0 -0
  129. data/guides/output/images/icons/callouts/4.png +0 -0
  130. data/guides/output/images/icons/callouts/5.png +0 -0
  131. data/guides/output/images/icons/callouts/6.png +0 -0
  132. data/guides/output/images/icons/callouts/7.png +0 -0
  133. data/guides/output/images/icons/callouts/8.png +0 -0
  134. data/guides/output/images/icons/callouts/9.png +0 -0
  135. data/guides/output/images/icons/caution.png +0 -0
  136. data/guides/output/images/icons/example.png +0 -0
  137. data/guides/output/images/icons/home.png +0 -0
  138. data/guides/output/images/icons/important.png +0 -0
  139. data/guides/output/images/icons/next.png +0 -0
  140. data/guides/output/images/icons/note.png +0 -0
  141. data/guides/output/images/icons/prev.png +0 -0
  142. data/guides/output/images/icons/tip.png +0 -0
  143. data/guides/output/images/icons/up.png +0 -0
  144. data/guides/output/images/icons/warning.png +0 -0
  145. data/guides/output/images/nav_arrow.gif +0 -0
  146. data/guides/output/images/oscardelben.jpg +0 -0
  147. data/guides/output/images/polymorphic.png +0 -0
  148. data/guides/output/images/radar.png +0 -0
  149. data/guides/output/images/rails4_features.png +0 -0
  150. data/guides/output/images/rails_guides_kindle_cover.jpg +0 -0
  151. data/guides/output/images/rails_guides_logo.gif +0 -0
  152. data/guides/output/images/rails_logo_remix.gif +0 -0
  153. data/guides/output/images/session_fixation.png +0 -0
  154. data/guides/output/images/tab_grey.gif +0 -0
  155. data/guides/output/images/tab_info.gif +0 -0
  156. data/guides/output/images/tab_note.gif +0 -0
  157. data/guides/output/images/tab_red.gif +0 -0
  158. data/guides/output/images/tab_yellow.gif +0 -0
  159. data/guides/output/images/tab_yellow.png +0 -0
  160. data/guides/output/images/vijaydev.jpg +0 -0
  161. data/guides/output/index.html +0 -354
  162. data/guides/output/initialization.html +0 -876
  163. data/guides/output/javascripts/guides.js +0 -59
  164. data/guides/output/javascripts/jquery.min.js +0 -4
  165. data/guides/output/javascripts/responsive-tables.js +0 -43
  166. data/guides/output/javascripts/syntaxhighlighter/shBrushAS3.js +0 -59
  167. data/guides/output/javascripts/syntaxhighlighter/shBrushAppleScript.js +0 -75
  168. data/guides/output/javascripts/syntaxhighlighter/shBrushBash.js +0 -59
  169. data/guides/output/javascripts/syntaxhighlighter/shBrushCSharp.js +0 -65
  170. data/guides/output/javascripts/syntaxhighlighter/shBrushColdFusion.js +0 -100
  171. data/guides/output/javascripts/syntaxhighlighter/shBrushCpp.js +0 -97
  172. data/guides/output/javascripts/syntaxhighlighter/shBrushCss.js +0 -91
  173. data/guides/output/javascripts/syntaxhighlighter/shBrushDelphi.js +0 -55
  174. data/guides/output/javascripts/syntaxhighlighter/shBrushDiff.js +0 -41
  175. data/guides/output/javascripts/syntaxhighlighter/shBrushErlang.js +0 -52
  176. data/guides/output/javascripts/syntaxhighlighter/shBrushGroovy.js +0 -67
  177. data/guides/output/javascripts/syntaxhighlighter/shBrushJScript.js +0 -52
  178. data/guides/output/javascripts/syntaxhighlighter/shBrushJava.js +0 -57
  179. data/guides/output/javascripts/syntaxhighlighter/shBrushJavaFX.js +0 -58
  180. data/guides/output/javascripts/syntaxhighlighter/shBrushPerl.js +0 -72
  181. data/guides/output/javascripts/syntaxhighlighter/shBrushPhp.js +0 -88
  182. data/guides/output/javascripts/syntaxhighlighter/shBrushPlain.js +0 -33
  183. data/guides/output/javascripts/syntaxhighlighter/shBrushPowerShell.js +0 -74
  184. data/guides/output/javascripts/syntaxhighlighter/shBrushPython.js +0 -64
  185. data/guides/output/javascripts/syntaxhighlighter/shBrushRuby.js +0 -55
  186. data/guides/output/javascripts/syntaxhighlighter/shBrushSass.js +0 -94
  187. data/guides/output/javascripts/syntaxhighlighter/shBrushScala.js +0 -51
  188. data/guides/output/javascripts/syntaxhighlighter/shBrushSql.js +0 -66
  189. data/guides/output/javascripts/syntaxhighlighter/shBrushVb.js +0 -56
  190. data/guides/output/javascripts/syntaxhighlighter/shBrushXml.js +0 -69
  191. data/guides/output/javascripts/syntaxhighlighter/shCore.js +0 -17
  192. data/guides/output/layout.html +0 -448
  193. data/guides/output/layouts_and_rendering.html +0 -1541
  194. data/guides/output/maintenance_policy.html +0 -257
  195. data/guides/output/migrations.html +0 -1360
  196. data/guides/output/nested_model_forms.html +0 -412
  197. data/guides/output/plugins.html +0 -644
  198. data/guides/output/rails_application_templates.html +0 -450
  199. data/guides/output/rails_on_rack.html +0 -547
  200. data/guides/output/routing.html +0 -1631
  201. data/guides/output/ruby_on_rails_guides_guidelines.html +0 -329
  202. data/guides/output/security.html +0 -935
  203. data/guides/output/stylesheets/fixes.css +0 -16
  204. data/guides/output/stylesheets/kindle.css +0 -11
  205. data/guides/output/stylesheets/main.css +0 -713
  206. data/guides/output/stylesheets/print.css +0 -52
  207. data/guides/output/stylesheets/reset.css +0 -43
  208. data/guides/output/stylesheets/responsive-tables.css +0 -50
  209. data/guides/output/stylesheets/style.css +0 -13
  210. data/guides/output/stylesheets/syntaxhighlighter/shCore.css +0 -226
  211. data/guides/output/stylesheets/syntaxhighlighter/shCoreDefault.css +0 -328
  212. data/guides/output/stylesheets/syntaxhighlighter/shCoreDjango.css +0 -331
  213. data/guides/output/stylesheets/syntaxhighlighter/shCoreEclipse.css +0 -339
  214. data/guides/output/stylesheets/syntaxhighlighter/shCoreEmacs.css +0 -324
  215. data/guides/output/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +0 -328
  216. data/guides/output/stylesheets/syntaxhighlighter/shCoreMDUltra.css +0 -324
  217. data/guides/output/stylesheets/syntaxhighlighter/shCoreMidnight.css +0 -324
  218. data/guides/output/stylesheets/syntaxhighlighter/shCoreRDark.css +0 -324
  219. data/guides/output/stylesheets/syntaxhighlighter/shThemeDefault.css +0 -117
  220. data/guides/output/stylesheets/syntaxhighlighter/shThemeDjango.css +0 -120
  221. data/guides/output/stylesheets/syntaxhighlighter/shThemeEclipse.css +0 -128
  222. data/guides/output/stylesheets/syntaxhighlighter/shThemeEmacs.css +0 -113
  223. data/guides/output/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +0 -117
  224. data/guides/output/stylesheets/syntaxhighlighter/shThemeMDUltra.css +0 -113
  225. data/guides/output/stylesheets/syntaxhighlighter/shThemeMidnight.css +0 -113
  226. data/guides/output/stylesheets/syntaxhighlighter/shThemeRDark.css +0 -113
  227. data/guides/output/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +0 -116
  228. data/guides/output/testing.html +0 -1350
  229. data/guides/output/upgrading_ruby_on_rails.html +0 -1135
  230. data/guides/output/working_with_javascript_in_rails.html +0 -587
@@ -1,1335 +0,0 @@
1
- <!DOCTYPE html>
2
-
3
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
- <head>
5
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
7
-
8
- <title>Action Controller Overview — Ruby on Rails Guides</title>
9
- <link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
10
- <link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
11
-
12
- <link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
13
- <link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
14
-
15
- <link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" />
16
-
17
- <link href="images/favicon.ico" rel="shortcut icon" type="image/x-icon" />
18
- </head>
19
- <body class="guide">
20
- <div id="topNav">
21
- <div class="wrapper">
22
- <strong class="more-info-label">More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
23
- <span class="red-button more-info-button">
24
- More Ruby on Rails
25
- </span>
26
- <ul class="more-info-links s-hidden">
27
- <li class="more-info"><a href="http://rubyonrails.org/">Overview</a></li>
28
- <li class="more-info"><a href="http://rubyonrails.org/download">Download</a></li>
29
- <li class="more-info"><a href="http://rubyonrails.org/deploy">Deploy</a></li>
30
- <li class="more-info"><a href="https://github.com/rails/rails">Code</a></li>
31
- <li class="more-info"><a href="http://rubyonrails.org/screencasts">Screencasts</a></li>
32
- <li class="more-info"><a href="http://rubyonrails.org/documentation">Documentation</a></li>
33
- <li class="more-info"><a href="http://rubyonrails.org/community">Community</a></li>
34
- <li class="more-info"><a href="http://weblog.rubyonrails.org/">Blog</a></li>
35
- </ul>
36
- </div>
37
- </div>
38
- <div id="header">
39
- <div class="wrapper clearfix">
40
- <h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
41
- <ul class="nav">
42
- <li><a class="nav-item" href="index.html">Home</a></li>
43
- <li class="guides-index guides-index-large">
44
- <a href="index.html" id="guidesMenu" class="guides-index-item nav-item">Guides Index</a>
45
- <div id="guides" class="clearfix" style="display: none;">
46
- <hr />
47
- <dl class="L">
48
- <dt>Start Here</dt>
49
- <dd><a href="getting_started.html">Getting Started with Rails</a></dd>
50
- <dt>Models</dt>
51
- <dd><a href="active_record_basics.html">Active Record Basics</a></dd>
52
- <dd><a href="active_record_migrations.html">Active Record Migrations</a></dd>
53
- <dd><a href="active_record_validations.html">Active Record Validations</a></dd>
54
- <dd><a href="active_record_callbacks.html">Active Record Callbacks</a></dd>
55
- <dd><a href="association_basics.html">Active Record Associations</a></dd>
56
- <dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
57
- <dt>Views</dt>
58
- <dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd>
59
- <dd><a href="form_helpers.html">Action View Form Helpers</a></dd>
60
- <dt>Controllers</dt>
61
- <dd><a href="action_controller_overview.html">Action Controller Overview</a></dd>
62
- <dd><a href="routing.html">Rails Routing from the Outside In</a></dd>
63
- </dl>
64
- <dl class="R">
65
- <dt>Digging Deeper</dt>
66
- <dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd>
67
- <dd><a href="i18n.html">Rails Internationalization API</a></dd>
68
- <dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd>
69
- <dd><a href="active_job_basics.html">Active Job Basics</a></dd>
70
- <dd><a href="security.html">Securing Rails Applications</a></dd>
71
- <dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd>
72
- <dd><a href="configuring.html">Configuring Rails Applications</a></dd>
73
- <dd><a href="command_line.html">Rails Command Line Tools and Rake Tasks</a></dd>
74
- <dd><a href="asset_pipeline.html">Asset Pipeline</a></dd>
75
- <dd><a href="working_with_javascript_in_rails.html">Working with JavaScript in Rails</a></dd>
76
- <dt>Extending Rails</dt>
77
- <dd><a href="rails_on_rack.html">Rails on Rack</a></dd>
78
- <dd><a href="generators.html">Creating and Customizing Rails Generators</a></dd>
79
- <dt>Contributing to Ruby on Rails</dt>
80
- <dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd>
81
- <dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd>
82
- <dd><a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a></dd>
83
- <dt>Maintenance Policy</dt>
84
- <dd><a href="maintenance_policy.html">Maintenance Policy</a></dd>
85
- <dt>Release Notes</dt>
86
- <dd><a href="upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</a></dd>
87
- <dd><a href="4_1_release_notes.html">Ruby on Rails 4.1 Release Notes</a></dd>
88
- <dd><a href="4_0_release_notes.html">Ruby on Rails 4.0 Release Notes</a></dd>
89
- <dd><a href="3_2_release_notes.html">Ruby on Rails 3.2 Release Notes</a></dd>
90
- <dd><a href="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</a></dd>
91
- <dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
92
- <dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
93
- <dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
94
- </dl>
95
- </div>
96
- </li>
97
- <li><a class="nav-item" href="contributing_to_ruby_on_rails.html">Contribute</a></li>
98
- <li><a class="nav-item" href="credits.html">Credits</a></li>
99
- <li class="guides-index guides-index-small">
100
- <select class="guides-index-item nav-item">
101
- <option value="index.html">Guides Index</option>
102
- <optgroup label="Start Here">
103
- <option value="getting_started.html">Getting Started with Rails</option>
104
- </optgroup>
105
- <optgroup label="Models">
106
- <option value="active_record_basics.html">Active Record Basics</option>
107
- <option value="active_record_migrations.html">Active Record Migrations</option>
108
- <option value="active_record_validations.html">Active Record Validations</option>
109
- <option value="active_record_callbacks.html">Active Record Callbacks</option>
110
- <option value="association_basics.html">Active Record Associations</option>
111
- <option value="active_record_querying.html">Active Record Query Interface</option>
112
- </optgroup>
113
- <optgroup label="Views">
114
- <option value="layouts_and_rendering.html">Layouts and Rendering in Rails</option>
115
- <option value="form_helpers.html">Action View Form Helpers</option>
116
- </optgroup>
117
- <optgroup label="Controllers">
118
- <option value="action_controller_overview.html">Action Controller Overview</option>
119
- <option value="routing.html">Rails Routing from the Outside In</option>
120
- </optgroup>
121
- <optgroup label="Digging Deeper">
122
- <option value="active_support_core_extensions.html">Active Support Core Extensions</option>
123
- <option value="i18n.html">Rails Internationalization API</option>
124
- <option value="action_mailer_basics.html">Action Mailer Basics</option>
125
- <option value="active_job_basics.html">Active Job Basics</option>
126
- <option value="security.html">Securing Rails Applications</option>
127
- <option value="debugging_rails_applications.html">Debugging Rails Applications</option>
128
- <option value="configuring.html">Configuring Rails Applications</option>
129
- <option value="command_line.html">Rails Command Line Tools and Rake Tasks</option>
130
- <option value="asset_pipeline.html">Asset Pipeline</option>
131
- <option value="working_with_javascript_in_rails.html">Working with JavaScript in Rails</option>
132
- </optgroup>
133
- <optgroup label="Extending Rails">
134
- <option value="rails_on_rack.html">Rails on Rack</option>
135
- <option value="generators.html">Creating and Customizing Rails Generators</option>
136
- </optgroup>
137
- <optgroup label="Contributing to Ruby on Rails">
138
- <option value="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</option>
139
- <option value="api_documentation_guidelines.html">API Documentation Guidelines</option>
140
- <option value="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</option>
141
- </optgroup>
142
- <optgroup label="Maintenance Policy">
143
- <option value="maintenance_policy.html">Maintenance Policy</option>
144
- </optgroup>
145
- <optgroup label="Release Notes">
146
- <option value="upgrading_ruby_on_rails.html">Upgrading Ruby on Rails</option>
147
- <option value="4_1_release_notes.html">Ruby on Rails 4.1 Release Notes</option>
148
- <option value="4_0_release_notes.html">Ruby on Rails 4.0 Release Notes</option>
149
- <option value="3_2_release_notes.html">Ruby on Rails 3.2 Release Notes</option>
150
- <option value="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</option>
151
- <option value="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</option>
152
- <option value="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</option>
153
- <option value="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</option>
154
- </optgroup>
155
- </select>
156
- </li>
157
- </ul>
158
- </div>
159
- </div>
160
- <hr class="hide" />
161
-
162
- <div id="feature">
163
- <div class="wrapper">
164
- <h2>Action Controller Overview</h2><p>In this guide you will learn how controllers work and how they fit into the request cycle in your application.</p><p>After reading this guide, you will know:</p>
165
- <ul>
166
- <li>How to follow the flow of a request through a controller.</li>
167
- <li>How to restrict parameters passed to your controller.</li>
168
- <li>Why and how to store data in the session or cookies.</li>
169
- <li>How to work with filters to execute code during request processing.</li>
170
- <li>How to use Action Controller&#39;s built-in HTTP authentication.</li>
171
- <li>How to stream data directly to the user&#39;s browser.</li>
172
- <li>How to filter sensitive parameters so they do not appear in the application&#39;s log.</li>
173
- <li>How to deal with exceptions that may be raised during request processing.</li>
174
- </ul>
175
-
176
-
177
- <div id="subCol">
178
- <h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
179
- <ol class="chapters">
180
- <li><a href="#what-does-a-controller-do-questionmark">What Does a Controller Do?</a></li>
181
- <li><a href="#controller-naming-convention">Controller Naming Convention</a></li>
182
- <li><a href="#methods-and-actions">Methods and Actions</a></li>
183
- <li>
184
- <a href="#parameters">Parameters</a>
185
-
186
- <ul>
187
- <li><a href="#hash-and-array-parameters">Hash and Array Parameters</a></li>
188
- <li><a href="#json-parameters">JSON parameters</a></li>
189
- <li><a href="#routing-parameters">Routing Parameters</a></li>
190
- <li><a href="#default_url_options"><code>default_url_options</code></a></li>
191
- <li><a href="#strong-parameters">Strong Parameters</a></li>
192
- </ul>
193
- </li>
194
- <li>
195
- <a href="#session">Session</a>
196
-
197
- <ul>
198
- <li><a href="#accessing-the-session">Accessing the Session</a></li>
199
- <li><a href="#the-flash">The Flash</a></li>
200
- </ul>
201
- </li>
202
- <li><a href="#cookies">Cookies</a></li>
203
- <li><a href="#rendering-xml-and-json-data">Rendering XML and JSON data</a></li>
204
- <li>
205
- <a href="#filters">Filters</a>
206
-
207
- <ul>
208
- <li><a href="#after-filters-and-around-filters">After Filters and Around Filters</a></li>
209
- <li><a href="#other-ways-to-use-filters">Other Ways to Use Filters</a></li>
210
- </ul>
211
- </li>
212
- <li><a href="#request-forgery-protection">Request Forgery Protection</a></li>
213
- <li>
214
- <a href="#the-request-and-response-objects">The Request and Response Objects</a>
215
-
216
- <ul>
217
- <li><a href="#the-request-object">The <code>request</code> Object</a></li>
218
- <li><a href="#the-response-object">The <code>response</code> Object</a></li>
219
- </ul>
220
- </li>
221
- <li>
222
- <a href="#http-authentications">HTTP Authentications</a>
223
-
224
- <ul>
225
- <li><a href="#http-basic-authentication">HTTP Basic Authentication</a></li>
226
- <li><a href="#http-digest-authentication">HTTP Digest Authentication</a></li>
227
- </ul>
228
- </li>
229
- <li>
230
- <a href="#streaming-and-file-downloads">Streaming and File Downloads</a>
231
-
232
- <ul>
233
- <li><a href="#sending-files">Sending Files</a></li>
234
- <li><a href="#restful-downloads">RESTful Downloads</a></li>
235
- <li><a href="#live-streaming-of-arbitrary-data">Live Streaming of Arbitrary Data</a></li>
236
- </ul>
237
- </li>
238
- <li>
239
- <a href="#log-filtering">Log Filtering</a>
240
-
241
- <ul>
242
- <li><a href="#parameters-filtering">Parameters Filtering</a></li>
243
- <li><a href="#redirects-filtering">Redirects Filtering</a></li>
244
- </ul>
245
- </li>
246
- <li>
247
- <a href="#rescue">Rescue</a>
248
-
249
- <ul>
250
- <li><a href="#the-default-500-and-404-templates">The Default 500 and 404 Templates</a></li>
251
- <li><a href="#rescue_from"><code>rescue_from</code></a></li>
252
- <li><a href="#custom-errors-page">Custom errors page</a></li>
253
- </ul>
254
- </li>
255
- <li><a href="#force-https-protocol">Force HTTPS protocol</a></li>
256
- </ol>
257
-
258
- </div>
259
-
260
- </div>
261
- </div>
262
-
263
- <div id="container">
264
- <div class="wrapper">
265
- <div id="mainCol">
266
- <h3 id="what-does-a-controller-do-questionmark">1 What Does a Controller Do?</h3><p>Action Controller is the C in MVC. After routing has determined which controller to use for a request, your controller is responsible for making sense of the request and producing the appropriate output. Luckily, Action Controller does most of the groundwork for you and uses smart conventions to make this as straightforward as possible.</p><p>For most conventional <a href="http://en.wikipedia.org/wiki/Representational_state_transfer">RESTful</a> applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that's not a problem, this is just the most common way for a controller to work.</p><p>A controller can thus be thought of as a middle man between models and views. It makes the model data available to the view so it can display that data to the user, and it saves or updates data from the user to the model.</p><div class="note"><p>For more details on the routing process, see <a href="routing.html">Rails Routing from the Outside In</a>.</p></div><h3 id="controller-naming-convention">2 Controller Naming Convention</h3><p>The naming convention of controllers in Rails favors pluralization of the last word in the controller's name, although it is not strictly required (e.g. <code>ApplicationController</code>). For example, <code>ClientsController</code> is preferable to <code>ClientController</code>, <code>SiteAdminsController</code> is preferable to <code>SiteAdminController</code> or <code>SitesAdminsController</code>, and so on.</p><p>Following this convention will allow you to use the default route generators (e.g. <code>resources</code>, etc) without needing to qualify each <code>:path</code> or <code>:controller</code>, and keeps URL and path helpers' usage consistent throughout your application. See <a href="layouts_and_rendering.html">Layouts &amp; Rendering Guide</a> for more details.</p><div class="note"><p>The controller naming convention differs from the naming convention of models, which are expected to be named in singular form.</p></div><h3 id="methods-and-actions">3 Methods and Actions</h3><p>A controller is a Ruby class which inherits from <code>ApplicationController</code> and has methods just like any other class. When your application receives a request, the routing will determine which controller and action to run, then Rails creates an instance of that controller and runs the method with the same name as the action.</p><div class="code_container">
267
- <pre class="brush: ruby; gutter: false; toolbar: false">
268
- class ClientsController &lt; ApplicationController
269
- def new
270
- end
271
- end
272
-
273
- </pre>
274
- </div>
275
- <p>As an example, if a user goes to <code>/clients/new</code> in your application to add a new client, Rails will create an instance of <code>ClientsController</code> and run the <code>new</code> method. Note that the empty method from the example above would work just fine because Rails will by default render the <code>new.html.erb</code> view unless the action says otherwise. The <code>new</code> method could make available to the view a <code>@client</code> instance variable by creating a new <code>Client</code>:</p><div class="code_container">
276
- <pre class="brush: ruby; gutter: false; toolbar: false">
277
- def new
278
- @client = Client.new
279
- end
280
-
281
- </pre>
282
- </div>
283
- <p>The <a href="layouts_and_rendering.html">Layouts &amp; Rendering Guide</a> explains this in more detail.</p><p><code>ApplicationController</code> inherits from <code>ActionController::Base</code>, which defines a number of helpful methods. This guide will cover some of these, but if you're curious to see what's in there, you can see all of them in the API documentation or in the source itself.</p><p>Only public methods are callable as actions. It is a best practice to lower the visibility of methods which are not intended to be actions, like auxiliary methods or filters.</p><h3 id="parameters">4 Parameters</h3><p>You will probably want to access data sent in by the user or other parameters in your controller actions. There are two kinds of parameters possible in a web application. The first are parameters that are sent as part of the URL, called query string parameters. The query string is everything after "?" in the URL. The second type of parameter is usually referred to as POST data. This information usually comes from an HTML form which has been filled in by the user. It's called POST data because it can only be sent as part of an HTTP POST request. Rails does not make any distinction between query string parameters and POST parameters, and both are available in the <code>params</code> hash in your controller:</p><div class="code_container">
284
- <pre class="brush: ruby; gutter: false; toolbar: false">
285
- class ClientsController &lt; ApplicationController
286
- # This action uses query string parameters because it gets run
287
- # by an HTTP GET request, but this does not make any difference
288
- # to the way in which the parameters are accessed. The URL for
289
- # this action would look like this in order to list activated
290
- # clients: /clients?status=activated
291
- def index
292
- if params[:status] == "activated"
293
- @clients = Client.activated
294
- else
295
- @clients = Client.inactivated
296
- end
297
- end
298
-
299
- # This action uses POST parameters. They are most likely coming
300
- # from an HTML form which the user has submitted. The URL for
301
- # this RESTful request will be "/clients", and the data will be
302
- # sent as part of the request body.
303
- def create
304
- @client = Client.new(params[:client])
305
- if @client.save
306
- redirect_to @client
307
- else
308
- # This line overrides the default rendering behavior, which
309
- # would have been to render the "create" view.
310
- render "new"
311
- end
312
- end
313
- end
314
-
315
- </pre>
316
- </div>
317
- <h4 id="hash-and-array-parameters">4.1 Hash and Array Parameters</h4><p>The <code>params</code> hash is not limited to one-dimensional keys and values. It can contain arrays and (nested) hashes. To send an array of values, append an empty pair of square brackets "[]" to the key name:</p><div class="code_container">
318
- <pre class="brush: plain; gutter: false; toolbar: false">
319
- GET /clients?ids[]=1&amp;ids[]=2&amp;ids[]=3
320
-
321
- </pre>
322
- </div>
323
- <div class="note"><p>The actual URL in this example will be encoded as "/clients?ids%5b%5d=1&amp;ids%5b%5d=2&amp;ids%5b%5d=3" as "[" and "]" are not allowed in URLs. Most of the time you don't have to worry about this because the browser will take care of it for you, and Rails will decode it back when it receives it, but if you ever find yourself having to send those requests to the server manually you have to keep this in mind.</p></div><p>The value of <code>params[:ids]</code> will now be <code>["1", "2", "3"]</code>. Note that parameter values are always strings; Rails makes no attempt to guess or cast the type.</p><div class="note"><p>Values such as <code>[]</code>, <code>[nil]</code> or <code>[nil, nil, ...]</code> in <code>params</code> are replaced
324
- with <code>nil</code> for security reasons by default. See <a href="security.html#unsafe-query-generation">Security Guide</a>
325
- for more information.</p></div><p>To send a hash you include the key name inside the brackets:</p><div class="code_container">
326
- <pre class="brush: xml; gutter: false; toolbar: false">
327
- &lt;form accept-charset="UTF-8" action="/clients" method="post"&gt;
328
- &lt;input type="text" name="client[name]" value="Acme" /&gt;
329
- &lt;input type="text" name="client[phone]" value="12345" /&gt;
330
- &lt;input type="text" name="client[address][postcode]" value="12345" /&gt;
331
- &lt;input type="text" name="client[address][city]" value="Carrot City" /&gt;
332
- &lt;/form&gt;
333
-
334
- </pre>
335
- </div>
336
- <p>When this form is submitted, the value of <code>params[:client]</code> will be <code>{ "name" =&gt; "Acme", "phone" =&gt; "12345", "address" =&gt; { "postcode" =&gt; "12345", "city" =&gt; "Carrot City" } }</code>. Note the nested hash in <code>params[:client][:address]</code>.</p><p>Note that the <code>params</code> hash is actually an instance of <code>ActiveSupport::HashWithIndifferentAccess</code>, which acts like a hash but lets you use symbols and strings interchangeably as keys.</p><h4 id="json-parameters">4.2 JSON parameters</h4><p>If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. If the "Content-Type" header of your request is set to "application/json", Rails will automatically convert your parameters into the <code>params</code> hash, which you can access as you would normally.</p><p>So for example, if you are sending this JSON content:</p><div class="code_container">
337
- <pre class="brush: plain; gutter: false; toolbar: false">
338
- { "company": { "name": "acme", "address": "123 Carrot Street" } }
339
-
340
- </pre>
341
- </div>
342
- <p>You'll get <code>params[:company]</code> as <code>{ "name" =&gt; "acme", "address" =&gt; "123 Carrot Street" }</code>.</p><p>Also, if you've turned on <code>config.wrap_parameters</code> in your initializer or calling <code>wrap_parameters</code> in your controller, you can safely omit the root element in the JSON parameter. The parameters will be cloned and wrapped in the key according to your controller's name by default. So the above parameter can be written as:</p><div class="code_container">
343
- <pre class="brush: plain; gutter: false; toolbar: false">
344
- { "name": "acme", "address": "123 Carrot Street" }
345
-
346
- </pre>
347
- </div>
348
- <p>And assume that you're sending the data to <code>CompaniesController</code>, it would then be wrapped in <code>:company</code> key like this:</p><div class="code_container">
349
- <pre class="brush: ruby; gutter: false; toolbar: false">
350
- { name: "acme", address: "123 Carrot Street", company: { name: "acme", address: "123 Carrot Street" } }
351
-
352
- </pre>
353
- </div>
354
- <p>You can customize the name of the key or specific parameters you want to wrap by consulting the <a href="http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html">API documentation</a></p><div class="note"><p>Support for parsing XML parameters has been extracted into a gem named <code>actionpack-xml_parser</code></p></div><h4 id="routing-parameters">4.3 Routing Parameters</h4><p>The <code>params</code> hash will always contain the <code>:controller</code> and <code>:action</code> keys, but you should use the methods <code>controller_name</code> and <code>action_name</code> instead to access these values. Any other parameters defined by the routing, such as <code>:id</code> will also be available. As an example, consider a listing of clients where the list can show either active or inactive clients. We can add a route which captures the <code>:status</code> parameter in a "pretty" URL:</p><div class="code_container">
355
- <pre class="brush: ruby; gutter: false; toolbar: false">
356
- get '/clients/:status' =&gt; 'clients#index', foo: 'bar'
357
-
358
- </pre>
359
- </div>
360
- <p>In this case, when a user opens the URL <code>/clients/active</code>, <code>params[:status]</code> will be set to "active". When this route is used, <code>params[:foo]</code> will also be set to "bar" just like it was passed in the query string. In the same way <code>params[:action]</code> will contain "index".</p><h4 id="default_url_options">4.4 <code>default_url_options</code>
361
- </h4><p>You can set global default parameters for URL generation by defining a method called <code>default_url_options</code> in your controller. Such a method must return a hash with the desired defaults, whose keys must be symbols:</p><div class="code_container">
362
- <pre class="brush: ruby; gutter: false; toolbar: false">
363
- class ApplicationController &lt; ActionController::Base
364
- def default_url_options
365
- { locale: I18n.locale }
366
- end
367
- end
368
-
369
- </pre>
370
- </div>
371
- <p>These options will be used as a starting point when generating URLs, so it's possible they'll be overridden by the options passed in <code>url_for</code> calls.</p><p>If you define <code>default_url_options</code> in <code>ApplicationController</code>, as in the example above, it would be used for all URL generation. The method can also be defined in one specific controller, in which case it only affects URLs generated there.</p><h4 id="strong-parameters">4.5 Strong Parameters</h4><p>With strong parameters, Action Controller parameters are forbidden to
372
- be used in Active Model mass assignments until they have been
373
- whitelisted. This means you'll have to make a conscious choice about
374
- which attributes to allow for mass updating and thus prevent
375
- accidentally exposing that which shouldn't be exposed.</p><p>In addition, parameters can be marked as required and flow through a
376
- predefined raise/rescue flow to end up as a 400 Bad Request with no
377
- effort.</p><div class="code_container">
378
- <pre class="brush: ruby; gutter: false; toolbar: false">
379
- class PeopleController &lt; ActionController::Base
380
- # This will raise an ActiveModel::ForbiddenAttributes exception
381
- # because it's using mass assignment without an explicit permit
382
- # step.
383
- def create
384
- Person.create(params[:person])
385
- end
386
-
387
- # This will pass with flying colors as long as there's a person key
388
- # in the parameters, otherwise it'll raise a
389
- # ActionController::ParameterMissing exception, which will get
390
- # caught by ActionController::Base and turned into that 400 Bad
391
- # Request reply.
392
- def update
393
- person = current_account.people.find(params[:id])
394
- person.update!(person_params)
395
- redirect_to person
396
- end
397
-
398
- private
399
- # Using a private method to encapsulate the permissible parameters
400
- # is just a good pattern since you'll be able to reuse the same
401
- # permit list between create and update. Also, you can specialize
402
- # this method with per-user checking of permissible attributes.
403
- def person_params
404
- params.require(:person).permit(:name, :age)
405
- end
406
- end
407
-
408
- </pre>
409
- </div>
410
- <h5 id="permitted-scalar-values">4.5.1 Permitted Scalar Values</h5><p>Given</p><div class="code_container">
411
- <pre class="brush: ruby; gutter: false; toolbar: false">
412
- params.permit(:id)
413
-
414
- </pre>
415
- </div>
416
- <p>the key <code>:id</code> will pass the whitelisting if it appears in <code>params</code> and
417
- it has a permitted scalar value associated. Otherwise the key is going
418
- to be filtered out, so arrays, hashes, or any other objects cannot be
419
- injected.</p><p>The permitted scalar types are <code>String</code>, <code>Symbol</code>, <code>NilClass</code>,
420
- <code>Numeric</code>, <code>TrueClass</code>, <code>FalseClass</code>, <code>Date</code>, <code>Time</code>, <code>DateTime</code>,
421
- <code>StringIO</code>, <code>IO</code>, <code>ActionDispatch::Http::UploadedFile</code> and
422
- <code>Rack::Test::UploadedFile</code>.</p><p>To declare that the value in <code>params</code> must be an array of permitted
423
- scalar values map the key to an empty array:</p><div class="code_container">
424
- <pre class="brush: ruby; gutter: false; toolbar: false">
425
- params.permit(id: [])
426
-
427
- </pre>
428
- </div>
429
- <p>To whitelist an entire hash of parameters, the <code>permit!</code> method can be
430
- used:</p><div class="code_container">
431
- <pre class="brush: ruby; gutter: false; toolbar: false">
432
- params.require(:log_entry).permit!
433
-
434
- </pre>
435
- </div>
436
- <p>This will mark the <code>:log_entry</code> parameters hash and any sub-hash of it
437
- permitted. Extreme care should be taken when using <code>permit!</code> as it
438
- will allow all current and future model attributes to be
439
- mass-assigned.</p><h5 id="nested-parameters">4.5.2 Nested Parameters</h5><p>You can also use permit on nested parameters, like:</p><div class="code_container">
440
- <pre class="brush: ruby; gutter: false; toolbar: false">
441
- params.permit(:name, { emails: [] },
442
- friends: [ :name,
443
- { family: [ :name ], hobbies: [] }])
444
-
445
- </pre>
446
- </div>
447
- <p>This declaration whitelists the <code>name</code>, <code>emails</code> and <code>friends</code>
448
- attributes. It is expected that <code>emails</code> will be an array of permitted
449
- scalar values and that <code>friends</code> will be an array of resources with
450
- specific attributes : they should have a <code>name</code> attribute (any
451
- permitted scalar values allowed), a <code>hobbies</code> attribute as an array of
452
- permitted scalar values, and a <code>family</code> attribute which is restricted
453
- to having a <code>name</code> (any permitted scalar values allowed, too).</p><h5 id="more-examples">4.5.3 More Examples</h5><p>You want to also use the permitted attributes in the <code>new</code>
454
- action. This raises the problem that you can't use <code>require</code> on the
455
- root key because normally it does not exist when calling <code>new</code>:</p><div class="code_container">
456
- <pre class="brush: ruby; gutter: false; toolbar: false">
457
- # using `fetch` you can supply a default and use
458
- # the Strong Parameters API from there.
459
- params.fetch(:blog, {}).permit(:title, :author)
460
-
461
- </pre>
462
- </div>
463
- <p><code>accepts_nested_attributes_for</code> allows you to update and destroy
464
- associated records. This is based on the <code>id</code> and <code>_destroy</code>
465
- parameters:</p><div class="code_container">
466
- <pre class="brush: ruby; gutter: false; toolbar: false">
467
- # permit :id and :_destroy
468
- params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy])
469
-
470
- </pre>
471
- </div>
472
- <p>Hashes with integer keys are treated differently and you can declare
473
- the attributes as if they were direct children. You get these kinds of
474
- parameters when you use <code>accepts_nested_attributes_for</code> in combination
475
- with a <code>has_many</code> association:</p><div class="code_container">
476
- <pre class="brush: ruby; gutter: false; toolbar: false">
477
- # To whitelist the following data:
478
- # {"book" =&gt; {"title" =&gt; "Some Book",
479
- # "chapters_attributes" =&gt; { "1" =&gt; {"title" =&gt; "First Chapter"},
480
- # "2" =&gt; {"title" =&gt; "Second Chapter"}}}}
481
-
482
- params.require(:book).permit(:title, chapters_attributes: [:title])
483
-
484
- </pre>
485
- </div>
486
- <h5 id="outside-the-scope-of-strong-parameters">4.5.4 Outside the Scope of Strong Parameters</h5><p>The strong parameter API was designed with the most common use cases
487
- in mind. It is not meant as a silver bullet to handle all your
488
- whitelisting problems. However you can easily mix the API with your
489
- own code to adapt to your situation.</p><p>Imagine a scenario where you have parameters representing a product
490
- name and a hash of arbitrary data associated with that product, and
491
- you want to whitelist the product name attribute but also the whole
492
- data hash. The strong parameters API doesn't let you directly
493
- whitelist the whole of a nested hash with any keys, but you can use
494
- the keys of your nested hash to declare what to whitelist:</p><div class="code_container">
495
- <pre class="brush: ruby; gutter: false; toolbar: false">
496
- def product_params
497
- params.require(:product).permit(:name, data: params[:product][:data].try(:keys))
498
- end
499
-
500
- </pre>
501
- </div>
502
- <h3 id="session">5 Session</h3><p>Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of a number of different storage mechanisms:</p>
503
- <ul>
504
- <li>
505
- <code>ActionDispatch::Session::CookieStore</code> - Stores everything on the client.</li>
506
- <li>
507
- <code>ActionDispatch::Session::CacheStore</code> - Stores the data in the Rails cache.</li>
508
- <li>
509
- <code>ActionDispatch::Session::ActiveRecordStore</code> - Stores the data in a database using Active Record. (require <code>activerecord-session_store</code> gem).</li>
510
- <li>
511
- <code>ActionDispatch::Session::MemCacheStore</code> - Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).</li>
512
- </ul>
513
- <p>All session stores use a cookie to store a unique ID for each session (you must use a cookie, Rails will not allow you to pass the session ID in the URL as this is less secure).</p><p>For most stores, this ID is used to look up the session data on the server, e.g. in a database table. There is one exception, and that is the default and recommended session store - the CookieStore - which stores all session data in the cookie itself (the ID is still available to you if you need it). This has the advantage of being very lightweight and it requires zero setup in a new application in order to use the session. The cookie data is cryptographically signed to make it tamper-proof. And it is also encrypted so anyone with access to it can't read its contents. (Rails will not accept it if it has been edited).</p><p>The CookieStore can store around 4kB of data - much less than the others - but this is usually enough. Storing large amounts of data in the session is discouraged no matter which session store your application uses. You should especially avoid storing complex objects (anything other than basic Ruby objects, the most common example being model instances) in the session, as the server might not be able to reassemble them between requests, which will result in an error.</p><p>If your user sessions don't store critical data or don't need to be around for long periods (for instance if you just use the flash for messaging), you can consider using <code>ActionDispatch::Session::CacheStore</code>. This will store sessions using the cache implementation you have configured for your application. The advantage of this is that you can use your existing cache infrastructure for storing sessions without requiring any additional setup or administration. The downside, of course, is that the sessions will be ephemeral and could disappear at any time.</p><p>Read more about session storage in the <a href="security.html">Security Guide</a>.</p><p>If you need a different session storage mechanism, you can change it in the <code>config/initializers/session_store.rb</code> file:</p><div class="code_container">
514
- <pre class="brush: ruby; gutter: false; toolbar: false">
515
- # Use the database for sessions instead of the cookie-based default,
516
- # which shouldn't be used to store highly confidential information
517
- # (create the session table with "rails g active_record:session_migration")
518
- # Rails.application.config.session_store :active_record_store
519
-
520
- </pre>
521
- </div>
522
- <p>Rails sets up a session key (the name of the cookie) when signing the session data. These can also be changed in <code>config/initializers/session_store.rb</code>:</p><div class="code_container">
523
- <pre class="brush: ruby; gutter: false; toolbar: false">
524
- # Be sure to restart your server when you modify this file.
525
- Rails.application.config.session_store :cookie_store, key: '_your_app_session'
526
-
527
- </pre>
528
- </div>
529
- <p>You can also pass a <code>:domain</code> key and specify the domain name for the cookie:</p><div class="code_container">
530
- <pre class="brush: ruby; gutter: false; toolbar: false">
531
- # Be sure to restart your server when you modify this file.
532
- Rails.application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com"
533
-
534
- </pre>
535
- </div>
536
- <p>Rails sets up (for the CookieStore) a secret key used for signing the session data. This can be changed in <code>config/secrets.yml</code></p><div class="code_container">
537
- <pre class="brush: ruby; gutter: false; toolbar: false">
538
- # Be sure to restart your server when you modify this file.
539
-
540
- # Your secret key is used for verifying the integrity of signed cookies.
541
- # If you change this key, all old signed cookies will become invalid!
542
-
543
- # Make sure the secret is at least 30 characters and all random,
544
- # no regular words or you'll be exposed to dictionary attacks.
545
- # You can use `rake secret` to generate a secure secret key.
546
-
547
- # Make sure the secrets in this file are kept private
548
- # if you're sharing your code publicly.
549
-
550
- development:
551
- secret_key_base: a75d...
552
-
553
- test:
554
- secret_key_base: 492f...
555
-
556
- # Do not keep production secrets in the repository,
557
- # instead read values from the environment.
558
- production:
559
- secret_key_base: &lt;%= ENV["SECRET_KEY_BASE"] %&gt;
560
-
561
- </pre>
562
- </div>
563
- <div class="note"><p>Changing the secret when using the <code>CookieStore</code> will invalidate all existing sessions.</p></div><h4 id="accessing-the-session">5.1 Accessing the Session</h4><p>In your controller you can access the session through the <code>session</code> instance method.</p><div class="note"><p>Sessions are lazily loaded. If you don't access sessions in your action's code, they will not be loaded. Hence you will never need to disable sessions, just not accessing them will do the job.</p></div><p>Session values are stored using key/value pairs like a hash:</p><div class="code_container">
564
- <pre class="brush: ruby; gutter: false; toolbar: false">
565
- class ApplicationController &lt; ActionController::Base
566
-
567
- private
568
-
569
- # Finds the User with the ID stored in the session with the key
570
- # :current_user_id This is a common way to handle user login in
571
- # a Rails application; logging in sets the session value and
572
- # logging out removes it.
573
- def current_user
574
- @_current_user ||= session[:current_user_id] &amp;&amp;
575
- User.find_by(id: session[:current_user_id])
576
- end
577
- end
578
-
579
- </pre>
580
- </div>
581
- <p>To store something in the session, just assign it to the key like a hash:</p><div class="code_container">
582
- <pre class="brush: ruby; gutter: false; toolbar: false">
583
- class LoginsController &lt; ApplicationController
584
- # "Create" a login, aka "log the user in"
585
- def create
586
- if user = User.authenticate(params[:username], params[:password])
587
- # Save the user ID in the session so it can be used in
588
- # subsequent requests
589
- session[:current_user_id] = user.id
590
- redirect_to root_url
591
- end
592
- end
593
- end
594
-
595
- </pre>
596
- </div>
597
- <p>To remove something from the session, assign that key to be <code>nil</code>:</p><div class="code_container">
598
- <pre class="brush: ruby; gutter: false; toolbar: false">
599
- class LoginsController &lt; ApplicationController
600
- # "Delete" a login, aka "log the user out"
601
- def destroy
602
- # Remove the user id from the session
603
- @_current_user = session[:current_user_id] = nil
604
- redirect_to root_url
605
- end
606
- end
607
-
608
- </pre>
609
- </div>
610
- <p>To reset the entire session, use <code>reset_session</code>.</p><h4 id="the-flash">5.2 The Flash</h4><p>The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for passing error messages etc.</p><p>It is accessed in much the same way as the session, as a hash (it's a <a href="http://api.rubyonrails.org/classes/ActionDispatch/Flash/FlashHash.html">FlashHash</a> instance).</p><p>Let's use the act of logging out as an example. The controller can send a message which will be displayed to the user on the next request:</p><div class="code_container">
611
- <pre class="brush: ruby; gutter: false; toolbar: false">
612
- class LoginsController &lt; ApplicationController
613
- def destroy
614
- session[:current_user_id] = nil
615
- flash[:notice] = "You have successfully logged out."
616
- redirect_to root_url
617
- end
618
- end
619
-
620
- </pre>
621
- </div>
622
- <p>Note that it is also possible to assign a flash message as part of the redirection. You can assign <code>:notice</code>, <code>:alert</code> or the general purpose <code>:flash</code>:</p><div class="code_container">
623
- <pre class="brush: ruby; gutter: false; toolbar: false">
624
- redirect_to root_url, notice: "You have successfully logged out."
625
- redirect_to root_url, alert: "You're stuck here!"
626
- redirect_to root_url, flash: { referral_code: 1234 }
627
-
628
- </pre>
629
- </div>
630
- <p>The <code>destroy</code> action redirects to the application's <code>root_url</code>, where the message will be displayed. Note that it's entirely up to the next action to decide what, if anything, it will do with what the previous action put in the flash. It's conventional to display any error alerts or notices from the flash in the application's layout:</p><div class="code_container">
631
- <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
632
- &lt;html&gt;
633
- &lt;!-- &lt;head/&gt; --&gt;
634
- &lt;body&gt;
635
- &lt;% flash.each do |name, msg| -%&gt;
636
- &lt;%= content_tag :div, msg, class: name %&gt;
637
- &lt;% end -%&gt;
638
-
639
- &lt;!-- more content --&gt;
640
- &lt;/body&gt;
641
- &lt;/html&gt;
642
-
643
- </pre>
644
- </div>
645
- <p>This way, if an action sets a notice or an alert message, the layout will display it automatically.</p><p>You can pass anything that the session can store; you're not limited to notices and alerts:</p><div class="code_container">
646
- <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
647
- &lt;% if flash[:just_signed_up] %&gt;
648
- &lt;p class="welcome"&gt;Welcome to our site!&lt;/p&gt;
649
- &lt;% end %&gt;
650
-
651
- </pre>
652
- </div>
653
- <p>If you want a flash value to be carried over to another request, use the <code>keep</code> method:</p><div class="code_container">
654
- <pre class="brush: ruby; gutter: false; toolbar: false">
655
- class MainController &lt; ApplicationController
656
- # Let's say this action corresponds to root_url, but you want
657
- # all requests here to be redirected to UsersController#index.
658
- # If an action sets the flash and redirects here, the values
659
- # would normally be lost when another redirect happens, but you
660
- # can use 'keep' to make it persist for another request.
661
- def index
662
- # Will persist all flash values.
663
- flash.keep
664
-
665
- # You can also use a key to keep only some kind of value.
666
- # flash.keep(:notice)
667
- redirect_to users_url
668
- end
669
- end
670
-
671
- </pre>
672
- </div>
673
- <h5 id="flash.now">5.2.1 <code>flash.now</code>
674
- </h5><p>By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request. For example, if the <code>create</code> action fails to save a resource and you render the <code>new</code> template directly, that's not going to result in a new request, but you may still want to display a message using the flash. To do this, you can use <code>flash.now</code> in the same way you use the normal <code>flash</code>:</p><div class="code_container">
675
- <pre class="brush: ruby; gutter: false; toolbar: false">
676
- class ClientsController &lt; ApplicationController
677
- def create
678
- @client = Client.new(params[:client])
679
- if @client.save
680
- # ...
681
- else
682
- flash.now[:error] = "Could not save client"
683
- render action: "new"
684
- end
685
- end
686
- end
687
-
688
- </pre>
689
- </div>
690
- <h3 id="cookies">6 Cookies</h3><p>Your application can store small amounts of data on the client - called cookies - that will be persisted across requests and even sessions. Rails provides easy access to cookies via the <code>cookies</code> method, which - much like the <code>session</code> - works like a hash:</p><div class="code_container">
691
- <pre class="brush: ruby; gutter: false; toolbar: false">
692
- class CommentsController &lt; ApplicationController
693
- def new
694
- # Auto-fill the commenter's name if it has been stored in a cookie
695
- @comment = Comment.new(author: cookies[:commenter_name])
696
- end
697
-
698
- def create
699
- @comment = Comment.new(params[:comment])
700
- if @comment.save
701
- flash[:notice] = "Thanks for your comment!"
702
- if params[:remember_name]
703
- # Remember the commenter's name.
704
- cookies[:commenter_name] = @comment.author
705
- else
706
- # Delete cookie for the commenter's name cookie, if any.
707
- cookies.delete(:commenter_name)
708
- end
709
- redirect_to @comment.article
710
- else
711
- render action: "new"
712
- end
713
- end
714
- end
715
-
716
- </pre>
717
- </div>
718
- <p>Note that while for session values you set the key to <code>nil</code>, to delete a cookie value you should use <code>cookies.delete(:key)</code>.</p><p>Rails also provides a signed cookie jar and an encrypted cookie jar for storing
719
- sensitive data. The signed cookie jar appends a cryptographic signature on the
720
- cookie values to protect their integrity. The encrypted cookie jar encrypts the
721
- values in addition to signing them, so that they cannot be read by the end user.
722
- Refer to the <a href="http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html">API documentation</a>
723
- for more details.</p><p>These special cookie jars use a serializer to serialize the assigned values into
724
- strings and deserializes them into Ruby objects on read.</p><p>You can specify what serializer to use:</p><div class="code_container">
725
- <pre class="brush: ruby; gutter: false; toolbar: false">
726
- Rails.application.config.action_dispatch.cookies_serializer = :json
727
-
728
- </pre>
729
- </div>
730
- <p>The default serializer for new applications is <code>:json</code>. For compatibility with
731
- old applications with existing cookies, <code>:marshal</code> is used when <code>serializer</code>
732
- option is not specified.</p><p>You may also set this option to <code>:hybrid</code>, in which case Rails would transparently
733
- deserialize existing (<code>Marshal</code>-serialized) cookies on read and re-write them in
734
- the <code>JSON</code> format. This is useful for migrating existing applications to the
735
- <code>:json</code> serializer.</p><p>It is also possible to pass a custom serializer that responds to <code>load</code> and
736
- <code>dump</code>:</p><div class="code_container">
737
- <pre class="brush: ruby; gutter: false; toolbar: false">
738
- Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializer
739
-
740
- </pre>
741
- </div>
742
- <p>When using the <code>:json</code> or <code>:hybrid</code> serializer, you should beware that not all
743
- Ruby objects can be serialized as JSON. For example, <code>Date</code> and <code>Time</code> objects
744
- will be serialized as strings, and <code>Hash</code>es will have their keys stringified.</p><div class="code_container">
745
- <pre class="brush: ruby; gutter: false; toolbar: false">
746
- class CookiesController &lt; ApplicationController
747
- def set_cookie
748
- cookies.encrypted[:expiration_date] = Date.tomorrow # =&gt; Thu, 20 Mar 2014
749
- redirect_to action: 'read_cookie'
750
- end
751
-
752
- def read_cookie
753
- cookies.encrypted[:expiration_date] # =&gt; "2014-03-20"
754
- end
755
- end
756
-
757
- </pre>
758
- </div>
759
- <p>It's advisable that you only store simple data (strings and numbers) in cookies.
760
- If you have to store complex objects, you would need to handle the conversion
761
- manually when reading the values on subsequent requests.</p><p>If you use the cookie session store, this would apply to the <code>session</code> and
762
- <code>flash</code> hash as well.</p><h3 id="rendering-xml-and-json-data">7 Rendering XML and JSON data</h3><p>ActionController makes it extremely easy to render <code>XML</code> or <code>JSON</code> data. If you've generated a controller using scaffolding, it would look something like this:</p><div class="code_container">
763
- <pre class="brush: ruby; gutter: false; toolbar: false">
764
- class UsersController &lt; ApplicationController
765
- def index
766
- @users = User.all
767
- respond_to do |format|
768
- format.html # index.html.erb
769
- format.xml { render xml: @users}
770
- format.json { render json: @users}
771
- end
772
- end
773
- end
774
-
775
- </pre>
776
- </div>
777
- <p>You may notice in the above code that we're using <code>render xml: @users</code>, not <code>render xml: @users.to_xml</code>. If the object is not a String, then Rails will automatically invoke <code>to_xml</code> for us.</p><h3 id="filters">8 Filters</h3><p>Filters are methods that are run before, after or "around" a controller action.</p><p>Filters are inherited, so if you set a filter on <code>ApplicationController</code>, it will be run on every controller in your application.</p><p>"Before" filters may halt the request cycle. A common "before" filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:</p><div class="code_container">
778
- <pre class="brush: ruby; gutter: false; toolbar: false">
779
- class ApplicationController &lt; ActionController::Base
780
- before_action :require_login
781
-
782
- private
783
-
784
- def require_login
785
- unless logged_in?
786
- flash[:error] = "You must be logged in to access this section"
787
- redirect_to new_login_url # halts request cycle
788
- end
789
- end
790
- end
791
-
792
- </pre>
793
- </div>
794
- <p>The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a "before" filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter, they are also cancelled.</p><p>In this example the filter is added to <code>ApplicationController</code> and thus all controllers in the application inherit it. This will make everything in the application require the user to be logged in in order to use it. For obvious reasons (the user wouldn't be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with <code>skip_before_action</code>:</p><div class="code_container">
795
- <pre class="brush: ruby; gutter: false; toolbar: false">
796
- class LoginsController &lt; ApplicationController
797
- skip_before_action :require_login, only: [:new, :create]
798
- end
799
-
800
- </pre>
801
- </div>
802
- <p>Now, the <code>LoginsController</code>'s <code>new</code> and <code>create</code> actions will work as before without requiring the user to be logged in. The <code>:only</code> option is used to only skip this filter for these actions, and there is also an <code>:except</code> option which works the other way. These options can be used when adding filters too, so you can add a filter which only runs for selected actions in the first place.</p><h4 id="after-filters-and-around-filters">8.1 After Filters and Around Filters</h4><p>In addition to "before" filters, you can also run filters after an action has been executed, or both before and after.</p><p>"After" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running.</p><p>"Around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.</p><p>For example, in a website where changes have an approval workflow an administrator could be able to preview them easily, just apply them within a transaction:</p><div class="code_container">
803
- <pre class="brush: ruby; gutter: false; toolbar: false">
804
- class ChangesController &lt; ApplicationController
805
- around_action :wrap_in_transaction, only: :show
806
-
807
- private
808
-
809
- def wrap_in_transaction
810
- ActiveRecord::Base.transaction do
811
- begin
812
- yield
813
- ensure
814
- raise ActiveRecord::Rollback
815
- end
816
- end
817
- end
818
- end
819
-
820
- </pre>
821
- </div>
822
- <p>Note that an "around" filter also wraps rendering. In particular, if in the example above, the view itself reads from the database (e.g. via a scope), it will do so within the transaction and thus present the data to preview.</p><p>You can choose not to yield and build the response yourself, in which case the action will not be run.</p><h4 id="other-ways-to-use-filters">8.2 Other Ways to Use Filters</h4><p>While the most common way to use filters is by creating private methods and using *_action to add them, there are two other ways to do the same thing.</p><p>The first is to use a block directly with the *<em>action methods. The block receives the controller as an argument, and the `require</em>login` filter from above could be rewritten to use a block:</p><div class="code_container">
823
- <pre class="brush: ruby; gutter: false; toolbar: false">
824
- class ApplicationController &lt; ActionController::Base
825
- before_action do |controller|
826
- unless controller.send(:logged_in?)
827
- flash[:error] = "You must be logged in to access this section"
828
- redirect_to new_login_url
829
- end
830
- end
831
- end
832
-
833
- </pre>
834
- </div>
835
- <p>Note that the filter in this case uses <code>send</code> because the <code>logged_in?</code> method is private and the filter is not run in the scope of the controller. This is not the recommended way to implement this particular filter, but in more simple cases it might be useful.</p><p>The second way is to use a class (actually, any object that responds to the right methods will do) to handle the filtering. This is useful in cases that are more complex and cannot be implemented in a readable and reusable way using the two other methods. As an example, you could rewrite the login filter again to use a class:</p><div class="code_container">
836
- <pre class="brush: ruby; gutter: false; toolbar: false">
837
- class ApplicationController &lt; ActionController::Base
838
- before_action LoginFilter
839
- end
840
-
841
- class LoginFilter
842
- def self.before(controller)
843
- unless controller.send(:logged_in?)
844
- controller.flash[:error] = "You must be logged in to access this section"
845
- controller.redirect_to controller.new_login_url
846
- end
847
- end
848
- end
849
-
850
- </pre>
851
- </div>
852
- <p>Again, this is not an ideal example for this filter, because it's not run in the scope of the controller but gets the controller passed as an argument. The filter class must implement a method with the same name as the filter, so for the <code>before_action</code> filter the class must implement a <code>before</code> method, and so on. The <code>around</code> method must <code>yield</code> to execute the action.</p><h3 id="request-forgery-protection">9 Request Forgery Protection</h3><p>Cross-site request forgery is a type of attack in which a site tricks a user into making requests on another site, possibly adding, modifying or deleting data on that site without the user's knowledge or permission.</p><p>The first step to avoid this is to make sure all "destructive" actions (create, update and destroy) can only be accessed with non-GET requests. If you're following RESTful conventions you're already doing this. However, a malicious site can still send a non-GET request to your site quite easily, and that's where the request forgery protection comes in. As the name says, it protects from forged requests.</p><p>The way this is done is to add a non-guessable token which is only known to your server to each request. This way, if a request comes in without the proper token, it will be denied access.</p><p>If you generate a form like this:</p><div class="code_container">
853
- <pre class="brush: ruby; html-script: true; gutter: false; toolbar: false">
854
- &lt;%= form_for @user do |f| %&gt;
855
- &lt;%= f.text_field :username %&gt;
856
- &lt;%= f.text_field :password %&gt;
857
- &lt;% end %&gt;
858
-
859
- </pre>
860
- </div>
861
- <p>You will see how the token gets added as a hidden field:</p><div class="code_container">
862
- <pre class="brush: xml; gutter: false; toolbar: false">
863
- &lt;form accept-charset="UTF-8" action="/users/1" method="post"&gt;
864
- &lt;input type="hidden"
865
- value="67250ab105eb5ad10851c00a5621854a23af5489"
866
- name="authenticity_token"/&gt;
867
- &lt;!-- fields --&gt;
868
- &lt;/form&gt;
869
-
870
- </pre>
871
- </div>
872
- <p>Rails adds this token to every form that's generated using the <a href="form_helpers.html">form helpers</a>, so most of the time you don't have to worry about it. If you're writing a form manually or need to add the token for another reason, it's available through the method <code>form_authenticity_token</code>:</p><p>The <code>form_authenticity_token</code> generates a valid authentication token. That's useful in places where Rails does not add it automatically, like in custom Ajax calls.</p><p>The <a href="security.html">Security Guide</a> has more about this and a lot of other security-related issues that you should be aware of when developing a web application.</p><h3 id="the-request-and-response-objects">10 The Request and Response Objects</h3><p>In every controller there are two accessor methods pointing to the request and the response objects associated with the request cycle that is currently in execution. The <code>request</code> method contains an instance of <code>AbstractRequest</code> and the <code>response</code> method returns a response object representing what is going to be sent back to the client.</p><h4 id="the-request-object">10.1 The <code>request</code> Object</h4><p>The request object contains a lot of useful information about the request coming in from the client. To get a full list of the available methods, refer to the <a href="http://api.rubyonrails.org/classes/ActionDispatch/Request.html">API documentation</a>. Among the properties that you can access on this object are:</p>
873
- <table>
874
- <thead>
875
- <tr>
876
- <th>Property of <code>request</code>
877
- </th>
878
- <th>Purpose</th>
879
- </tr>
880
- </thead>
881
- <tbody>
882
- <tr>
883
- <td>host</td>
884
- <td>The hostname used for this request.</td>
885
- </tr>
886
- <tr>
887
- <td>domain(n=2)</td>
888
- <td>The hostname's first <code>n</code> segments, starting from the right (the TLD).</td>
889
- </tr>
890
- <tr>
891
- <td>format</td>
892
- <td>The content type requested by the client.</td>
893
- </tr>
894
- <tr>
895
- <td>method</td>
896
- <td>The HTTP method used for the request.</td>
897
- </tr>
898
- <tr>
899
- <td>get?, post?, patch?, put?, delete?, head?</td>
900
- <td>Returns true if the HTTP method is GET/POST/PATCH/PUT/DELETE/HEAD.</td>
901
- </tr>
902
- <tr>
903
- <td>headers</td>
904
- <td>Returns a hash containing the headers associated with the request.</td>
905
- </tr>
906
- <tr>
907
- <td>port</td>
908
- <td>The port number (integer) used for the request.</td>
909
- </tr>
910
- <tr>
911
- <td>protocol</td>
912
- <td>Returns a string containing the protocol used plus "://", for example "http://".</td>
913
- </tr>
914
- <tr>
915
- <td>query_string</td>
916
- <td>The query string part of the URL, i.e., everything after "?".</td>
917
- </tr>
918
- <tr>
919
- <td>remote_ip</td>
920
- <td>The IP address of the client.</td>
921
- </tr>
922
- <tr>
923
- <td>url</td>
924
- <td>The entire URL used for the request.</td>
925
- </tr>
926
- </tbody>
927
- </table>
928
- <h5 id="path_parameters,-query_parameters,-and-request_parameters">10.1.1 <code>path_parameters</code>, <code>query_parameters</code>, and <code>request_parameters</code>
929
- </h5><p>Rails collects all of the parameters sent along with the request in the <code>params</code> hash, whether they are sent as part of the query string or the post body. The request object has three accessors that give you access to these parameters depending on where they came from. The <code>query_parameters</code> hash contains parameters that were sent as part of the query string while the <code>request_parameters</code> hash contains parameters sent as part of the post body. The <code>path_parameters</code> hash contains parameters that were recognized by the routing as being part of the path leading to this particular controller and action.</p><h4 id="the-response-object">10.2 The <code>response</code> Object</h4><p>The response object is not usually used directly, but is built up during the execution of the action and rendering of the data that is being sent back to the user, but sometimes - like in an after filter - it can be useful to access the response directly. Some of these accessor methods also have setters, allowing you to change their values.</p>
930
- <table>
931
- <thead>
932
- <tr>
933
- <th>Property of <code>response</code>
934
- </th>
935
- <th>Purpose</th>
936
- </tr>
937
- </thead>
938
- <tbody>
939
- <tr>
940
- <td>body</td>
941
- <td>This is the string of data being sent back to the client. This is most often HTML.</td>
942
- </tr>
943
- <tr>
944
- <td>status</td>
945
- <td>The HTTP status code for the response, like 200 for a successful request or 404 for file not found.</td>
946
- </tr>
947
- <tr>
948
- <td>location</td>
949
- <td>The URL the client is being redirected to, if any.</td>
950
- </tr>
951
- <tr>
952
- <td>content_type</td>
953
- <td>The content type of the response.</td>
954
- </tr>
955
- <tr>
956
- <td>charset</td>
957
- <td>The character set being used for the response. Default is "utf-8".</td>
958
- </tr>
959
- <tr>
960
- <td>headers</td>
961
- <td>Headers used for the response.</td>
962
- </tr>
963
- </tbody>
964
- </table>
965
- <h5 id="setting-custom-headers">10.2.1 Setting Custom Headers</h5><p>If you want to set custom headers for a response then <code>response.headers</code> is the place to do it. The headers attribute is a hash which maps header names to their values, and Rails will set some of them automatically. If you want to add or change a header, just assign it to <code>response.headers</code> this way:</p><div class="code_container">
966
- <pre class="brush: ruby; gutter: false; toolbar: false">
967
- response.headers["Content-Type"] = "application/pdf"
968
-
969
- </pre>
970
- </div>
971
- <p>Note: in the above case it would make more sense to use the <code>content_type</code> setter directly.</p><h3 id="http-authentications">11 HTTP Authentications</h3><p>Rails comes with two built-in HTTP authentication mechanisms:</p>
972
- <ul>
973
- <li>Basic Authentication</li>
974
- <li>Digest Authentication</li>
975
- </ul>
976
- <h4 id="http-basic-authentication">11.1 HTTP Basic Authentication</h4><p>HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser's HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, <code>http_basic_authenticate_with</code>.</p><div class="code_container">
977
- <pre class="brush: ruby; gutter: false; toolbar: false">
978
- class AdminsController &lt; ApplicationController
979
- http_basic_authenticate_with name: "humbaba", password: "5baa61e4"
980
- end
981
-
982
- </pre>
983
- </div>
984
- <p>With this in place, you can create namespaced controllers that inherit from <code>AdminsController</code>. The filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication.</p><h4 id="http-digest-authentication">11.2 HTTP Digest Authentication</h4><p>HTTP digest authentication is superior to the basic authentication as it does not require the client to send an unencrypted password over the network (though HTTP basic authentication is safe over HTTPS). Using digest authentication with Rails is quite easy and only requires using one method, <code>authenticate_or_request_with_http_digest</code>.</p><div class="code_container">
985
- <pre class="brush: ruby; gutter: false; toolbar: false">
986
- class AdminsController &lt; ApplicationController
987
- USERS = { "lifo" =&gt; "world" }
988
-
989
- before_action :authenticate
990
-
991
- private
992
-
993
- def authenticate
994
- authenticate_or_request_with_http_digest do |username|
995
- USERS[username]
996
- end
997
- end
998
- end
999
-
1000
- </pre>
1001
- </div>
1002
- <p>As seen in the example above, the <code>authenticate_or_request_with_http_digest</code> block takes only one argument - the username. And the block returns the password. Returning <code>false</code> or <code>nil</code> from the <code>authenticate_or_request_with_http_digest</code> will cause authentication failure.</p><h3 id="streaming-and-file-downloads">12 Streaming and File Downloads</h3><p>Sometimes you may want to send a file to the user instead of rendering an HTML page. All controllers in Rails have the <code>send_data</code> and the <code>send_file</code> methods, which will both stream data to the client. <code>send_file</code> is a convenience method that lets you provide the name of a file on the disk and it will stream the contents of that file for you.</p><p>To stream data to the client, use <code>send_data</code>:</p><div class="code_container">
1003
- <pre class="brush: ruby; gutter: false; toolbar: false">
1004
- require "prawn"
1005
- class ClientsController &lt; ApplicationController
1006
- # Generates a PDF document with information on the client and
1007
- # returns it. The user will get the PDF as a file download.
1008
- def download_pdf
1009
- client = Client.find(params[:id])
1010
- send_data generate_pdf(client),
1011
- filename: "#{client.name}.pdf",
1012
- type: "application/pdf"
1013
- end
1014
-
1015
- private
1016
-
1017
- def generate_pdf(client)
1018
- Prawn::Document.new do
1019
- text client.name, align: :center
1020
- text "Address: #{client.address}"
1021
- text "Email: #{client.email}"
1022
- end.render
1023
- end
1024
- end
1025
-
1026
- </pre>
1027
- </div>
1028
- <p>The <code>download_pdf</code> action in the example above will call a private method which actually generates the PDF document and returns it as a string. This string will then be streamed to the client as a file download and a filename will be suggested to the user. Sometimes when streaming files to the user, you may not want them to download the file. Take images, for example, which can be embedded into HTML pages. To tell the browser a file is not meant to be downloaded, you can set the <code>:disposition</code> option to "inline". The opposite and default value for this option is "attachment".</p><h4 id="sending-files">12.1 Sending Files</h4><p>If you want to send a file that already exists on disk, use the <code>send_file</code> method.</p><div class="code_container">
1029
- <pre class="brush: ruby; gutter: false; toolbar: false">
1030
- class ClientsController &lt; ApplicationController
1031
- # Stream a file that has already been generated and stored on disk.
1032
- def download_pdf
1033
- client = Client.find(params[:id])
1034
- send_file("#{Rails.root}/files/clients/#{client.id}.pdf",
1035
- filename: "#{client.name}.pdf",
1036
- type: "application/pdf")
1037
- end
1038
- end
1039
-
1040
- </pre>
1041
- </div>
1042
- <p>This will read and stream the file 4kB at the time, avoiding loading the entire file into memory at once. You can turn off streaming with the <code>:stream</code> option or adjust the block size with the <code>:buffer_size</code> option.</p><p>If <code>:type</code> is not specified, it will be guessed from the file extension specified in <code>:filename</code>. If the content type is not registered for the extension, <code>application/octet-stream</code> will be used.</p><div class="warning"><p>Be careful when using data coming from the client (params, cookies, etc.) to locate the file on disk, as this is a security risk that might allow someone to gain access to files they are not meant to.</p></div><div class="info"><p>It is not recommended that you stream static files through Rails if you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack.</p></div><h4 id="restful-downloads">12.2 RESTful Downloads</h4><p>While <code>send_data</code> works just fine, if you are creating a RESTful application having separate actions for file downloads is usually not necessary. In REST terminology, the PDF file from the example above can be considered just another representation of the client resource. Rails provides an easy and quite sleek way of doing "RESTful downloads". Here's how you can rewrite the example so that the PDF download is a part of the <code>show</code> action, without any streaming:</p><div class="code_container">
1043
- <pre class="brush: ruby; gutter: false; toolbar: false">
1044
- class ClientsController &lt; ApplicationController
1045
- # The user can request to receive this resource as HTML or PDF.
1046
- def show
1047
- @client = Client.find(params[:id])
1048
-
1049
- respond_to do |format|
1050
- format.html
1051
- format.pdf { render pdf: generate_pdf(@client) }
1052
- end
1053
- end
1054
- end
1055
-
1056
- </pre>
1057
- </div>
1058
- <p>In order for this example to work, you have to add the PDF MIME type to Rails. This can be done by adding the following line to the file <code>config/initializers/mime_types.rb</code>:</p><div class="code_container">
1059
- <pre class="brush: ruby; gutter: false; toolbar: false">
1060
- Mime::Type.register "application/pdf", :pdf
1061
-
1062
- </pre>
1063
- </div>
1064
- <div class="note"><p>Configuration files are not reloaded on each request, so you have to restart the server in order for their changes to take effect.</p></div><p>Now the user can request to get a PDF version of a client just by adding ".pdf" to the URL:</p><div class="code_container">
1065
- <pre class="brush: plain; gutter: false; toolbar: false">
1066
- GET /clients/1.pdf
1067
-
1068
- </pre>
1069
- </div>
1070
- <h4 id="live-streaming-of-arbitrary-data">12.3 Live Streaming of Arbitrary Data</h4><p>Rails allows you to stream more than just files. In fact, you can stream anything
1071
- you would like in a response object. The <code>ActionController::Live</code> module allows
1072
- you to create a persistent connection with a browser. Using this module, you will
1073
- be able to send arbitrary data to the browser at specific points in time.</p><h5 id="incorporating-live-streaming">12.3.1 Incorporating Live Streaming</h5><p>Including <code>ActionController::Live</code> inside of your controller class will provide
1074
- all actions inside of the controller the ability to stream data. You can mix in
1075
- the module like so:</p><div class="code_container">
1076
- <pre class="brush: ruby; gutter: false; toolbar: false">
1077
- class MyController &lt; ActionController::Base
1078
- include ActionController::Live
1079
-
1080
- def stream
1081
- response.headers['Content-Type'] = 'text/event-stream'
1082
- 100.times {
1083
- response.stream.write "hello world\n"
1084
- sleep 1
1085
- }
1086
- ensure
1087
- response.stream.close
1088
- end
1089
- end
1090
-
1091
- </pre>
1092
- </div>
1093
- <p>The above code will keep a persistent connection with the browser and send 100
1094
- messages of <code>"hello world\n"</code>, each one second apart.</p><p>There are a couple of things to notice in the above example. We need to make
1095
- sure to close the response stream. Forgetting to close the stream will leave
1096
- the socket open forever. We also have to set the content type to <code>text/event-stream</code>
1097
- before we write to the response stream. This is because headers cannot be written
1098
- after the response has been committed (when <code>response.committed</code> returns a truthy
1099
- value), which occurs when you <code>write</code> or <code>commit</code> the response stream.</p><h5 id="example-usage">12.3.2 Example Usage</h5><p>Let's suppose that you were making a Karaoke machine and a user wants to get the
1100
- lyrics for a particular song. Each <code>Song</code> has a particular number of lines and
1101
- each line takes time <code>num_beats</code> to finish singing.</p><p>If we wanted to return the lyrics in Karaoke fashion (only sending the line when
1102
- the singer has finished the previous line), then we could use <code>ActionController::Live</code>
1103
- as follows:</p><div class="code_container">
1104
- <pre class="brush: ruby; gutter: false; toolbar: false">
1105
- class LyricsController &lt; ActionController::Base
1106
- include ActionController::Live
1107
-
1108
- def show
1109
- response.headers['Content-Type'] = 'text/event-stream'
1110
- song = Song.find(params[:id])
1111
-
1112
- song.each do |line|
1113
- response.stream.write line.lyrics
1114
- sleep line.num_beats
1115
- end
1116
- ensure
1117
- response.stream.close
1118
- end
1119
- end
1120
-
1121
- </pre>
1122
- </div>
1123
- <p>The above code sends the next line only after the singer has completed the previous
1124
- line.</p><h5 id="streaming-considerations">12.3.3 Streaming Considerations</h5><p>Streaming arbitrary data is an extremely powerful tool. As shown in the previous
1125
- examples, you can choose when and what to send across a response stream. However,
1126
- you should also note the following things:</p>
1127
- <ul>
1128
- <li>Each response stream creates a new thread and copies over the thread local
1129
- variables from the original thread. Having too many thread local variables can
1130
- negatively impact performance. Similarly, a large number of threads can also
1131
- hinder performance.</li>
1132
- <li>Failing to close the response stream will leave the corresponding socket open
1133
- forever. Make sure to call <code>close</code> whenever you are using a response stream.</li>
1134
- <li>WEBrick servers buffer all responses, and so including <code>ActionController::Live</code>
1135
- will not work. You must use a web server which does not automatically buffer
1136
- responses.</li>
1137
- </ul>
1138
- <h3 id="log-filtering">13 Log Filtering</h3><p>Rails keeps a log file for each environment in the <code>log</code> folder. These are extremely useful when debugging what's actually going on in your application, but in a live application you may not want every bit of information to be stored in the log file.</p><h4 id="parameters-filtering">13.1 Parameters Filtering</h4><p>You can filter out sensitive request parameters from your log files by appending them to <code>config.filter_parameters</code> in the application configuration. These parameters will be marked [FILTERED] in the log.</p><div class="code_container">
1139
- <pre class="brush: ruby; gutter: false; toolbar: false">
1140
- config.filter_parameters &lt;&lt; :password
1141
-
1142
- </pre>
1143
- </div>
1144
- <h4 id="redirects-filtering">13.2 Redirects Filtering</h4><p>Sometimes it's desirable to filter out from log files some sensitive locations your application is redirecting to.
1145
- You can do that by using the <code>config.filter_redirect</code> configuration option:</p><div class="code_container">
1146
- <pre class="brush: ruby; gutter: false; toolbar: false">
1147
- config.filter_redirect &lt;&lt; 's3.amazonaws.com'
1148
-
1149
- </pre>
1150
- </div>
1151
- <p>You can set it to a String, a Regexp, or an array of both.</p><div class="code_container">
1152
- <pre class="brush: ruby; gutter: false; toolbar: false">
1153
- config.filter_redirect.concat ['s3.amazonaws.com', /private_path/]
1154
-
1155
- </pre>
1156
- </div>
1157
- <p>Matching URLs will be marked as '[FILTERED]'.</p><h3 id="rescue">14 Rescue</h3><p>Most likely your application is going to contain bugs or otherwise throw an exception that needs to be handled. For example, if the user follows a link to a resource that no longer exists in the database, Active Record will throw the <code>ActiveRecord::RecordNotFound</code> exception.</p><p>Rails' default exception handling displays a "500 Server Error" message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple "500 Server Error" message to the user, or a "404 Not Found" if there was a routing error or a record could not be found. Sometimes you might want to customize how these errors are caught and how they're displayed to the user. There are several levels of exception handling available in a Rails application:</p><h4 id="the-default-500-and-404-templates">14.1 The Default 500 and 404 Templates</h4><p>By default a production application will render either a 404 or a 500 error message. These messages are contained in static HTML files in the <code>public</code> folder, in <code>404.html</code> and <code>500.html</code> respectively. You can customize these files to add some extra information and layout, but remember that they are static; i.e. you can't use RHTML or layouts in them, just plain HTML.</p><h4 id="rescue_from">14.2 <code>rescue_from</code>
1158
- </h4><p>If you want to do something a bit more elaborate when catching errors, you can use <code>rescue_from</code>, which handles exceptions of a certain type (or multiple types) in an entire controller and its subclasses.</p><p>When an exception occurs which is caught by a <code>rescue_from</code> directive, the exception object is passed to the handler. The handler can be a method or a <code>Proc</code> object passed to the <code>:with</code> option. You can also use a block directly instead of an explicit <code>Proc</code> object.</p><p>Here's how you can use <code>rescue_from</code> to intercept all <code>ActiveRecord::RecordNotFound</code> errors and do something with them.</p><div class="code_container">
1159
- <pre class="brush: ruby; gutter: false; toolbar: false">
1160
- class ApplicationController &lt; ActionController::Base
1161
- rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
1162
-
1163
- private
1164
-
1165
- def record_not_found
1166
- render plain: "404 Not Found", status: 404
1167
- end
1168
- end
1169
-
1170
- </pre>
1171
- </div>
1172
- <p>Of course, this example is anything but elaborate and doesn't improve on the default exception handling at all, but once you can catch all those exceptions you're free to do whatever you want with them. For example, you could create custom exception classes that will be thrown when a user doesn't have access to a certain section of your application:</p><div class="code_container">
1173
- <pre class="brush: ruby; gutter: false; toolbar: false">
1174
- class ApplicationController &lt; ActionController::Base
1175
- rescue_from User::NotAuthorized, with: :user_not_authorized
1176
-
1177
- private
1178
-
1179
- def user_not_authorized
1180
- flash[:error] = "You don't have access to this section."
1181
- redirect_to :back
1182
- end
1183
- end
1184
-
1185
- class ClientsController &lt; ApplicationController
1186
- # Check that the user has the right authorization to access clients.
1187
- before_action :check_authorization
1188
-
1189
- # Note how the actions don't have to worry about all the auth stuff.
1190
- def edit
1191
- @client = Client.find(params[:id])
1192
- end
1193
-
1194
- private
1195
-
1196
- # If the user is not authorized, just throw the exception.
1197
- def check_authorization
1198
- raise User::NotAuthorized unless current_user.admin?
1199
- end
1200
- end
1201
-
1202
- </pre>
1203
- </div>
1204
- <div class="warning"><p>You shouldn't do <code>rescue_from Exception</code> or <code>rescue_from StandardError</code> unless you have a particular reason as it will cause serious side-effects (e.g. you won't be able to see exception details and tracebacks during development). If you would like to dynamically generate error pages, see <a href="#custom-errors-page">Custom errors page</a>.</p></div><div class="note"><p>Certain exceptions are only rescuable from the <code>ApplicationController</code> class, as they are raised before the controller gets initialized and the action gets executed. See Pratik Naik's <a href="http://m.onkey.org/2008/7/20/rescue-from-dispatching">article</a> on the subject for more information.</p></div><h4 id="custom-errors-page">14.3 Custom errors page</h4><p>You can customize the layout of your error handling using controllers and views.
1205
- First define your app own routes to display the errors page.</p>
1206
- <ul>
1207
- <li><code>config/application.rb</code></li>
1208
- </ul>
1209
- <div class="code_container">
1210
- <pre class="brush: ruby; gutter: false; toolbar: false">
1211
- config.exceptions_app = self.routes
1212
-
1213
- </pre>
1214
- </div>
1215
-
1216
- <ul>
1217
- <li><code>config/routes.rb</code></li>
1218
- </ul>
1219
- <div class="code_container">
1220
- <pre class="brush: ruby; gutter: false; toolbar: false">
1221
- get '/404', to: 'errors#not_found'
1222
- get '/422', to: 'errors#unprocessable_entity'
1223
- get '/500', to: 'errors#server_error'
1224
-
1225
- </pre>
1226
- </div>
1227
- <p>Create the controller and views.</p>
1228
- <ul>
1229
- <li><code>app/controllers/errors_controller.rb</code></li>
1230
- </ul>
1231
- <div class="code_container">
1232
- <pre class="brush: ruby; gutter: false; toolbar: false">
1233
- class ErrorsController &lt; ActionController::Base
1234
- layout 'error'
1235
-
1236
- def not_found
1237
- render status: :not_found
1238
- end
1239
-
1240
- def unprocessable_entity
1241
- render status: :unprocessable_entity
1242
- end
1243
-
1244
- def server_error
1245
- render status: :server_error
1246
- end
1247
- end
1248
-
1249
- </pre>
1250
- </div>
1251
-
1252
- <ul>
1253
- <li><code>app/views</code></li>
1254
- </ul>
1255
- <div class="code_container">
1256
- <pre class="brush: plain; gutter: false; toolbar: false">
1257
- errors/
1258
- not_found.html.erb
1259
- unprocessable_entity.html.erb
1260
- server_error.html.erb
1261
- layouts/
1262
- error.html.erb
1263
-
1264
- </pre>
1265
- </div>
1266
- <p>Do not forget to set the correct status code on the controller as shown before. You should avoid using the database or any complex operations because the user is already on the error page. Generating another error while on an error page could cause issues.</p><h3 id="force-https-protocol">15 Force HTTPS protocol</h3><p>Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. You can use the <code>force_ssl</code> method in your controller to enforce that:</p><div class="code_container">
1267
- <pre class="brush: ruby; gutter: false; toolbar: false">
1268
- class DinnerController
1269
- force_ssl
1270
- end
1271
-
1272
- </pre>
1273
- </div>
1274
- <p>Just like the filter, you could also pass <code>:only</code> and <code>:except</code> to enforce the secure connection only to specific actions:</p><div class="code_container">
1275
- <pre class="brush: ruby; gutter: false; toolbar: false">
1276
- class DinnerController
1277
- force_ssl only: :cheeseburger
1278
- # or
1279
- force_ssl except: :cheeseburger
1280
- end
1281
-
1282
- </pre>
1283
- </div>
1284
- <p>Please note that if you find yourself adding <code>force_ssl</code> to many controllers, you may want to force the whole application to use HTTPS instead. In that case, you can set the <code>config.force_ssl</code> in your environment file.</p>
1285
-
1286
- <h3>Feedback</h3>
1287
- <p>
1288
- You're encouraged to help improve the quality of this guide.
1289
- </p>
1290
- <p>
1291
- Please contribute if you see any typos or factual errors.
1292
- To get started, you can read our <a href="http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation">documentation contributions</a> section.
1293
- </p>
1294
- <p>
1295
- You may also find incomplete content, or stuff that is not up to date.
1296
- Please do add any missing documentation for master. Make sure to check
1297
- <a href="http://edgeguides.rubyonrails.org">Edge Guides</a> first to verify
1298
- if the issues are already fixed or not on the master branch.
1299
- Check the <a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a>
1300
- for style and conventions.
1301
- </p>
1302
- <p>
1303
- If for whatever reason you spot something to fix but cannot patch it yourself, please
1304
- <a href="https://github.com/rails/rails/issues">open an issue</a>.
1305
- </p>
1306
- <p>And last but not least, any kind of discussion regarding Ruby on Rails
1307
- documentation is very welcome in the <a href="http://groups.google.com/group/rubyonrails-docs">rubyonrails-docs mailing list</a>.
1308
- </p>
1309
- </div>
1310
- </div>
1311
- </div>
1312
-
1313
- <hr class="hide" />
1314
- <div id="footer">
1315
- <div class="wrapper">
1316
- <p>This work is licensed under a <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International</a> License</p>
1317
- <p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
1318
-
1319
- </div>
1320
- </div>
1321
-
1322
- <script type="text/javascript" src="javascripts/jquery.min.js"></script>
1323
- <script type="text/javascript" src="javascripts/responsive-tables.js"></script>
1324
- <script type="text/javascript" src="javascripts/guides.js"></script>
1325
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
1326
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
1327
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushXml.js"></script>
1328
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushSql.js"></script>
1329
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
1330
- <script type="text/javascript">
1331
- SyntaxHighlighter.all();
1332
- $(guidesIndex.bind);
1333
- </script>
1334
- </body>
1335
- </html>