railties 3.1.1 → 3.1.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +2382 -0
- data/guides/output/2_2_release_notes.html +565 -0
- data/guides/output/2_3_release_notes.html +713 -0
- data/guides/output/3_0_release_notes.html +652 -0
- data/guides/output/3_1_release_notes.html +670 -0
- data/guides/output/action_controller_overview.html +925 -0
- data/guides/output/action_mailer_basics.html +658 -0
- data/guides/output/action_view_overview.html +1471 -0
- data/guides/output/active_model_basics.html +349 -0
- data/guides/output/active_record_basics.html +364 -0
- data/guides/output/active_record_querying.html +1272 -0
- data/guides/output/active_record_validations_callbacks.html +1292 -0
- data/guides/output/active_resource_basics.html +252 -0
- data/guides/output/active_support_core_extensions.html +3374 -0
- data/guides/output/ajax_on_rails.html +412 -0
- data/guides/output/api_documentation_guidelines.html +317 -0
- data/guides/output/asset_pipeline.html +691 -0
- data/guides/output/association_basics.html +1742 -0
- data/guides/output/caching_with_rails.html +533 -0
- data/guides/output/command_line.html +662 -0
- data/guides/output/configuring.html +811 -0
- data/guides/output/contribute.html +216 -0
- data/guides/output/contributing_to_ruby_on_rails.html +465 -0
- data/guides/output/credits.html +210 -0
- data/guides/output/debugging_rails_applications.html +791 -0
- data/guides/output/engines.html +673 -0
- data/guides/output/form_helpers.html +850 -0
- data/guides/output/generators.html +725 -0
- data/guides/output/getting_started.html +1980 -0
- data/guides/output/i18n.html +1054 -0
- data/guides/output/images/belongs_to.png +0 -0
- data/guides/output/images/book_icon.gif +0 -0
- data/guides/output/images/bullet.gif +0 -0
- data/guides/output/images/challenge.png +0 -0
- data/guides/output/images/chapters_icon.gif +0 -0
- data/guides/output/images/check_bullet.gif +0 -0
- data/guides/output/images/credits_pic_blank.gif +0 -0
- data/guides/output/images/csrf.png +0 -0
- data/guides/output/images/customized_error_messages.png +0 -0
- data/guides/output/images/edge_badge.png +0 -0
- data/guides/output/images/error_messages.png +0 -0
- data/guides/output/images/feature_tile.gif +0 -0
- data/guides/output/images/footer_tile.gif +0 -0
- data/guides/output/images/fxn.png +0 -0
- data/guides/output/images/grey_bullet.gif +0 -0
- data/guides/output/images/habtm.png +0 -0
- data/guides/output/images/has_many.png +0 -0
- data/guides/output/images/has_many_through.png +0 -0
- data/guides/output/images/has_one.png +0 -0
- data/guides/output/images/has_one_through.png +0 -0
- data/guides/output/images/header_backdrop.png +0 -0
- data/guides/output/images/header_tile.gif +0 -0
- data/guides/output/images/i18n/demo_html_safe.png +0 -0
- data/guides/output/images/i18n/demo_localized_pirate.png +0 -0
- data/guides/output/images/i18n/demo_translated_en.png +0 -0
- data/guides/output/images/i18n/demo_translated_pirate.png +0 -0
- data/guides/output/images/i18n/demo_translation_missing.png +0 -0
- data/guides/output/images/i18n/demo_untranslated.png +0 -0
- data/guides/output/images/icons/README +5 -0
- data/guides/output/images/icons/callouts/1.png +0 -0
- data/guides/output/images/icons/callouts/10.png +0 -0
- data/guides/output/images/icons/callouts/11.png +0 -0
- data/guides/output/images/icons/callouts/12.png +0 -0
- data/guides/output/images/icons/callouts/13.png +0 -0
- data/guides/output/images/icons/callouts/14.png +0 -0
- data/guides/output/images/icons/callouts/15.png +0 -0
- data/guides/output/images/icons/callouts/2.png +0 -0
- data/guides/output/images/icons/callouts/3.png +0 -0
- data/guides/output/images/icons/callouts/4.png +0 -0
- data/guides/output/images/icons/callouts/5.png +0 -0
- data/guides/output/images/icons/callouts/6.png +0 -0
- data/guides/output/images/icons/callouts/7.png +0 -0
- data/guides/output/images/icons/callouts/8.png +0 -0
- data/guides/output/images/icons/callouts/9.png +0 -0
- data/guides/output/images/icons/caution.png +0 -0
- data/guides/output/images/icons/example.png +0 -0
- data/guides/output/images/icons/home.png +0 -0
- data/guides/output/images/icons/important.png +0 -0
- data/guides/output/images/icons/next.png +0 -0
- data/guides/output/images/icons/note.png +0 -0
- data/guides/output/images/icons/prev.png +0 -0
- data/guides/output/images/icons/tip.png +0 -0
- data/guides/output/images/icons/up.png +0 -0
- data/guides/output/images/icons/warning.png +0 -0
- data/guides/output/images/jaimeiniesta.jpg +0 -0
- data/guides/output/images/nav_arrow.gif +0 -0
- data/guides/output/images/polymorphic.png +0 -0
- data/guides/output/images/posts_index.png +0 -0
- data/guides/output/images/radar.png +0 -0
- data/guides/output/images/rails_guides_logo.gif +0 -0
- data/guides/output/images/rails_logo_remix.gif +0 -0
- data/guides/output/images/rails_welcome.png +0 -0
- data/guides/output/images/session_fixation.png +0 -0
- data/guides/output/images/tab_grey.gif +0 -0
- data/guides/output/images/tab_info.gif +0 -0
- data/guides/output/images/tab_note.gif +0 -0
- data/guides/output/images/tab_red.gif +0 -0
- data/guides/output/images/tab_yellow.gif +0 -0
- data/guides/output/images/tab_yellow.png +0 -0
- data/guides/output/images/validation_error_messages.png +0 -0
- data/guides/output/images/vijaydev.jpg +0 -0
- data/guides/output/index.html +300 -0
- data/guides/output/initialization.html +1087 -0
- data/guides/output/javascripts/guides.js +7 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
- data/guides/output/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
- data/guides/output/javascripts/syntaxhighlighter/shCore.js +17 -0
- data/guides/output/layout.html +312 -0
- data/guides/output/layouts_and_rendering.html +1257 -0
- data/guides/output/migrations.html +751 -0
- data/guides/output/nested_model_forms.html +350 -0
- data/guides/output/performance_testing.html +858 -0
- data/guides/output/plugins.html +590 -0
- data/guides/output/rails_application_templates.html +368 -0
- data/guides/output/rails_on_rack.html +408 -0
- data/guides/output/routing.html +1246 -0
- data/guides/output/ruby_on_rails_guides_guidelines.html +218 -0
- data/guides/output/security.html +968 -0
- data/guides/output/stylesheets/fixes.css +16 -0
- data/guides/output/stylesheets/main.css +445 -0
- data/guides/output/stylesheets/print.css +52 -0
- data/guides/output/stylesheets/reset.css +43 -0
- data/guides/output/stylesheets/style.css +13 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCore.css +226 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
- data/guides/output/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +116 -0
- data/guides/output/testing.html +1182 -0
- data/guides/source/active_record_validations_callbacks.textile +3 -3
- data/guides/source/active_support_core_extensions.textile +2 -2
- data/guides/source/asset_pipeline.textile +7 -5
- data/guides/source/association_basics.textile +2 -4
- data/guides/source/command_line.textile +1 -1
- data/guides/source/configuring.textile +4 -2
- data/guides/source/contributing_to_ruby_on_rails.textile +6 -6
- data/guides/source/initialization.textile +2 -2
- data/guides/source/performance_testing.textile +1 -1
- data/guides/source/routing.textile +1 -1
- data/guides/source/security.textile +2 -2
- data/lib/rails/commands/server.rb +1 -1
- data/lib/rails/engine.rb +1 -1
- data/lib/rails/generators/app_base.rb +2 -1
- data/lib/rails/generators/base.rb +3 -3
- data/lib/rails/generators/rails/app/templates/gitignore +15 -5
- data/lib/rails/rack.rb +0 -1
- data/lib/rails/tasks/documentation.rake +7 -7
- data/lib/rails/tasks/misc.rake +0 -2
- data/lib/rails/test_unit/testing.rake +2 -0
- data/lib/rails/version.rb +2 -2
- metadata +495 -326
- data/CHANGELOG +0 -2371
- data/lib/rails/rack/content_length.rb +0 -38
@@ -0,0 +1,412 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7
|
+
|
8
|
+
<title>Ruby on Rails Guides: AJAX on Rails</title>
|
9
|
+
|
10
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
|
11
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
|
12
|
+
|
13
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
|
14
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
|
15
|
+
|
16
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" />
|
17
|
+
</head>
|
18
|
+
<body class="guide">
|
19
|
+
<div id="topNav">
|
20
|
+
<div class="wrapper">
|
21
|
+
<strong>More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
|
22
|
+
<a href="http://rubyonrails.org/">Overview</a> |
|
23
|
+
<a href="http://rubyonrails.org/download">Download</a> |
|
24
|
+
<a href="http://rubyonrails.org/deploy">Deploy</a> |
|
25
|
+
<a href="https://github.com/rails/rails">Code</a> |
|
26
|
+
<a href="http://rubyonrails.org/screencasts">Screencasts</a> |
|
27
|
+
<a href="http://rubyonrails.org/documentation">Documentation</a> |
|
28
|
+
<a href="http://rubyonrails.org/ecosystem">Ecosystem</a> |
|
29
|
+
<a href="http://rubyonrails.org/community">Community</a> |
|
30
|
+
<a href="http://weblog.rubyonrails.org/">Blog</a>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div id="header">
|
34
|
+
<div class="wrapper clearfix">
|
35
|
+
<h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
|
36
|
+
<p class="hide"><a href="#mainCol">Skip navigation</a>.</p>
|
37
|
+
<ul class="nav">
|
38
|
+
<li><a href="index.html">Home</a></li>
|
39
|
+
<li class="index"><a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu">Guides Index</a>
|
40
|
+
<div id="guides" class="clearfix" style="display: none;">
|
41
|
+
<hr />
|
42
|
+
<dl class="L">
|
43
|
+
<dt>Start Here</dt>
|
44
|
+
<dd><a href="getting_started.html">Getting Started with Rails</a></dd>
|
45
|
+
<dt>Models</dt>
|
46
|
+
<dd><a href="migrations.html">Rails Database Migrations</a></dd>
|
47
|
+
<dd><a href="active_record_validations_callbacks.html">Active Record Validations and Callbacks</a></dd>
|
48
|
+
<dd><a href="association_basics.html">Active Record Associations</a></dd>
|
49
|
+
<dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
|
50
|
+
<dt>Views</dt>
|
51
|
+
<dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd>
|
52
|
+
<dd><a href="form_helpers.html">Action View Form Helpers</a></dd>
|
53
|
+
<dt>Controllers</dt>
|
54
|
+
<dd><a href="action_controller_overview.html">Action Controller Overview</a></dd>
|
55
|
+
<dd><a href="routing.html">Rails Routing from the Outside In</a></dd>
|
56
|
+
</dl>
|
57
|
+
<dl class="R">
|
58
|
+
<dt>Digging Deeper</dt>
|
59
|
+
<dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd>
|
60
|
+
<dd><a href="i18n.html">Rails Internationalization API</a></dd>
|
61
|
+
<dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd>
|
62
|
+
<dd><a href="testing.html">Testing Rails Applications</a></dd>
|
63
|
+
<dd><a href="security.html">Securing Rails Applications</a></dd>
|
64
|
+
<dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd>
|
65
|
+
<dd><a href="performance_testing.html">Performance Testing Rails Applications</a></dd>
|
66
|
+
<dd><a href="configuring.html">Configuring Rails Applications</a></dd>
|
67
|
+
<dd><a href="command_line.html">Rails Command Line Tools and Rake Tasks</a></dd>
|
68
|
+
<dd><a href="caching_with_rails.html">Caching with Rails</a></dd>
|
69
|
+
<dd><a href="asset_pipeline.html">Asset Pipeline</a></dd>
|
70
|
+
|
71
|
+
<dt>Extending Rails</dt>
|
72
|
+
<dd><a href="plugins.html">The Basics of Creating Rails Plugins</a></dd>
|
73
|
+
<dd><a href="rails_on_rack.html">Rails on Rack</a></dd>
|
74
|
+
<dd><a href="generators.html">Creating and Customizing Rails Generators</a></dd>
|
75
|
+
|
76
|
+
<dt>Contributing to Ruby on Rails</dt>
|
77
|
+
<dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd>
|
78
|
+
<dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd>
|
79
|
+
<dd><a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a></dd>
|
80
|
+
|
81
|
+
<dt>Release Notes</dt>
|
82
|
+
<dd><a href="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</a></dd>
|
83
|
+
<dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
|
84
|
+
<dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
|
85
|
+
<dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
|
86
|
+
</dl>
|
87
|
+
</div>
|
88
|
+
</li>
|
89
|
+
<li><a href="contributing_to_ruby_on_rails.html">Contribute</a></li>
|
90
|
+
<li><a href="credits.html">Credits</a></li>
|
91
|
+
</ul>
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
<hr class="hide" />
|
95
|
+
|
96
|
+
<div id="feature">
|
97
|
+
<div class="wrapper">
|
98
|
+
<h2><span class="caps">AJAX</span> on Rails</h2>
|
99
|
+
<p>This guide covers the built-in Ajax/JavaScript functionality of Rails (and more); it will enable you to create rich and dynamic <span class="caps">AJAX</span> applications with ease! We will cover the following topics:</p>
|
100
|
+
<ul>
|
101
|
+
<li>Quick introduction to <span class="caps">AJAX</span> and related technologies</li>
|
102
|
+
<li>Unobtrusive JavaScript helpers with drivers for Prototype, jQuery etc</li>
|
103
|
+
<li>Testing JavaScript functionality</li>
|
104
|
+
</ul>
|
105
|
+
|
106
|
+
<div id="subCol">
|
107
|
+
<h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
|
108
|
+
<ol class="chapters">
|
109
|
+
<li><a href="#hello-ajax-a-quick-intro">Hello <span class="caps">AJAX</span> – a Quick Intro</a><ul><li><a href="#asynchronous-javascript-xml">Asynchronous JavaScript + <span class="caps">XML</span></a></li> <li><a href="#the-dom">The <span class="caps">DOM</span></a></li> <li><a href="#standard-html-communication-vs-ajax">Standard <span class="caps">HTML</span> communication vs <span class="caps">AJAX</span></a></li></ul></li><li><a href="#built-in-rails-helpers">Built-in Rails Helpers</a><ul><li><a href="#examples">Examples</a></li> <li><a href="#the-quintessential-ajax-rails-helper-link_to_remote">The Quintessential <span class="caps">AJAX</span> Rails Helper: link_to_remote</a></li> <li><a href="#ajax-forms"><span class="caps">AJAX</span> Forms</a></li> <li><a href="#observing-elements">Observing Elements</a></li> <li><a href="#calling-a-function-periodically">Calling a Function Periodically</a></li> <li><a href="#miscellaneous-functionality">Miscellaneous Functionality</a></li> <li><a href="#serving-javascript">Serving JavaScript</a></li></ul></li><li><a href="#testing-javascript">Testing JavaScript</a></li></ol></div>
|
110
|
+
</div>
|
111
|
+
</div>
|
112
|
+
|
113
|
+
<div id="container">
|
114
|
+
<div class="wrapper">
|
115
|
+
<div id="mainCol">
|
116
|
+
<h3 id="hello-ajax-a-quick-intro">1 Hello <span class="caps">AJAX</span> – a Quick Intro</h3>
|
117
|
+
<p>You’ll need the basics of <span class="caps">DOM</span>, <span class="caps">HTTP</span> requests and other topics discussed here to really understand Ajax on Rails.</p>
|
118
|
+
<h4 id="asynchronous-javascript-xml">1.1 Asynchronous JavaScript + <span class="caps">XML</span></h4>
|
119
|
+
<p>Basic terminology, new style of creating web apps</p>
|
120
|
+
<h4 id="the-dom">1.2 The <span class="caps">DOM</span></h4>
|
121
|
+
<p>basics of the <span class="caps">DOM</span>, how is it built, properties, features, why is it central to <span class="caps">AJAX</span></p>
|
122
|
+
<h4 id="standard-html-communication-vs-ajax">1.3 Standard <span class="caps">HTML</span> communication vs <span class="caps">AJAX</span></h4>
|
123
|
+
<p>How do ‘standard’ and <span class="caps">AJAX</span> requests differ, why does this matter for understanding <span class="caps">AJAX</span> on Rails (tie in for *_remote helpers, the next section)</p>
|
124
|
+
<h3 id="built-in-rails-helpers">2 Built-in Rails Helpers</h3>
|
125
|
+
<p>Rails 3.1 ships with <a href="http://jquery.com">jQuery</a> as the default JavaScript library. The Gemfile contains <tt>gem ‘jquery-rails’</tt> which makes the jQuery files available to the application automatically. This can be accessed as:</p>
|
126
|
+
<div class="code_container">
|
127
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
128
|
+
javascript_include_tag :defaults
|
129
|
+
</pre>
|
130
|
+
</div>
|
131
|
+
<h4 id="examples">2.1 Examples</h4>
|
132
|
+
<p>All the remote_method helpers has been removed. To make them working with <span class="caps">AJAX</span>, simply pass the <tt>:remote => true</tt> option to the original non-remote method.</p>
|
133
|
+
<div class="code_container">
|
134
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
135
|
+
button_to "New", :action => "new", :form_class => "new-thing"
|
136
|
+
</pre>
|
137
|
+
</div>
|
138
|
+
<p>will produce</p>
|
139
|
+
<div class="code_container">
|
140
|
+
<pre class="brush: xml; gutter: false; toolbar: false">
|
141
|
+
<form method="post" action="/controller/new" class="new-thing">
|
142
|
+
<div><input value="New" type="submit" /></div>
|
143
|
+
</form>
|
144
|
+
</pre>
|
145
|
+
</div>
|
146
|
+
<div class="code_container">
|
147
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
148
|
+
button_to "Create", :action => "create", :remote => true, :form => { "data-type" => "json" }
|
149
|
+
</pre>
|
150
|
+
</div>
|
151
|
+
<p>will produce</p>
|
152
|
+
<div class="code_container">
|
153
|
+
<pre class="brush: xml; gutter: false; toolbar: false">
|
154
|
+
<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
|
155
|
+
<div><input value="Create" type="submit" /></div>
|
156
|
+
</form>
|
157
|
+
</pre>
|
158
|
+
</div>
|
159
|
+
<div class="code_container">
|
160
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
161
|
+
button_to "Delete Image", { :action => "delete", :id => @image.id },
|
162
|
+
:confirm => "Are you sure?", :method => :delete
|
163
|
+
</pre>
|
164
|
+
</div>
|
165
|
+
<p>will produce</p>
|
166
|
+
<div class="code_container">
|
167
|
+
<pre class="brush: xml; gutter: false; toolbar: false">
|
168
|
+
<form method="post" action="/images/delete/1" class="button_to">
|
169
|
+
<div>
|
170
|
+
<input type="hidden" name="_method" value="delete" />
|
171
|
+
<input data-confirm='Are you sure?' value="Delete" type="submit" />
|
172
|
+
</div>
|
173
|
+
</form>
|
174
|
+
</pre>
|
175
|
+
</div>
|
176
|
+
<div class="code_container">
|
177
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
178
|
+
button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
|
179
|
+
:method => "delete", :remote => true, :disable_with => 'loading...')
|
180
|
+
</pre>
|
181
|
+
</div>
|
182
|
+
<p>will produce</p>
|
183
|
+
<div class="code_container">
|
184
|
+
<pre class="brush: xml; gutter: false; toolbar: false">
|
185
|
+
<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
|
186
|
+
<div>
|
187
|
+
<input name='_method' value='delete' type='hidden' />
|
188
|
+
<input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
|
189
|
+
</div>
|
190
|
+
</form>
|
191
|
+
</pre>
|
192
|
+
</div>
|
193
|
+
<p>You can also choose to use Prototype instead of jQuery and specify the option using <tt>-j</tt> switch while generating the application.</p>
|
194
|
+
<div class="code_container">
|
195
|
+
<pre class="brush: plain; gutter: false; toolbar: false">
|
196
|
+
rails new app_name -j prototype
|
197
|
+
</pre>
|
198
|
+
</div>
|
199
|
+
<p>You are ready to add some <span class="caps">AJAX</span> love to your Rails app!</p>
|
200
|
+
<h4 id="the-quintessential-ajax-rails-helper-link_to_remote">2.2 The Quintessential <span class="caps">AJAX</span> Rails Helper: link_to_remote</h4>
|
201
|
+
<p>Let’s start with what is probably the most often used helper: <tt>link_to_remote</tt>. It has an interesting feature from the documentation point of view: the options supplied to <tt>link_to_remote</tt> are shared by all other <span class="caps">AJAX</span> helpers, so learning the mechanics and options of <tt>link_to_remote</tt> is a great help when using other helpers.</p>
|
202
|
+
<p>The signature of <tt>link_to_remote</tt> function is the same as that of the standard <tt>link_to</tt> helper:</p>
|
203
|
+
<div class="code_container">
|
204
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
205
|
+
def link_to_remote(name, options = {}, html_options = nil)
|
206
|
+
</pre>
|
207
|
+
</div>
|
208
|
+
<p>And here is a simple example of link_to_remote in action:</p>
|
209
|
+
<div class="code_container">
|
210
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
211
|
+
link_to_remote "Add to cart",
|
212
|
+
:url => add_to_cart_url(product.id),
|
213
|
+
:update => "cart"
|
214
|
+
</pre>
|
215
|
+
</div>
|
216
|
+
<ul>
|
217
|
+
<li>The very first parameter, a string, is the text of the link which appears on the page.</li>
|
218
|
+
<li>The second parameter, the <tt>options</tt> hash is the most interesting part as it has the <span class="caps">AJAX</span> specific stuff:
|
219
|
+
<ul>
|
220
|
+
<li><strong>:url</strong> This is the only parameter that is always required to generate the simplest remote link (technically speaking, it is not required, you can pass an empty <tt>options</tt> hash to <tt>link_to_remote</tt> – but in this case the <span class="caps">URL</span> used for the <span class="caps">POST</span> request will be equal to your current <span class="caps">URL</span> which is probably not your intention). This <span class="caps">URL</span> points to your <span class="caps">AJAX</span> action handler. The <span class="caps">URL</span> is typically specified by Rails <span class="caps">REST</span> view helpers, but you can use the <tt>url_for</tt> format too.</li>
|
221
|
+
<li><strong>:update</strong> Specifying a <span class="caps">DOM</span> id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this – however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation:</li>
|
222
|
+
</ul></li>
|
223
|
+
</ul>
|
224
|
+
<div class="code_container">
|
225
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
226
|
+
link_to_remote "Add to cart",
|
227
|
+
:url => add_to_cart_url(product),
|
228
|
+
:update => { :success => "cart", :failure => "error" }
|
229
|
+
</pre>
|
230
|
+
</div>
|
231
|
+
<p>If the server returns 200, the output of the above example is equivalent to our first, simple one. However, in case of error, the element with the <span class="caps">DOM</span> id <tt>error</tt> is updated rather than the <tt>cart</tt> element.</p>
|
232
|
+
|
233
|
+
<ul>
|
234
|
+
<li><strong>position</strong> By default (i.e. when not specifying this option, like in the examples before) the response is injected into the element with the specified <span class="caps">DOM</span> id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content – the only question is where to place the new content? This can specified by the <tt>position</tt> parameter, with four possibilities:
|
235
|
+
<ul>
|
236
|
+
<li><tt>:before</tt> Inserts the response text just before the target element. More precisely, it creates a text node from the response and inserts it as the left sibling of the target element.</li>
|
237
|
+
<li><tt>:after</tt> Similar behavior to <tt>:before</tt>, but in this case the response is inserted after the target element.</li>
|
238
|
+
<li><tt>:top</tt> Inserts the text into the target element, before it’s original content. If the target element was empty, this is equivalent with not specifying <tt>:position</tt> at all.</li>
|
239
|
+
<li><tt>:bottom</tt> The counterpart of <tt>:top</tt>: the response is inserted after the target element’s original content.</li>
|
240
|
+
</ul></li>
|
241
|
+
</ul><p>A typical example of using <tt>:bottom</tt> is inserting a new <li> element into an existing list:</p>
|
242
|
+
<div class="code_container">
|
243
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
244
|
+
link_to_remote "Add new item",
|
245
|
+
:url => items_url,
|
246
|
+
:update => 'item_list',
|
247
|
+
:position => :bottom
|
248
|
+
</pre>
|
249
|
+
</div>
|
250
|
+
|
251
|
+
<ul>
|
252
|
+
<li><strong>:method</strong> Most typically you want to use a <span class="caps">POST</span> request when adding a remote link to your view so this is the default behavior. However, sometimes you’ll want to update (<span class="caps">PUT</span>) or delete/destroy (<span class="caps">DELETE</span>) something and you can specify this with the <tt>:method</tt> option. Let’s see an example for a typical <span class="caps">AJAX</span> link for deleting an item from a list:</li>
|
253
|
+
</ul><div class="code_container">
|
254
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
255
|
+
link_to_remote "Delete the item",
|
256
|
+
:url => item_url(item),
|
257
|
+
:method => :delete
|
258
|
+
</pre>
|
259
|
+
</div>
|
260
|
+
<p>Note that if we wouldn’t override the default behavior (<span class="caps">POST</span>), the above snippet would route to the create action rather than destroy.</p>
|
261
|
+
|
262
|
+
<ul>
|
263
|
+
<li><strong>JavaScript filters</strong> You can customize the remote call further by wrapping it with some JavaScript code. Let’s say in the previous example, when deleting a link, you’d like to ask for a confirmation by showing a simple modal text box to the user. This is a typical example what you can accomplish with these options – let’s see them one by one:
|
264
|
+
<ul>
|
265
|
+
<li><tt>:confirm</tt> => <tt>msg</tt> Pops up a JavaScript confirmation dialog, displaying <tt>msg</tt>. If the user chooses ‘OK’, the request is launched, otherwise canceled.</li>
|
266
|
+
<li><tt>:condition</tt> => <tt>code</tt> Evaluates <tt>code</tt> (which should evaluate to a boolean) and proceeds if it’s true, cancels the request otherwise.</li>
|
267
|
+
<li><tt>:before</tt> => <tt>code</tt> Evaluates the <tt>code</tt> just before launching the request. The output of the code has no influence on the execution. Typically used show a progress indicator (see this in action in the next example).</li>
|
268
|
+
<li><tt>:after</tt> => <tt>code</tt> Evaluates the <tt>code</tt> after launching the request. Note that this is different from the <tt>:success</tt> or <tt>:complete</tt> callback (covered in the next section) since those are triggered after the request is completed, while the code snippet passed to <tt>:after</tt> is evaluated after the remote call is made. A common example is to disable elements on the page or otherwise prevent further action while the request is completed.</li>
|
269
|
+
<li><tt>:submit</tt> => <tt>dom_id</tt> This option does not make sense for <tt>link_to_remote</tt>, but we’ll cover it for the sake of completeness. By default, the parent element of the form elements the user is going to submit is the current form – use this option if you want to change the default behavior. By specifying this option you can change the parent element to the element specified by the <span class="caps">DOM</span> id <tt>dom_id</tt>.</li>
|
270
|
+
<li><tt>:with</tt> > <tt>code</tt> The JavaScript code snippet in <tt>code</tt> is evaluated and added to the request <span class="caps">URL</span> as a parameter (or set of parameters). Therefore, <tt>code</tt> should return a valid <span class="caps">URL</span> query string (like “item_type=8” or “item_type=8&sort=true”). Usually you want to obtain some value(s) from the page – let’s see an example:</li>
|
271
|
+
</ul></li>
|
272
|
+
</ul><div class="code_container">
|
273
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
274
|
+
link_to_remote "Update record",
|
275
|
+
:url => record_url(record),
|
276
|
+
:method => :put,
|
277
|
+
:with => "'status=' + 'encodeURIComponent($('status').value) + '&completed=' + $('completed')"
|
278
|
+
</pre>
|
279
|
+
</div>
|
280
|
+
<p>This generates a remote link which adds 2 parameters to the standard <span class="caps">URL</span> generated by Rails, taken from the page (contained in the elements matched by the ‘status’ and ‘completed’ <span class="caps">DOM</span> id).</p>
|
281
|
+
|
282
|
+
<ul>
|
283
|
+
<li><strong>Callbacks</strong> Since an <span class="caps">AJAX</span> call is typically asynchronous, as it’s name suggests (this is not a rule, and you can fire a synchronous request – see the last option, <tt>:type</tt>) your only way of communicating with a request once it is fired is via specifying callbacks. There are six options at your disposal (in fact 508, counting all possible response types, but these six are the most frequent and therefore specified by a constant):
|
284
|
+
<ul>
|
285
|
+
<li><tt>:loading:</tt> => <tt>code</tt> The request is in the process of receiving the data, but the transfer is not completed yet.</li>
|
286
|
+
<li><tt>:loaded:</tt> => <tt>code</tt> The transfer is completed, but the data is not processed and returned yet</li>
|
287
|
+
<li><tt>:interactive:</tt> => <tt>code</tt> One step after <tt>:loaded</tt>: The data is fully received and being processed</li>
|
288
|
+
<li><tt>:success:</tt> => <tt>code</tt> The data is fully received, parsed and the server responded with “200 OK”</li>
|
289
|
+
<li><tt>:failure:</tt> => <tt>code</tt> The data is fully received, parsed and the server responded with <strong>anything</strong> but “200 OK” (typically 404 or 500, but in general with any status code ranging from 100 to 509)</li>
|
290
|
+
<li><tt>:complete:</tt> => <tt>code</tt> The combination of the previous two: The request has finished receiving and parsing the data, and returned a status code (which can be anything).</li>
|
291
|
+
<li>Any other status code ranging from 100 to 509: Additionally you might want to check for other <span class="caps">HTTP</span> status codes, such as 404. In this case simply use the status code as a number:
|
292
|
+
<div class="code_container">
|
293
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
294
|
+
link_to_remote "Add new item",
|
295
|
+
:url => items_url,
|
296
|
+
:update => "item_list",
|
297
|
+
404 => "alert('Item not found!')"
|
298
|
+
</pre>
|
299
|
+
</div>
|
300
|
+
</li>
|
301
|
+
</ul></li>
|
302
|
+
</ul><p>Let’s see a typical example for the most frequent callbacks, <tt>:success</tt>, <tt>:failure</tt> and <tt>:complete</tt> in action:</p>
|
303
|
+
<div class="code_container">
|
304
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
305
|
+
link_to_remote "Add new item",
|
306
|
+
:url => items_url,
|
307
|
+
:update => "item_list",
|
308
|
+
:before => "$('progress').show()",
|
309
|
+
:complete => "$('progress').hide()",
|
310
|
+
:success => "display_item_added(request)",
|
311
|
+
:failure => "display_error(request)"
|
312
|
+
</pre>
|
313
|
+
</div>
|
314
|
+
|
315
|
+
<ul>
|
316
|
+
<li><strong>:type</strong> If you want to fire a synchronous request for some obscure reason (blocking the browser while the request is processed and doesn’t return a status code), you can use the <tt>:type</tt> option with the value of <tt>:synchronous</tt>.</li>
|
317
|
+
</ul></li>
|
318
|
+
<li>Finally, using the <tt>html_options</tt> parameter you can add <span class="caps">HTML</span> attributes to the generated tag. It works like the same parameter of the <tt>link_to</tt> helper. There are interesting side effects for the <tt>href</tt> and <tt>onclick</tt> parameters though:
|
319
|
+
<ul>
|
320
|
+
<li>If you specify the <tt>href</tt> parameter, the <span class="caps">AJAX</span> link will degrade gracefully, i.e. the link will point to the <span class="caps">URL</span> even if JavaScript is disabled in the client browser</li>
|
321
|
+
<li><tt>link_to_remote</tt> gains it’s <span class="caps">AJAX</span> behavior by specifying the remote call in the onclick handler of the link. If you supply <tt>html_options[:onclick]</tt> you override the default behavior, so use this with care!</li>
|
322
|
+
</ul><p>We are finished with <tt>link_to_remote</tt>. I know this is quite a lot to digest for one helper function, but remember, these options are common for all the rest of the Rails view helpers, so we will take a look at the differences / additional parameters in the next sections.</p>
|
323
|
+
<h4 id="ajax-forms">2.3 <span class="caps">AJAX</span> Forms</h4>
|
324
|
+
<p>There are three different ways of adding <span class="caps">AJAX</span> forms to your view using Rails Prototype helpers. They are slightly different, but striving for the same goal: instead of submitting the form using the standard <span class="caps">HTTP</span> request/response cycle, it is submitted asynchronously, thus not reloading the page. These methods are the following:</p>
|
325
|
+
<ul>
|
326
|
+
<li><tt>remote_form_for</tt> (and it’s alias <tt>form_remote_for</tt>) is tied to Rails most tightly of the three since it takes a resource, model or array of resources (in case of a nested resource) as a parameter.</li>
|
327
|
+
<li><tt>form_remote_tag</tt> AJAXifies the form by serializing and sending it’s data in the background</li>
|
328
|
+
<li><tt>submit_to_remote</tt> and <tt>button_to_remote</tt> is more rarely used than the previous two. Rather than creating an <span class="caps">AJAX</span> form, you add a button/input</li>
|
329
|
+
</ul>
|
330
|
+
<p>Let’s see them in action one by one!</p>
|
331
|
+
<h5 id="remote_form_for">2.3.1 <tt>remote_form_for</tt></h5>
|
332
|
+
<h5 id="form_remote_tag">2.3.2 <tt>form_remote_tag</tt></h5>
|
333
|
+
<h5 id="submit_to_remote">2.3.3 <tt>submit_to_remote</tt></h5>
|
334
|
+
<h4 id="observing-elements">2.4 Observing Elements</h4>
|
335
|
+
<h5 id="observe_field">2.4.1 <tt>observe_field</tt></h5>
|
336
|
+
<h5 id="observe_form">2.4.2 <tt>observe_form</tt></h5>
|
337
|
+
<h4 id="calling-a-function-periodically">2.5 Calling a Function Periodically</h4>
|
338
|
+
<h5 id="periodically_call_remote">2.5.1 <tt>periodically_call_remote</tt></h5>
|
339
|
+
<h4 id="miscellaneous-functionality">2.6 Miscellaneous Functionality</h4>
|
340
|
+
<h5 id="remote_function">2.6.1 <tt>remote_function</tt></h5>
|
341
|
+
<h5 id="update_page">2.6.2 <tt>update_page</tt></h5>
|
342
|
+
<h4 id="serving-javascript">2.7 Serving JavaScript</h4>
|
343
|
+
<p>First we’ll check out how to send JavaScript to the server manually. You are practically never going to need this, but it’s interesting to understand what’s going on under the hood.</p>
|
344
|
+
<div class="code_container">
|
345
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
346
|
+
def javascript_test
|
347
|
+
render :text => "alert('Hello, world!')",
|
348
|
+
:content_type => "text/javascript"
|
349
|
+
end
|
350
|
+
</pre>
|
351
|
+
</div>
|
352
|
+
<p>(Note: if you want to test the above method, create a <tt>link_to_remote</tt> with a single parameter – <tt>:url</tt>, pointing to the <tt>javascript_test</tt> action)</p>
|
353
|
+
<p>What happens here is that by specifying the Content-Type header variable, we instruct the browser to evaluate the text we are sending over (rather than displaying it as plain text, which is the default behavior).</p>
|
354
|
+
<h3 id="testing-javascript">3 Testing JavaScript</h3>
|
355
|
+
<p>JavaScript testing reminds me the definition of the world ‘classic’ by Mark Twain: “A classic is something that everybody wants to have read and nobody wants to read.” It’s similar with JavaScript testing: everyone would like to have it, yet it’s not done by too much developers as it is tedious, complicated, there is a proliferation of tools and no consensus/accepted best practices, but we will nevertheless take a stab at it:</p>
|
356
|
+
<ul>
|
357
|
+
<li>(Fire)Watir</li>
|
358
|
+
<li>Selenium</li>
|
359
|
+
<li>Celerity/Culerity</li>
|
360
|
+
<li>Cucumber+Webrat</li>
|
361
|
+
<li>Mention stuff like screw.unit/jsSpec</li>
|
362
|
+
</ul>
|
363
|
+
<p>Note to self: check out the RailsConf JS testing video</p>
|
364
|
+
|
365
|
+
<h3>Feedback</h3>
|
366
|
+
<p>
|
367
|
+
You're encouraged to help improve the quality of this guide.
|
368
|
+
</p>
|
369
|
+
<p>
|
370
|
+
If you see any typos or factual errors you are confident to
|
371
|
+
patch, please clone <a href="https://github.com/lifo/docrails">docrails</a>
|
372
|
+
and push the change yourself. That branch of Rails has public write access.
|
373
|
+
Commits are still reviewed, but that happens after you've submitted your
|
374
|
+
contribution. <a href="https://github.com/lifo/docrails">docrails</a> is
|
375
|
+
cross-merged with master periodically.
|
376
|
+
</p>
|
377
|
+
<p>
|
378
|
+
You may also find incomplete content, or stuff that is not up to date.
|
379
|
+
Please do add any missing documentation for master. Check the
|
380
|
+
<a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a>
|
381
|
+
for style and conventions.
|
382
|
+
</p>
|
383
|
+
<p>
|
384
|
+
If for whatever reason you spot something to fix but cannot patch it yourself, please
|
385
|
+
<a href="https://github.com/rails/rails/issues">open an issue</a>.
|
386
|
+
</p>
|
387
|
+
<p>And last but not least, any kind of discussion regarding Ruby on Rails
|
388
|
+
documentation is very welcome in the <a href="http://groups.google.com/group/rubyonrails-docs">rubyonrails-docs mailing list</a>.
|
389
|
+
</p>
|
390
|
+
</div>
|
391
|
+
</div>
|
392
|
+
</div>
|
393
|
+
|
394
|
+
<hr class="hide" />
|
395
|
+
<div id="footer">
|
396
|
+
<div class="wrapper">
|
397
|
+
<p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</p>
|
398
|
+
<p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
|
399
|
+
</div>
|
400
|
+
</div>
|
401
|
+
|
402
|
+
<script type="text/javascript" src="javascripts/guides.js"></script>
|
403
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
|
404
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
|
405
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushXml.js"></script>
|
406
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushSql.js"></script>
|
407
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
|
408
|
+
<script type="text/javascript">
|
409
|
+
SyntaxHighlighter.all()
|
410
|
+
</script>
|
411
|
+
</body>
|
412
|
+
</html>
|
@@ -0,0 +1,317 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7
|
+
|
8
|
+
<title>Ruby on Rails Guides: API Documentation Guidelines</title>
|
9
|
+
|
10
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
|
11
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
|
12
|
+
|
13
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
|
14
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
|
15
|
+
|
16
|
+
<link rel="stylesheet" type="text/css" href="stylesheets/fixes.css" />
|
17
|
+
</head>
|
18
|
+
<body class="guide">
|
19
|
+
<div id="topNav">
|
20
|
+
<div class="wrapper">
|
21
|
+
<strong>More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
|
22
|
+
<a href="http://rubyonrails.org/">Overview</a> |
|
23
|
+
<a href="http://rubyonrails.org/download">Download</a> |
|
24
|
+
<a href="http://rubyonrails.org/deploy">Deploy</a> |
|
25
|
+
<a href="https://github.com/rails/rails">Code</a> |
|
26
|
+
<a href="http://rubyonrails.org/screencasts">Screencasts</a> |
|
27
|
+
<a href="http://rubyonrails.org/documentation">Documentation</a> |
|
28
|
+
<a href="http://rubyonrails.org/ecosystem">Ecosystem</a> |
|
29
|
+
<a href="http://rubyonrails.org/community">Community</a> |
|
30
|
+
<a href="http://weblog.rubyonrails.org/">Blog</a>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div id="header">
|
34
|
+
<div class="wrapper clearfix">
|
35
|
+
<h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
|
36
|
+
<p class="hide"><a href="#mainCol">Skip navigation</a>.</p>
|
37
|
+
<ul class="nav">
|
38
|
+
<li><a href="index.html">Home</a></li>
|
39
|
+
<li class="index"><a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu">Guides Index</a>
|
40
|
+
<div id="guides" class="clearfix" style="display: none;">
|
41
|
+
<hr />
|
42
|
+
<dl class="L">
|
43
|
+
<dt>Start Here</dt>
|
44
|
+
<dd><a href="getting_started.html">Getting Started with Rails</a></dd>
|
45
|
+
<dt>Models</dt>
|
46
|
+
<dd><a href="migrations.html">Rails Database Migrations</a></dd>
|
47
|
+
<dd><a href="active_record_validations_callbacks.html">Active Record Validations and Callbacks</a></dd>
|
48
|
+
<dd><a href="association_basics.html">Active Record Associations</a></dd>
|
49
|
+
<dd><a href="active_record_querying.html">Active Record Query Interface</a></dd>
|
50
|
+
<dt>Views</dt>
|
51
|
+
<dd><a href="layouts_and_rendering.html">Layouts and Rendering in Rails</a></dd>
|
52
|
+
<dd><a href="form_helpers.html">Action View Form Helpers</a></dd>
|
53
|
+
<dt>Controllers</dt>
|
54
|
+
<dd><a href="action_controller_overview.html">Action Controller Overview</a></dd>
|
55
|
+
<dd><a href="routing.html">Rails Routing from the Outside In</a></dd>
|
56
|
+
</dl>
|
57
|
+
<dl class="R">
|
58
|
+
<dt>Digging Deeper</dt>
|
59
|
+
<dd><a href="active_support_core_extensions.html">Active Support Core Extensions</a></dd>
|
60
|
+
<dd><a href="i18n.html">Rails Internationalization API</a></dd>
|
61
|
+
<dd><a href="action_mailer_basics.html">Action Mailer Basics</a></dd>
|
62
|
+
<dd><a href="testing.html">Testing Rails Applications</a></dd>
|
63
|
+
<dd><a href="security.html">Securing Rails Applications</a></dd>
|
64
|
+
<dd><a href="debugging_rails_applications.html">Debugging Rails Applications</a></dd>
|
65
|
+
<dd><a href="performance_testing.html">Performance Testing Rails Applications</a></dd>
|
66
|
+
<dd><a href="configuring.html">Configuring Rails Applications</a></dd>
|
67
|
+
<dd><a href="command_line.html">Rails Command Line Tools and Rake Tasks</a></dd>
|
68
|
+
<dd><a href="caching_with_rails.html">Caching with Rails</a></dd>
|
69
|
+
<dd><a href="asset_pipeline.html">Asset Pipeline</a></dd>
|
70
|
+
|
71
|
+
<dt>Extending Rails</dt>
|
72
|
+
<dd><a href="plugins.html">The Basics of Creating Rails Plugins</a></dd>
|
73
|
+
<dd><a href="rails_on_rack.html">Rails on Rack</a></dd>
|
74
|
+
<dd><a href="generators.html">Creating and Customizing Rails Generators</a></dd>
|
75
|
+
|
76
|
+
<dt>Contributing to Ruby on Rails</dt>
|
77
|
+
<dd><a href="contributing_to_ruby_on_rails.html">Contributing to Ruby on Rails</a></dd>
|
78
|
+
<dd><a href="api_documentation_guidelines.html">API Documentation Guidelines</a></dd>
|
79
|
+
<dd><a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a></dd>
|
80
|
+
|
81
|
+
<dt>Release Notes</dt>
|
82
|
+
<dd><a href="3_1_release_notes.html">Ruby on Rails 3.1 Release Notes</a></dd>
|
83
|
+
<dd><a href="3_0_release_notes.html">Ruby on Rails 3.0 Release Notes</a></dd>
|
84
|
+
<dd><a href="2_3_release_notes.html">Ruby on Rails 2.3 Release Notes</a></dd>
|
85
|
+
<dd><a href="2_2_release_notes.html">Ruby on Rails 2.2 Release Notes</a></dd>
|
86
|
+
</dl>
|
87
|
+
</div>
|
88
|
+
</li>
|
89
|
+
<li><a href="contributing_to_ruby_on_rails.html">Contribute</a></li>
|
90
|
+
<li><a href="credits.html">Credits</a></li>
|
91
|
+
</ul>
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
<hr class="hide" />
|
95
|
+
|
96
|
+
<div id="feature">
|
97
|
+
<div class="wrapper">
|
98
|
+
<h2><span class="caps">API</span> Documentation Guidelines</h2>
|
99
|
+
<p>This guide documents the Ruby on Rails <span class="caps">API</span> documentation guidelines.</p>
|
100
|
+
|
101
|
+
<div id="subCol">
|
102
|
+
<h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
|
103
|
+
<ol class="chapters">
|
104
|
+
<li><a href="#rdoc">RDoc</a></li><li><a href="#wording">Wording</a></li><li><a href="#english">English</a></li><li><a href="#example-code">Example Code</a></li><li><a href="#filenames">Filenames</a></li><li><a href="#fonts">Fonts</a><ul><li><a href="#fixed-width-font">Fixed-width Font</a></li> <li><a href="#regular-font">Regular Font</a></li></ul></li><li><a href="#description-lists">Description Lists</a></li><li><a href="#dynamically-generated-methods">Dynamically Generated Methods</a></li></ol></div>
|
105
|
+
</div>
|
106
|
+
</div>
|
107
|
+
|
108
|
+
<div id="container">
|
109
|
+
<div class="wrapper">
|
110
|
+
<div id="mainCol">
|
111
|
+
<h3 id="rdoc">1 RDoc</h3>
|
112
|
+
<p>The Rails <span class="caps">API</span> documentation is generated with RDoc 2.5. Please consult the documentation for help with the <a href="http://rdoc.rubyforge.org/RDoc/Markup.html">markup</a>, and take into account also these <a href="http://rdoc.rubyforge.org/RDoc/Parser/Ruby.html">additional directives</a>.</p>
|
113
|
+
<h3 id="wording">2 Wording</h3>
|
114
|
+
<p>Write simple, declarative sentences. Brevity is a plus: get to the point.</p>
|
115
|
+
<p>Write in present tense: “Returns a hash that…”, rather than “Returned a hash that…” or “Will return a hash that…”.</p>
|
116
|
+
<p>Start comments in upper case, follow regular punctuation rules:</p>
|
117
|
+
<div class="code_container">
|
118
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
119
|
+
# Declares an attribute reader backed by an internally-named instance variable.
|
120
|
+
def attr_internal_reader(*attrs)
|
121
|
+
...
|
122
|
+
end
|
123
|
+
</pre>
|
124
|
+
</div>
|
125
|
+
<p>Communicate to the reader the current way of doing things, both explicitly and implicitly. Use the recommended idioms in edge, reorder sections to emphasize favored approaches if needed, etc. The documentation should be a model for best practices and canonical, modern Rails usage.</p>
|
126
|
+
<p>Documentation has to be concise but comprehensive. Explore and document edge cases. What happens if a module is anonymous? What if a collection is empty? What if an argument is nil?</p>
|
127
|
+
<p>The proper names of Rails components have a space in between the words, like “Active Support”. <tt>ActiveRecord</tt> is a Ruby module, whereas Active Record is an <span class="caps">ORM</span>. All Rails documentation should consistently refer to Rails components by their proper name, and if in your next blog post or presentation you remember this tidbit and take it into account that’d be phenomenal.</p>
|
128
|
+
<p>Spell names correctly: Arel, Test::Unit, RSpec, <span class="caps">HTML</span>, MySQL, JavaScript, <span class="caps">ERB</span>. When in doubt, please have a look at some authoritative source like their official documentation.</p>
|
129
|
+
<p>Use the article “an” for “<span class="caps">SQL</span>”, as in “an <span class="caps">SQL</span> statement”. Also “an SQLite database”.</p>
|
130
|
+
<h3 id="english">3 English</h3>
|
131
|
+
<p>Please use American English (<em>color</em>, <em>center</em>, <em>modularize</em>, etc.). See <a href="http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences">a list of American and British English spelling differences here</a>.</p>
|
132
|
+
<h3 id="example-code">4 Example Code</h3>
|
133
|
+
<p>Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas.</p>
|
134
|
+
<p>Use two spaces to indent chunks of code—that is two spaces with respect to the left margin; the examples
|
135
|
+
themselves should use <a href="contributing_to_ruby_on_rails.html#follow-the-coding-conventions">Rails coding conventions</a>.</p>
|
136
|
+
<p>Short docs do not need an explicit “Examples” label to introduce snippets, they just follow paragraphs:</p>
|
137
|
+
<div class="code_container">
|
138
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
139
|
+
# Converts a collection of elements into a formatted string by calling
|
140
|
+
# <tt>to_s</tt> on all elements and joining them.
|
141
|
+
#
|
142
|
+
# Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
|
143
|
+
</pre>
|
144
|
+
</div>
|
145
|
+
<p>On the other hand, big chunks of structured documentation may have a separate “Examples” section:</p>
|
146
|
+
<div class="code_container">
|
147
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
148
|
+
# ==== Examples
|
149
|
+
#
|
150
|
+
# Person.exists?(5)
|
151
|
+
# Person.exists?('5')
|
152
|
+
# Person.exists?(:name => "David")
|
153
|
+
# Person.exists?(['name LIKE ?', "%#{query}%"])
|
154
|
+
</pre>
|
155
|
+
</div>
|
156
|
+
<p>The result of expressions follow them and are introduced by "# => ", vertically aligned:</p>
|
157
|
+
<div class="code_container">
|
158
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
159
|
+
# For checking if a fixnum is even or odd.
|
160
|
+
#
|
161
|
+
# 1.even? # => false
|
162
|
+
# 1.odd? # => true
|
163
|
+
# 2.even? # => true
|
164
|
+
# 2.odd? # => false
|
165
|
+
</pre>
|
166
|
+
</div>
|
167
|
+
<p>If a line is too long, the comment may be placed on the next line:</p>
|
168
|
+
<div class="code_container">
|
169
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
170
|
+
# label(:post, :title)
|
171
|
+
# # => <label for="post_title">Title</label>
|
172
|
+
#
|
173
|
+
# label(:post, :title, "A short title")
|
174
|
+
# # => <label for="post_title">A short title</label>
|
175
|
+
#
|
176
|
+
# label(:post, :title, "A short title", :class => "title_label")
|
177
|
+
# # => <label for="post_title" class="title_label">A short title</label>
|
178
|
+
</pre>
|
179
|
+
</div>
|
180
|
+
<p>Avoid using any printing methods like <tt>puts</tt> or <tt>p</tt> for that purpose.</p>
|
181
|
+
<p>On the other hand, regular comments do not use an arrow:</p>
|
182
|
+
<div class="code_container">
|
183
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
184
|
+
# polymorphic_url(record) # same as comment_url(record)
|
185
|
+
</pre>
|
186
|
+
</div>
|
187
|
+
<h3 id="filenames">5 Filenames</h3>
|
188
|
+
<p>As a rule of thumb use filenames relative to the application root:</p>
|
189
|
+
<div class="code_container">
|
190
|
+
<pre class="brush: plain; gutter: false; toolbar: false">
|
191
|
+
config/routes.rb # YES
|
192
|
+
routes.rb # NO
|
193
|
+
RAILS_ROOT/config/routes.rb # NO
|
194
|
+
</pre>
|
195
|
+
</div>
|
196
|
+
<h3 id="fonts">6 Fonts</h3>
|
197
|
+
<h4 id="fixed-width-font">6.1 Fixed-width Font</h4>
|
198
|
+
<p>Use fixed-width fonts for:</p>
|
199
|
+
<ul>
|
200
|
+
<li>constants, in particular class and module names</li>
|
201
|
+
<li>method names</li>
|
202
|
+
<li>literals like <tt>nil</tt>, <tt>false</tt>, <tt>true</tt>, <tt>self</tt></li>
|
203
|
+
<li>symbols</li>
|
204
|
+
<li>method parameters</li>
|
205
|
+
<li>file names</li>
|
206
|
+
</ul>
|
207
|
+
<div class="code_container">
|
208
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
209
|
+
class Array
|
210
|
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
211
|
+
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
212
|
+
def to_param
|
213
|
+
collect { |e| e.to_param }.join '/'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
</pre>
|
217
|
+
</div>
|
218
|
+
<div class="warning"><p>Using a pair of <tt>+...+</tt> for fixed-width font only works with <strong>words</strong>; that is: anything matching <tt>\A\w+\z</tt>. For anything else use <tt><tt>...</tt></tt>, notably symbols, setters, inline snippets, etc:</p></div>
|
219
|
+
<h4 id="regular-font">6.2 Regular Font</h4>
|
220
|
+
<p>When “true” and “false” are English words rather than Ruby keywords use a regular font:</p>
|
221
|
+
<div class="code_container">
|
222
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
223
|
+
# If <tt>reload_plugins?</tt> is false, add this to your plugin's <tt>init.rb</tt>
|
224
|
+
# to make it reloadable:
|
225
|
+
#
|
226
|
+
# Dependencies.load_once_paths.delete lib_path
|
227
|
+
</pre>
|
228
|
+
</div>
|
229
|
+
<h3 id="description-lists">7 Description Lists</h3>
|
230
|
+
<p>In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols):</p>
|
231
|
+
<div class="code_container">
|
232
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
233
|
+
# * <tt>:allow_nil</tt> - Skip validation if attribute is <tt>nil</tt>.
|
234
|
+
</pre>
|
235
|
+
</div>
|
236
|
+
<p>The description starts in upper case and ends with a full stop—it’s standard English.</p>
|
237
|
+
<h3 id="dynamically-generated-methods">8 Dynamically Generated Methods</h3>
|
238
|
+
<p>Methods created with <tt>(module|class)_eval(STRING)</tt> have a comment by their side with an instance of the generated code. That comment is 2 spaces apart from the template:</p>
|
239
|
+
<div class="code_container">
|
240
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
241
|
+
for severity in Severity.constants
|
242
|
+
class_eval <<-EOT, __FILE__, __LINE__
|
243
|
+
def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
|
244
|
+
add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
|
245
|
+
end # end
|
246
|
+
#
|
247
|
+
def #{severity.downcase}? # def debug?
|
248
|
+
#{severity} >= @level # DEBUG >= @level
|
249
|
+
end # end
|
250
|
+
EOT
|
251
|
+
end
|
252
|
+
</pre>
|
253
|
+
</div>
|
254
|
+
<p>If the resulting lines are too wide, say 200 columns or more, we put the comment above the call:</p>
|
255
|
+
<div class="code_container">
|
256
|
+
<pre class="brush: ruby; gutter: false; toolbar: false">
|
257
|
+
# def self.find_by_login_and_activated(*args)
|
258
|
+
# options = args.extract_options!
|
259
|
+
# ...
|
260
|
+
# end
|
261
|
+
self.class_eval %{
|
262
|
+
def self.#{method_id}(*args)
|
263
|
+
options = args.extract_options!
|
264
|
+
...
|
265
|
+
end
|
266
|
+
}
|
267
|
+
</pre>
|
268
|
+
</div>
|
269
|
+
|
270
|
+
<h3>Feedback</h3>
|
271
|
+
<p>
|
272
|
+
You're encouraged to help improve the quality of this guide.
|
273
|
+
</p>
|
274
|
+
<p>
|
275
|
+
If you see any typos or factual errors you are confident to
|
276
|
+
patch, please clone <a href="https://github.com/lifo/docrails">docrails</a>
|
277
|
+
and push the change yourself. That branch of Rails has public write access.
|
278
|
+
Commits are still reviewed, but that happens after you've submitted your
|
279
|
+
contribution. <a href="https://github.com/lifo/docrails">docrails</a> is
|
280
|
+
cross-merged with master periodically.
|
281
|
+
</p>
|
282
|
+
<p>
|
283
|
+
You may also find incomplete content, or stuff that is not up to date.
|
284
|
+
Please do add any missing documentation for master. Check the
|
285
|
+
<a href="ruby_on_rails_guides_guidelines.html">Ruby on Rails Guides Guidelines</a>
|
286
|
+
for style and conventions.
|
287
|
+
</p>
|
288
|
+
<p>
|
289
|
+
If for whatever reason you spot something to fix but cannot patch it yourself, please
|
290
|
+
<a href="https://github.com/rails/rails/issues">open an issue</a>.
|
291
|
+
</p>
|
292
|
+
<p>And last but not least, any kind of discussion regarding Ruby on Rails
|
293
|
+
documentation is very welcome in the <a href="http://groups.google.com/group/rubyonrails-docs">rubyonrails-docs mailing list</a>.
|
294
|
+
</p>
|
295
|
+
</div>
|
296
|
+
</div>
|
297
|
+
</div>
|
298
|
+
|
299
|
+
<hr class="hide" />
|
300
|
+
<div id="footer">
|
301
|
+
<div class="wrapper">
|
302
|
+
<p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0</a> License</p>
|
303
|
+
<p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
|
304
|
+
</div>
|
305
|
+
</div>
|
306
|
+
|
307
|
+
<script type="text/javascript" src="javascripts/guides.js"></script>
|
308
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
|
309
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
|
310
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushXml.js"></script>
|
311
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushSql.js"></script>
|
312
|
+
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
|
313
|
+
<script type="text/javascript">
|
314
|
+
SyntaxHighlighter.all()
|
315
|
+
</script>
|
316
|
+
</body>
|
317
|
+
</html>
|