aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/2_2_release_notes.md2
-rw-r--r--guides/source/2_3_release_notes.md4
-rw-r--r--guides/source/3_0_release_notes.md2
-rw-r--r--guides/source/3_1_release_notes.md6
-rw-r--r--guides/source/3_2_release_notes.md2
-rw-r--r--guides/source/4_0_release_notes.md47
-rw-r--r--guides/source/4_1_release_notes.md20
-rw-r--r--guides/source/4_2_release_notes.md32
-rw-r--r--guides/source/action_controller_overview.md103
-rw-r--r--guides/source/action_mailer_basics.md44
-rw-r--r--guides/source/action_view_overview.md234
-rw-r--r--guides/source/active_job_basics.md39
-rw-r--r--guides/source/active_model_basics.md6
-rw-r--r--guides/source/active_record_basics.md24
-rw-r--r--guides/source/active_record_callbacks.md4
-rw-r--r--guides/source/active_record_migrations.md40
-rw-r--r--guides/source/active_record_postgresql.md74
-rw-r--r--guides/source/active_record_querying.md55
-rw-r--r--guides/source/active_record_validations.md108
-rw-r--r--guides/source/active_support_core_extensions.md172
-rw-r--r--guides/source/active_support_instrumentation.md22
-rw-r--r--guides/source/api_app.md435
-rw-r--r--guides/source/api_documentation_guidelines.md5
-rw-r--r--guides/source/asset_pipeline.md73
-rw-r--r--guides/source/association_basics.md185
-rw-r--r--guides/source/autoloading_and_reloading_constants.md46
-rw-r--r--guides/source/caching_with_rails.md30
-rw-r--r--guides/source/command_line.md32
-rw-r--r--guides/source/configuring.md148
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md100
-rw-r--r--guides/source/debugging_rails_applications.md167
-rw-r--r--guides/source/development_dependencies_install.md6
-rw-r--r--guides/source/documents.yaml12
-rw-r--r--guides/source/engines.md35
-rw-r--r--guides/source/form_helpers.md27
-rw-r--r--guides/source/generators.md2
-rw-r--r--guides/source/getting_started.md106
-rw-r--r--guides/source/i18n.md204
-rw-r--r--guides/source/initialization.md21
-rw-r--r--guides/source/kindle/welcome.html.erb4
-rw-r--r--guides/source/layouts_and_rendering.md126
-rw-r--r--guides/source/maintenance_policy.md2
-rw-r--r--guides/source/nested_model_forms.md4
-rw-r--r--guides/source/plugins.md8
-rw-r--r--guides/source/profiling.md2
-rw-r--r--guides/source/rails_application_templates.md4
-rw-r--r--guides/source/rails_on_rack.md4
-rw-r--r--guides/source/routing.md25
-rw-r--r--guides/source/ruby_on_rails_guides_guidelines.md8
-rw-r--r--guides/source/security.md24
-rw-r--r--guides/source/testing.md316
-rw-r--r--guides/source/upgrading_ruby_on_rails.md59
-rw-r--r--guides/source/working_with_javascript_in_rails.md4
53 files changed, 2100 insertions, 1164 deletions
diff --git a/guides/source/2_2_release_notes.md b/guides/source/2_2_release_notes.md
index 019da08687..be00087f63 100644
--- a/guides/source/2_2_release_notes.md
+++ b/guides/source/2_2_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 2.2 Release Notes
===============================
diff --git a/guides/source/2_3_release_notes.md b/guides/source/2_3_release_notes.md
index 4ac1529e76..0a62f34371 100644
--- a/guides/source/2_3_release_notes.md
+++ b/guides/source/2_3_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 2.3 Release Notes
===============================
@@ -187,7 +187,7 @@ MySQL supports a reconnect flag in its connections - if set to true, then the cl
* Lead Contributor: [Dov Murik](http://twitter.com/dubek)
* More information:
- * [Controlling Automatic Reconnection Behavior](http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html)
+ * [Controlling Automatic Reconnection Behavior](http://dev.mysql.com/doc/refman/5.6/en/auto-reconnect.html)
* [MySQL auto-reconnect revisited](http://groups.google.com/group/rubyonrails-core/browse_thread/thread/49d2a7e9c96cb9f4)
### Other Active Record Changes
diff --git a/guides/source/3_0_release_notes.md b/guides/source/3_0_release_notes.md
index 3d7966e50b..9ad32e8168 100644
--- a/guides/source/3_0_release_notes.md
+++ b/guides/source/3_0_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 3.0 Release Notes
===============================
diff --git a/guides/source/3_1_release_notes.md b/guides/source/3_1_release_notes.md
index 8728750966..d753346fa3 100644
--- a/guides/source/3_1_release_notes.md
+++ b/guides/source/3_1_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 3.1 Release Notes
===============================
@@ -174,7 +174,7 @@ Rails Architectural Changes
The major change in Rails 3.1 is the Assets Pipeline. It makes CSS and JavaScript first-class code citizens and enables proper organization, including use in plugins and engines.
-The assets pipeline is powered by [Sprockets](https://github.com/sstephenson/sprockets) and is covered in the [Asset Pipeline](asset_pipeline.html) guide.
+The assets pipeline is powered by [Sprockets](https://github.com/rails/sprockets) and is covered in the [Asset Pipeline](asset_pipeline.html) guide.
### HTTP Streaming
@@ -199,7 +199,7 @@ Railties
* jQuery is the new default JavaScript library.
-* jQuery and Prototype are no longer vendored and is provided from now on by the jquery-rails and prototype-rails gems.
+* jQuery and Prototype are no longer vendored and is provided from now on by the `jquery-rails` and `prototype-rails` gems.
* The application generator accepts an option `-j` which can be an arbitrary string. If passed "foo", the gem "foo-rails" is added to the `Gemfile`, and the application JavaScript manifest requires "foo" and "foo_ujs". Currently only "prototype-rails" and "jquery-rails" exist and provide those files via the asset pipeline.
diff --git a/guides/source/3_2_release_notes.md b/guides/source/3_2_release_notes.md
index 0b28aac9ce..6ddf77d9c0 100644
--- a/guides/source/3_2_release_notes.md
+++ b/guides/source/3_2_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 3.2 Release Notes
===============================
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index 5f52c33746..9feaff098a 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 4.0 Release Notes
===============================
@@ -59,25 +59,25 @@ Major Features
### Upgrade
- * **Ruby 1.9.3** ([commit](https://github.com/rails/rails/commit/a0380e808d3dbd2462df17f5d3b7fcd8bd812496)) - Ruby 2.0 preferred; 1.9.3+ required
- * **[New deprecation policy](http://www.youtube.com/watch?v=z6YgD6tVPQs)** - Deprecated features are warnings in Rails 4.0 and will be removed in Rails 4.1.
- * **ActionPack page and action caching** ([commit](https://github.com/rails/rails/commit/b0a7068564f0c95e7ef28fc39d0335ed17d93e90)) - Page and action caching are extracted to a separate gem. Page and action caching requires too much manual intervention (manually expiring caches when the underlying model objects are updated). Instead, use Russian doll caching.
- * **ActiveRecord observers** ([commit](https://github.com/rails/rails/commit/ccecab3ba950a288b61a516bf9b6962e384aae0b)) - Observers are extracted to a separate gem. Observers are only needed for page and action caching, and can lead to spaghetti code.
- * **ActiveRecord session store** ([commit](https://github.com/rails/rails/commit/0ffe19056c8e8b2f9ae9d487b896cad2ce9387ad)) - The ActiveRecord session store is extracted to a separate gem. Storing sessions in SQL is costly. Instead, use cookie sessions, memcache sessions, or a custom session store.
- * **ActiveModel mass assignment protection** ([commit](https://github.com/rails/rails/commit/f8c9a4d3e88181cee644f91e1342bfe896ca64c6)) - Rails 3 mass assignment protection is deprecated. Instead, use strong parameters.
- * **ActiveResource** ([commit](https://github.com/rails/rails/commit/f1637bf2bb00490203503fbd943b73406e043d1d)) - ActiveResource is extracted to a separate gem. ActiveResource was not widely used.
- * **vendor/plugins removed** ([commit](https://github.com/rails/rails/commit/853de2bd9ac572735fa6cf59fcf827e485a231c3)) - Use a Gemfile to manage installed gems.
+* **Ruby 1.9.3** ([commit](https://github.com/rails/rails/commit/a0380e808d3dbd2462df17f5d3b7fcd8bd812496)) - Ruby 2.0 preferred; 1.9.3+ required
+* **[New deprecation policy](http://www.youtube.com/watch?v=z6YgD6tVPQs)** - Deprecated features are warnings in Rails 4.0 and will be removed in Rails 4.1.
+* **ActionPack page and action caching** ([commit](https://github.com/rails/rails/commit/b0a7068564f0c95e7ef28fc39d0335ed17d93e90)) - Page and action caching are extracted to a separate gem. Page and action caching requires too much manual intervention (manually expiring caches when the underlying model objects are updated). Instead, use Russian doll caching.
+* **ActiveRecord observers** ([commit](https://github.com/rails/rails/commit/ccecab3ba950a288b61a516bf9b6962e384aae0b)) - Observers are extracted to a separate gem. Observers are only needed for page and action caching, and can lead to spaghetti code.
+* **ActiveRecord session store** ([commit](https://github.com/rails/rails/commit/0ffe19056c8e8b2f9ae9d487b896cad2ce9387ad)) - The ActiveRecord session store is extracted to a separate gem. Storing sessions in SQL is costly. Instead, use cookie sessions, memcache sessions, or a custom session store.
+* **ActiveModel mass assignment protection** ([commit](https://github.com/rails/rails/commit/f8c9a4d3e88181cee644f91e1342bfe896ca64c6)) - Rails 3 mass assignment protection is deprecated. Instead, use strong parameters.
+* **ActiveResource** ([commit](https://github.com/rails/rails/commit/f1637bf2bb00490203503fbd943b73406e043d1d)) - ActiveResource is extracted to a separate gem. ActiveResource was not widely used.
+* **vendor/plugins removed** ([commit](https://github.com/rails/rails/commit/853de2bd9ac572735fa6cf59fcf827e485a231c3)) - Use a Gemfile to manage installed gems.
### ActionPack
- * **Strong parameters** ([commit](https://github.com/rails/rails/commit/a8f6d5c6450a7fe058348a7f10a908352bb6c7fc)) - Only allow whitelisted parameters to update model objects (`params.permit(:title, :text)`).
- * **Routing concerns** ([commit](https://github.com/rails/rails/commit/0dd24728a088fcb4ae616bb5d62734aca5276b1b)) - In the routing DSL, factor out common subroutes (`comments` from `/posts/1/comments` and `/videos/1/comments`).
- * **ActionController::Live** ([commit](https://github.com/rails/rails/commit/af0a9f9eefaee3a8120cfd8d05cbc431af376da3)) - Stream JSON with `response.stream`.
- * **Declarative ETags** ([commit](https://github.com/rails/rails/commit/ed5c938fa36995f06d4917d9543ba78ed506bb8d)) - Add controller-level etag additions that will be part of the action etag computation
- * **[Russian doll caching](http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works)** ([commit](https://github.com/rails/rails/commit/4154bf012d2bec2aae79e4a49aa94a70d3e91d49)) - Cache nested fragments of views. Each fragment expires based on a set of dependencies (a cache key). The cache key is usually a template version number and a model object.
- * **Turbolinks** ([commit](https://github.com/rails/rails/commit/e35d8b18d0649c0ecc58f6b73df6b3c8d0c6bb74)) - Serve only one initial HTML page. When the user navigates to another page, use pushState to update the URL and use AJAX to update the title and body.
- * **Decouple ActionView from ActionController** ([commit](https://github.com/rails/rails/commit/78b0934dd1bb84e8f093fb8ef95ca99b297b51cd)) - ActionView was decoupled from ActionPack and will be moved to a separated gem in Rails 4.1.
- * **Do not depend on ActiveModel** ([commit](https://github.com/rails/rails/commit/166dbaa7526a96fdf046f093f25b0a134b277a68)) - ActionPack no longer depends on ActiveModel.
+* **Strong parameters** ([commit](https://github.com/rails/rails/commit/a8f6d5c6450a7fe058348a7f10a908352bb6c7fc)) - Only allow whitelisted parameters to update model objects (`params.permit(:title, :text)`).
+* **Routing concerns** ([commit](https://github.com/rails/rails/commit/0dd24728a088fcb4ae616bb5d62734aca5276b1b)) - In the routing DSL, factor out common subroutes (`comments` from `/posts/1/comments` and `/videos/1/comments`).
+* **ActionController::Live** ([commit](https://github.com/rails/rails/commit/af0a9f9eefaee3a8120cfd8d05cbc431af376da3)) - Stream JSON with `response.stream`.
+* **Declarative ETags** ([commit](https://github.com/rails/rails/commit/ed5c938fa36995f06d4917d9543ba78ed506bb8d)) - Add controller-level etag additions that will be part of the action etag computation.
+* **[Russian doll caching](http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works)** ([commit](https://github.com/rails/rails/commit/4154bf012d2bec2aae79e4a49aa94a70d3e91d49)) - Cache nested fragments of views. Each fragment expires based on a set of dependencies (a cache key). The cache key is usually a template version number and a model object.
+* **Turbolinks** ([commit](https://github.com/rails/rails/commit/e35d8b18d0649c0ecc58f6b73df6b3c8d0c6bb74)) - Serve only one initial HTML page. When the user navigates to another page, use pushState to update the URL and use AJAX to update the title and body.
+* **Decouple ActionView from ActionController** ([commit](https://github.com/rails/rails/commit/78b0934dd1bb84e8f093fb8ef95ca99b297b51cd)) - ActionView was decoupled from ActionPack and will be moved to a separated gem in Rails 4.1.
+* **Do not depend on ActiveModel** ([commit](https://github.com/rails/rails/commit/166dbaa7526a96fdf046f093f25b0a134b277a68)) - ActionPack no longer depends on ActiveModel.
### General
@@ -87,14 +87,17 @@ Major Features
* **Support for specifying transaction isolation level** ([commit](https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253)) - Choose whether repeatable reads or improved performance (less locking) is more important.
* **Dalli** ([commit](https://github.com/rails/rails/commit/82663306f428a5bbc90c511458432afb26d2f238)) - Use Dalli memcache client for the memcache store.
* **Notifications start & finish** ([commit](https://github.com/rails/rails/commit/f08f8750a512f741acb004d0cebe210c5f949f28)) - Active Support instrumentation reports start and finish notifications to subscribers.
- * **Thread safe by default** ([commit](https://github.com/rails/rails/commit/5d416b907864d99af55ebaa400fff217e17570cd)) - Rails can run in threaded app servers without additional configuration. Note: Check that the gems you are using are threadsafe.
+ * **Thread safe by default** ([commit](https://github.com/rails/rails/commit/5d416b907864d99af55ebaa400fff217e17570cd)) - Rails can run in threaded app servers without additional configuration.
+
+NOTE: Check that the gems you are using are threadsafe.
+
* **PATCH verb** ([commit](https://github.com/rails/rails/commit/eed9f2539e3ab5a68e798802f464b8e4e95e619e)) - In Rails, PATCH replaces PUT. PATCH is used for partial updates of resources.
### Security
- * **match do not catch all** ([commit](https://github.com/rails/rails/commit/90d2802b71a6e89aedfe40564a37bd35f777e541)) - In the routing DSL, match requires the HTTP verb or verbs to be specified.
- * **html entities escaped by default** ([commit](https://github.com/rails/rails/commit/5f189f41258b83d49012ec5a0678d827327e7543)) - Strings rendered in erb are escaped unless wrapped with `raw` or `html_safe` is called.
- * **New security headers** ([commit](https://github.com/rails/rails/commit/6794e92b204572d75a07bd6413bdae6ae22d5a82)) - Rails sends the following headers with every HTTP request: `X-Frame-Options` (prevents clickjacking by forbidding the browser from embedding the page in a frame), `X-XSS-Protection` (asks the browser to halt script injection) and `X-Content-Type-Options` (prevents the browser from opening a jpeg as an exe).
+* **match do not catch all** ([commit](https://github.com/rails/rails/commit/90d2802b71a6e89aedfe40564a37bd35f777e541)) - In the routing DSL, match requires the HTTP verb or verbs to be specified.
+* **html entities escaped by default** ([commit](https://github.com/rails/rails/commit/5f189f41258b83d49012ec5a0678d827327e7543)) - Strings rendered in erb are escaped unless wrapped with `raw` or `html_safe` is called.
+* **New security headers** ([commit](https://github.com/rails/rails/commit/6794e92b204572d75a07bd6413bdae6ae22d5a82)) - Rails sends the following headers with every HTTP request: `X-Frame-Options` (prevents clickjacking by forbidding the browser from embedding the page in a frame), `X-XSS-Protection` (asks the browser to halt script injection) and `X-Content-Type-Options` (prevents the browser from opening a jpeg as an exe).
Extraction of features to gems
---------------------------
@@ -181,7 +184,7 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/4-0-stable/a
* `String#to_date` now raises `ArgumentError: invalid date` instead of `NoMethodError: undefined method 'div' for nil:NilClass`
when given an invalid date. It is now the same as `Date.parse`, and it accepts more invalid dates than 3.x, such as:
- ```
+ ```ruby
# ActiveSupport 3.x
"asdf".to_date # => NoMethodError: undefined method `div' for nil:NilClass
"333".to_date # => NoMethodError: undefined method `div' for nil:NilClass
diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md
index dbc151c0ca..6bf65757ec 100644
--- a/guides/source/4_1_release_notes.md
+++ b/guides/source/4_1_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 4.1 Release Notes
===============================
@@ -317,15 +317,15 @@ for detailed changes.
* Removed deprecated constants from Action Controller:
- | Removed | Successor |
- |:-----------------------------------|:--------------------------------|
- | ActionController::AbstractRequest | ActionDispatch::Request |
- | ActionController::Request | ActionDispatch::Request |
- | ActionController::AbstractResponse | ActionDispatch::Response |
- | ActionController::Response | ActionDispatch::Response |
- | ActionController::Routing | ActionDispatch::Routing |
- | ActionController::Integration | ActionDispatch::Integration |
- | ActionController::IntegrationTest | ActionDispatch::IntegrationTest |
+| Removed | Successor |
+|:-----------------------------------|:--------------------------------|
+| ActionController::AbstractRequest | ActionDispatch::Request |
+| ActionController::Request | ActionDispatch::Request |
+| ActionController::AbstractResponse | ActionDispatch::Response |
+| ActionController::Response | ActionDispatch::Response |
+| ActionController::Routing | ActionDispatch::Routing |
+| ActionController::Integration | ActionDispatch::Integration |
+| ActionController::IntegrationTest | ActionDispatch::IntegrationTest |
### Notable changes
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index faff1add9f..684bd286bc 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails 4.2 Release Notes
===============================
@@ -257,7 +257,7 @@ application is using any of these spellings, you will need to update them:
* Values in attribute selectors may need to be quoted if they contain
non-alphanumeric characters.
- ```
+ ```ruby
# before
a[href=/]
a[href$=/]
@@ -272,7 +272,7 @@ application is using any of these spellings, you will need to update them:
For example:
- ``` ruby
+ ```ruby
# content: <div><i><p></i></div>
# before:
@@ -290,7 +290,7 @@ application is using any of these spellings, you will need to update them:
used to be raw (e.g. `AT&amp;T`), and now is evaluated
(e.g. `AT&T`).
- ``` ruby
+ ```ruby
# content: <p>AT&amp;T</p>
# before:
@@ -302,6 +302,30 @@ application is using any of these spellings, you will need to update them:
assert_select('p', 'AT&amp;T') # => false
```
+Furthermore substitutions have changed syntax.
+
+Now you have to use a `:match` CSS-like selector:
+
+```ruby
+assert_select ":match('id', ?)", 'comment_1'
+```
+
+Additionally Regexp substitutions look different when the assertion fails.
+Notice how `/hello/` here:
+
+```ruby
+assert_select(":match('id', ?)", /hello/)
+```
+
+becomes `"(?-mix:hello)"`:
+
+```
+Expected at least 1 element matching "div:match('id', "(?-mix:hello)")", found 0..
+Expected 0 to be >= 1.
+```
+
+See the [Rails Dom Testing](https://github.com/rails/rails-dom-testing/tree/8798b9349fb9540ad8cb9a0ce6cb88d1384a210b) documentation for more on `assert_select`.
+
Railties
--------
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 36d1b6de83..7d95d4792e 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Action Controller Overview
==========================
@@ -9,7 +9,7 @@ After reading this guide, you will know:
* How to follow the flow of a request through a controller.
* How to restrict parameters passed to your controller.
-* Why and how to store data in the session or cookies.
+* How and why to store data in the session or cookies.
* How to work with filters to execute code during request processing.
* How to use Action Controller's built-in HTTP authentication.
* How to stream data directly to the user's browser.
@@ -21,11 +21,11 @@ After reading this guide, you will know:
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.
+Action Controller is the C in MVC. After routing has determined which controller to use for a request, the 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.
For most conventional [RESTful](http://en.wikipedia.org/wiki/Representational_state_transfer) applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that's not a problem, this is just the most common way for a controller to work.
-A controller can thus be thought of as a middle man between models and views. It makes the model data available to the view so it can display that data to the user, and it saves or updates data from the user to the model.
+A controller can thus be thought of as a middleman between models and views. It makes the model data available to the view so it can display that data to the user, and it saves or updates user data to the model.
NOTE: For more details on the routing process, see [Rails Routing from the Outside In](routing.html).
@@ -34,7 +34,7 @@ Controller Naming Convention
The naming convention of controllers in Rails favors pluralization of the last word in the controller's name, although it is not strictly required (e.g. `ApplicationController`). For example, `ClientsController` is preferable to `ClientController`, `SiteAdminsController` is preferable to `SiteAdminController` or `SitesAdminsController`, and so on.
-Following this convention will allow you to use the default route generators (e.g. `resources`, etc) without needing to qualify each `:path` or `:controller`, and keeps URL and path helpers' usage consistent throughout your application. See [Layouts & Rendering Guide](layouts_and_rendering.html) for more details.
+Following this convention will allow you to use the default route generators (e.g. `resources`, etc) without needing to qualify each `:path` or `:controller`, and will keep URL and path helpers' usage consistent throughout your application. See [Layouts & Rendering Guide](layouts_and_rendering.html) for more details.
NOTE: The controller naming convention differs from the naming convention of models, which are expected to be named in singular form.
@@ -51,7 +51,7 @@ class ClientsController < ApplicationController
end
```
-As an example, if a user goes to `/clients/new` in your application to add a new client, Rails will create an instance of `ClientsController` and run the `new` method. Note that the empty method from the example above would work just fine because Rails will by default render the `new.html.erb` view unless the action says otherwise. The `new` method could make available to the view a `@client` instance variable by creating a new `Client`:
+As an example, if a user goes to `/clients/new` in your application to add a new client, Rails will create an instance of `ClientsController` and call its `new` method. Note that the empty method from the example above would work just fine because Rails will by default render the `new.html.erb` view unless the action says otherwise. The `new` method could make available to the view a `@client` instance variable by creating a new `Client`:
```ruby
def new
@@ -63,7 +63,7 @@ The [Layouts & Rendering Guide](layouts_and_rendering.html) explains this in mor
`ApplicationController` inherits from `ActionController::Base`, which defines a number of helpful methods. This guide will cover some of these, but if you're curious to see what's in there, you can see all of them in the API documentation or in the source itself.
-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.
+Only public methods are callable as actions. It is a best practice to lower the visibility of methods (with `private` or `protected`) which are not intended to be actions, like auxiliary methods or filters.
Parameters
----------
@@ -104,13 +104,13 @@ end
### 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:
+The `params` hash is not limited to one-dimensional keys and values. It can contain nested arrays and hashes. To send an array of values, append an empty pair of square brackets "[]" to the key name:
```
GET /clients?ids[]=1&ids[]=2&ids[]=3
```
-NOTE: The actual URL in this example will be encoded as "/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3" as "[" and "]" are not allowed in URLs. Most of the time you don't have to worry about this because the browser will take care of it for you, and Rails will decode it back when it receives it, but if you ever find yourself having to send those requests to the server manually you have to keep this in mind.
+NOTE: The actual URL in this example will be encoded as "/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3" as the "[" and "]" characters are not allowed in URLs. Most of the time you don't have to worry about this because the browser will encode it for you, and Rails will decode it automatically, but if you ever find yourself having to send those requests to the server manually you should keep this in mind.
The value of `params[:ids]` will now be `["1", "2", "3"]`. Note that parameter values are always strings; Rails makes no attempt to guess or cast the type.
@@ -118,7 +118,7 @@ NOTE: Values such as `[nil]` or `[nil, nil, ...]` in `params` are replaced
with `[]` for security reasons by default. See [Security Guide](security.html#unsafe-query-generation)
for more information.
-To send a hash you include the key name inside the brackets:
+To send a hash, you include the key name inside the brackets:
```html
<form accept-charset="UTF-8" action="/clients" method="post">
@@ -131,11 +131,11 @@ To send a hash you include the key name inside the brackets:
When this form is submitted, the value of `params[:client]` will be `{ "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" } }`. Note the nested hash in `params[:client][:address]`.
-Note that the `params` hash is actually an instance of `ActiveSupport::HashWithIndifferentAccess`, which acts like a hash but lets you use symbols and strings interchangeably as keys.
+The `params` object acts like a Hash, but lets you use symbols and strings interchangeably as keys.
### JSON parameters
-If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. If the "Content-Type" header of your request is set to "application/json", Rails will automatically convert your parameters into the `params` hash, which you can access as you would normally.
+If you're writing a web service application, you might find yourself more comfortable accepting parameters in JSON format. If the "Content-Type" header of your request is set to "application/json", Rails will automatically load your parameters into the `params` hash, which you can access as you would normally.
So for example, if you are sending this JSON content:
@@ -143,15 +143,15 @@ So for example, if you are sending this JSON content:
{ "company": { "name": "acme", "address": "123 Carrot Street" } }
```
-You'll get `params[:company]` as `{ "name" => "acme", "address" => "123 Carrot Street" }`.
+Your controller will receive `params[:company]` as `{ "name" => "acme", "address" => "123 Carrot Street" }`.
-Also, if you've turned on `config.wrap_parameters` in your initializer or calling `wrap_parameters` in your controller, you can safely omit the root element in the JSON parameter. The parameters will be cloned and wrapped in the key according to your controller's name by default. So the above parameter can be written as:
+Also, if you've turned on `config.wrap_parameters` in your initializer or called `wrap_parameters` in your controller, you can safely omit the root element in the JSON parameter. In this case, the parameters will be cloned and wrapped with a key chosen based on your controller's name. So the above JSON POST can be written as:
```json
{ "name": "acme", "address": "123 Carrot Street" }
```
-And assume that you're sending the data to `CompaniesController`, it would then be wrapped in `:company` key like this:
+And, assuming that you're sending the data to `CompaniesController`, it would then be wrapped within the `:company` key like this:
```ruby
{ name: "acme", address: "123 Carrot Street", company: { name: "acme", address: "123 Carrot Street" } }
@@ -159,17 +159,17 @@ 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)
-NOTE: Support for parsing XML parameters has been extracted into a gem named `actionpack-xml_parser`
+NOTE: Support for parsing XML parameters has been extracted into a gem named `actionpack-xml_parser`.
### 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:
+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:
```ruby
get '/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".
+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", as if it were passed in the query string. Your controller will also receive `params[:action]` as "index" and `params[:controller]` as "clients".
### `default_url_options`
@@ -183,21 +183,21 @@ class ApplicationController < ActionController::Base
end
```
-These options will be used as a starting point when generating URLs, so it's possible they'll be overridden by the options passed in `url_for` calls.
+These options will be used as a starting point when generating URLs, so it's possible they'll be overridden by the options passed to `url_for` calls.
-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.
+If you define `default_url_options` in `ApplicationController`, as in the example above, it will be used for all URL generation. The method can also be defined in a specific controller, in which case it only affects URLs generated there.
### Strong Parameters
With strong parameters, Action Controller parameters are forbidden to
be used in Active Model mass assignments until they have been
-whitelisted. This means you'll have to make a conscious choice about
-which attributes to allow for mass updating and thus prevent
-accidentally exposing that which shouldn't be exposed.
+whitelisted. This means that you'll have to make a conscious decision about
+which attributes to allow for mass update. This is a better security
+practice to help prevent accidentally allowing users to update sensitive
+model attributes.
-In addition, parameters can be marked as required and flow through a
-predefined raise/rescue flow to end up as a 400 Bad Request with no
-effort.
+In addition, parameters can be marked as required and will flow through a
+predefined raise/rescue flow to end up as a 400 Bad Request.
```ruby
class PeopleController < ActionController::Base
@@ -239,17 +239,17 @@ params.permit(:id)
```
the key `:id` will pass the whitelisting if it appears in `params` and
-it has a permitted scalar value associated. Otherwise the key is going
+it has a permitted scalar value associated. Otherwise, the key is going
to be filtered out, so arrays, hashes, or any other objects cannot be
injected.
The permitted scalar types are `String`, `Symbol`, `NilClass`,
`Numeric`, `TrueClass`, `FalseClass`, `Date`, `Time`, `DateTime`,
-`StringIO`, `IO`, `ActionDispatch::Http::UploadedFile` and
+`StringIO`, `IO`, `ActionDispatch::Http::UploadedFile`, and
`Rack::Test::UploadedFile`.
To declare that the value in `params` must be an array of permitted
-scalar values map the key to an empty array:
+scalar values, map the key to an empty array:
```ruby
params.permit(id: [])
@@ -262,14 +262,13 @@ used:
params.require(:log_entry).permit!
```
-This will mark the `:log_entry` parameters hash and any sub-hash of it
-permitted. Extreme care should be taken when using `permit!` as it
-will allow all current and future model attributes to be
-mass-assigned.
+This will mark the `:log_entry` parameters hash and any sub-hash of it as
+permitted. Extreme care should be taken when using `permit!`, as it
+will allow all current and future model attributes to be mass-assigned.
#### Nested Parameters
-You can also use permit on nested parameters, like:
+You can also use `permit` on nested parameters, like:
```ruby
params.permit(:name, { emails: [] },
@@ -277,19 +276,19 @@ params.permit(:name, { emails: [] },
{ family: [ :name ], hobbies: [] }])
```
-This declaration whitelists the `name`, `emails` and `friends`
+This declaration whitelists the `name`, `emails`, and `friends`
attributes. It is expected that `emails` will be an array of permitted
-scalar values and that `friends` will be an array of resources with
-specific attributes : they should have a `name` attribute (any
+scalar values, and that `friends` will be an array of resources with
+specific attributes: they should have a `name` attribute (any
permitted scalar values allowed), a `hobbies` attribute as an array of
permitted scalar values, and a `family` attribute which is restricted
-to having a `name` (any permitted scalar values allowed, too).
+to having a `name` (any permitted scalar values allowed here, too).
#### More Examples
-You want to also use the permitted attributes in the `new`
+You may want to also use the permitted attributes in your `new`
action. This raises the problem that you can't use `require` on the
-root key because normally it does not exist when calling `new`:
+root key because, normally, it does not exist when calling `new`:
```ruby
# using `fetch` you can supply a default and use
@@ -297,8 +296,8 @@ root key because normally it does not exist when calling `new`:
params.fetch(:blog, {}).permit(:title, :author)
```
-`accepts_nested_attributes_for` allows you to update and destroy
-associated records. This is based on the `id` and `_destroy`
+The model class method `accepts_nested_attributes_for` allows you to
+update and destroy associated records. This is based on the `id` and `_destroy`
parameters:
```ruby
@@ -306,7 +305,7 @@ parameters:
params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy])
```
-Hashes with integer keys are treated differently and you can declare
+Hashes with integer keys are treated differently, and you can declare
the attributes as if they were direct children. You get these kinds of
parameters when you use `accepts_nested_attributes_for` in combination
with a `has_many` association:
@@ -323,13 +322,13 @@ params.require(:book).permit(:title, chapters_attributes: [:title])
#### Outside the Scope of Strong Parameters
The strong parameter API was designed with the most common use cases
-in mind. It is not meant as a silver bullet to handle all your
-whitelisting problems. However you can easily mix the API with your
+in mind. It is not meant as a silver bullet to handle all of your
+whitelisting problems. However, you can easily mix the API with your
own code to adapt to your situation.
Imagine a scenario where you have parameters representing a product
name and a hash of arbitrary data associated with that product, and
-you want to whitelist the product name attribute but also the whole
+you want to whitelist the product name attribute and also the whole
data hash. The strong parameters API doesn't let you directly
whitelist the whole of a nested hash with any keys, but you can use
the keys of your nested hash to declare what to whitelist:
@@ -668,11 +667,11 @@ You may notice in the above code that we're using `render xml: @users`, not `ren
Filters
-------
-Filters are methods that are run before, after or "around" a controller action.
+Filters are methods that are run "before", "after" or "around" a controller action.
Filters are inherited, so if you set a filter on `ApplicationController`, it will be run on every controller in your application.
-"Before" filters may halt the request cycle. A common "before" filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:
+"before" filters may halt the request cycle. A common "before" filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:
```ruby
class ApplicationController < ActionController::Base
@@ -705,9 +704,9 @@ Now, the `LoginsController`'s `new` and `create` actions will work as before wit
In addition to "before" filters, you can also run filters after an action has been executed, or both before and after.
-"After" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running.
+"after" filters are similar to "before" filters, but because the action has already been run they have access to the response data that's about to be sent to the client. Obviously, "after" filters cannot stop the action from running.
-"Around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
+"around" filters are responsible for running their associated actions by yielding, similar to how Rack middlewares work.
For example, in a website where changes have an approval workflow an administrator could be able to preview them easily, just apply them within a transaction:
@@ -737,7 +736,7 @@ You can choose not to yield and build the response yourself, in which case the a
While the most common way to use filters is by creating private methods and using *_action to add them, there are two other ways to do the same thing.
-The first is to use a block directly with the *_action methods. The block receives the controller as an argument, and the `require_login` filter from above could be rewritten to use a block:
+The first is to use a block directly with the *\_action methods. The block receives the controller as an argument, and the `require_login` filter from above could be rewritten to use a block:
```ruby
class ApplicationController < ActionController::Base
@@ -750,7 +749,7 @@ class ApplicationController < ActionController::Base
end
```
-Note that the filter in this case uses `send` because the `logged_in?` method is private and the filter is not run in the scope of the controller. This is not the recommended way to implement this particular filter, but in more simple cases it might be useful.
+Note that the filter in this case uses `send` because the `logged_in?` method is private and the filter does not run in the scope of the controller. This is not the recommended way to implement this particular filter, but in more simple cases it might be useful.
The second way is to use a class (actually, any object that responds to the right methods will do) to handle the filtering. This is useful in cases that are more complex and cannot be implemented in a readable and reusable way using the two other methods. As an example, you could rewrite the login filter again to use a class:
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index c586675ee5..bf3bf5d19e 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Action Mailer Basics
====================
@@ -344,7 +344,7 @@ The same format can be used to set carbon copy (Cc:) and blind carbon copy
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 `"Full Name <email>"`.
+email address in the format `"Full Name" <email>`.
```ruby
def welcome_email(user)
@@ -442,6 +442,39 @@ end
Will render the HTML part using the `my_layout.html.erb` file and the text part
with the usual `user_mailer.text.erb` file if it exists.
+### Previewing Emails
+
+Action Mailer previews provide a way to see how emails look by visiting a
+special URL that renders them. In the above example, the preview class for
+`UserMailer` should be named `UserMailerPreview` and located in
+`test/mailers/previews/user_mailer_preview.rb`. To see the preview of
+`welcome_email`, implement a method that has the same name and call
+`UserMailer.welcome_email`:
+
+```ruby
+class UserMailerPreview < ActionMailer::Preview
+ def welcome_email
+ UserMailer.welcome_email(User.first)
+ end
+end
+```
+
+Then the preview will be available in <http://localhost:3000/rails/mailers/user_mailer/welcome_email>.
+
+If you change something in `app/views/user_mailer/welcome_email.html.erb`
+or the mailer itself, it'll automatically reload and render it so you can
+visually see the new style instantly. A list of previews are also available
+in <http://localhost:3000/rails/mailers>.
+
+By default, these preview classes live in `test/mailers/previews`.
+This can be configured using the `preview_path` option. For example, if you
+want to change it to `lib/mailer_previews`, you can configure it in
+`config/application.rb`:
+
+```ruby
+config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
+```
+
### Generating URLs in Action Mailer Views
Unlike controllers, the mailer instance doesn't have any context about the
@@ -470,7 +503,7 @@ You will need to use:
By using the full URL, your links will now work in your emails.
-#### generating URLs with `url_for`
+#### Generating URLs with `url_for`
`url_for` generate full URL by default in templates.
@@ -484,7 +517,7 @@ If you did not configure the `:host` option globally make sure to pass it to
action: 'greeting') %>
```
-#### generating URLs with named routes
+#### Generating URLs with Named Routes
Email clients have no web context and so paths have no base URL to form complete
web addresses. Thus, you should always use the "_url" variant of named route
@@ -497,6 +530,9 @@ url helper.
<%= user_url(@user, host: 'example.com') %>
```
+NOTE: non-`GET` links require [jQuery UJS](https://github.com/rails/jquery-ujs)
+and won't work in mailer templates. They will result in normal `GET` requests.
+
### Sending Multipart Emails
Action Mailer will automatically send multipart emails if you have different
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index a6bde4f517..09fac41491 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Action View Overview
====================
@@ -182,7 +182,7 @@ One way to use partials is to treat them as the equivalent of subroutines; a way
<p>Here are a few of our fine products:</p>
<% @products.each do |product| %>
- <%= render partial: "product", locals: {product: product} %>
+ <%= render partial: "product", locals: { product: product } %>
<% end %>
<%= render "shared/footer" %>
@@ -190,6 +190,22 @@ One way to use partials is to treat them as the equivalent of subroutines; a way
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.
+#### `render` without `partial` and `locals` options
+
+In the above example, `render` takes 2 options: `partial` and `locals`. But if
+these are the only options you want to pass, you can skip using these options.
+For example, instead of:
+
+```erb
+<%= render partial: "product", locals: { product: @product } %>
+```
+
+You can also do:
+
+```erb
+<%= render "product", product: @product %>
+```
+
#### The `as` and `object` options
By default `ActionView::Partials::PartialRenderer` has its object in a local variable with the same name as the template. So, given:
@@ -198,10 +214,11 @@ By default `ActionView::Partials::PartialRenderer` has its object in a local var
<%= render partial: "product" %>
```
-within product we'll get `@product` in the local variable `product`, as if we had written:
+within `_product` partial we'll get `@product` in the local variable `product`,
+as if we had written:
```erb
-<%= render partial: "product", locals: {product: @product} %>
+<%= render partial: "product", locals: { product: @product } %>
```
With the `as` option we can specify a different name for the local variable. For example, if we wanted it to be `item` instead of `product` we would do:
@@ -215,7 +232,7 @@ The `object` option can be used to directly specify which object is rendered int
For example, instead of:
```erb
-<%= render partial: "product", locals: {product: @item} %>
+<%= render partial: "product", locals: { product: @item } %>
```
we would do:
@@ -288,7 +305,7 @@ In the `show` template, we'll render the `_article` partial wrapped in the `box`
**articles/show.html.erb**
```erb
-<%= render partial: 'article', layout: 'box', locals: {article: @article} %>
+<%= render partial: 'article', layout: 'box', locals: { article: @article } %>
```
The `box` layout simply wraps the `_article` partial in a `div`:
@@ -301,26 +318,6 @@ The `box` layout simply wraps the `_article` partial in a `div`:
</div>
```
-The `_article` partial wraps the article's `body` in a `div` with the `id` of the article using the `div_for` helper:
-
-**articles/_article.html.erb**
-
-```html+erb
-<%= div_for(article) do %>
- <p><%= article.body %></p>
-<% end %>
-```
-
-this would output the following:
-
-```html
-<div class='box'>
- <div id='article_1'>
- <p>Partial Layouts are cool!</p>
- </div>
-</div>
-```
-
Note that the partial layout has access to the local `article` variable that was passed into the `render` call. However, unlike application-wide layouts, partial layouts still have the underscore prefix.
You can also render a block of code within a partial layout instead of calling `yield`. For example, if we didn't have the `_article` partial, we could do this instead:
@@ -328,10 +325,10 @@ You can also render a block of code within a partial layout instead of calling `
**articles/show.html.erb**
```html+erb
-<% render(layout: 'box', locals: {article: @article}) do %>
- <%= div_for(article) do %>
+<% render(layout: 'box', locals: { article: @article }) do %>
+ <div>
<p><%= article.body %></p>
- <% end %>
+ </div>
<% end %>
```
@@ -340,91 +337,41 @@ Supposing we use the same `_box` partial from above, this would produce the same
View Paths
----------
-TODO...
-
-Overview of helpers provided by Action View
--------------------------------------------
-
-WIP: Not all the helpers are listed here. For a full list see the [API documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html)
-
-The following is only a brief overview summary of the helpers available in Action View. It's recommended that you review the [API Documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html), which covers all of the helpers in more detail, but this should serve as a good starting point.
-
-### RecordTagHelper
+When rendering a response, the controller needs to resolve where the different
+views are located. By default it only looks inside the `app/views` directory.
-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.
+We can add other locations and give them a certain precedence when resolving
+paths using the `prepend_view_path` and `append_view_path` methods.
-#### content_tag_for
+### Prepend view path
-Renders a container tag that relates to your Active Record Object.
+This can be helpful for example, when we want to put views inside a different
+directory for subdomains.
-For example, given `@article` is the object of `Article` class, you can do:
+We can do this by using:
-```html+erb
-<%= content_tag_for(:tr, @article) do %>
- <td><%= @article.title %></td>
-<% end %>
-```
-
-This will generate this HTML output:
-
-```html
-<tr id="article_1234" class="article">
- <td>Hello World!</td>
-</tr>
-```
-
-You can also supply HTML attributes as an additional option hash. For example:
-
-```html+erb
-<%= content_tag_for(:tr, @article, class: "frontpage") do %>
- <td><%= @article.title %></td>
-<% end %>
-```
-
-Will generate this HTML output:
-
-```html
-<tr id="article_1234" class="article frontpage">
- <td>Hello World!</td>
-</tr>
+```ruby
+prepend_view_path "app/views/#{request.subdomain}"
```
-You can pass a collection of Active Record objects. This method will loop through your objects and create a container for each of them. For example, given `@articles` is an array of two `Article` objects:
+Then Action View will look first in this directory when resolving views.
-```html+erb
-<%= content_tag_for(:tr, @articles) do |article| %>
- <td><%= article.title %></td>
-<% end %>
-```
+### Append view path
-Will generate this HTML output:
+Similarly, we can append paths:
-```html
-<tr id="article_1234" class="article">
- <td>Hello World!</td>
-</tr>
-<tr id="article_1235" class="article">
- <td>Ruby on Rails Rocks!</td>
-</tr>
+```ruby
+append_view_path "app/views/direct"
```
-#### div_for
+This will add `app/views/direct` to the end of the lookup paths.
-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:
-
-```html+erb
-<%= div_for(@article, class: "frontpage") do %>
- <td><%= @article.title %></td>
-<% end %>
-```
+Overview of helpers provided by Action View
+-------------------------------------------
-Will generate this HTML output:
+WIP: Not all the helpers are listed here. For a full list see the [API documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html)
-```html
-<div id="article_1234" class="article frontpage">
- <td>Hello World!</td>
-</div>
-```
+The following is only a brief overview summary of the helpers available in Action View. It's recommended that you review the [API Documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html), which covers all of the helpers in more detail, but this should serve as a good starting point.
### AssetTagHelper
@@ -437,39 +384,13 @@ config.action_controller.asset_host = "assets.example.com"
image_tag("rails.png") # => <img src="http://assets.example.com/images/rails.png" alt="Rails" />
```
-#### 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`.
-
-```ruby
-ActionView::Helpers::AssetTagHelper.register_javascript_expansion monkey: ["head", "body", "tail"]
-
-javascript_include_tag :monkey # =>
- <script src="/assets/head.js"></script>
- <script src="/assets/body.js"></script>
- <script src="/assets/tail.js"></script>
-```
-
-#### 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`.
-
-```ruby
-ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion monkey: ["head", "body", "tail"]
-
-stylesheet_link_tag :monkey # =>
- <link href="/assets/head.css" media="screen" rel="stylesheet" />
- <link href="/assets/body.css" media="screen" rel="stylesheet" />
- <link href="/assets/tail.css" media="screen" rel="stylesheet" />
-```
-
#### auto_discovery_link_tag
Returns a link tag that browsers and feed readers can use to auto-detect an RSS or Atom feed.
```ruby
-auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "RSS Feed"}) # =>
- <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed" />
+auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", { title: "RSS Feed" }) # =>
+ <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed.rss" />
```
#### image_path
@@ -553,7 +474,7 @@ Returns a stylesheet link tag for the sources specified as arguments. If you don
stylesheet_link_tag "application" # => <link href="/assets/application.css" media="screen" rel="stylesheet" />
```
-You can also include all styles in the stylesheet directory using :all as the source:
+You can also include all styles in the stylesheet directory using `:all` as the source:
```ruby
stylesheet_link_tag :all
@@ -568,7 +489,7 @@ stylesheet_link_tag :all, cache: true
#### 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.
+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.
```ruby
stylesheet_path "application" # => /assets/application.css
@@ -612,7 +533,7 @@ end
```ruby
atom_feed do |feed|
feed.title("Articles Index")
- feed.updated((@articles.first.created_at))
+ feed.updated(@articles.first.created_at)
@articles.each do |article|
feed.entry(article) do |entry|
@@ -786,7 +707,7 @@ Returns a select tag with options for each of the minutes 0 through 59 with the
```ruby
# Generates a select field for minutes that defaults to the minutes for the time provided.
-select_minute(Time.now + 6.hours)
+select_minute(Time.now + 10.minutes)
```
#### select_month
@@ -850,7 +771,7 @@ time_select("order", "submitted")
Returns a `pre` tag that has object dumped by YAML. This creates a very readable way to inspect an object.
```ruby
-my_hash = {'first' => 1, 'second' => 'two', 'third' => [1,2,3]}
+my_hash = { 'first' => 1, 'second' => 'two', 'third' => [1,2,3] }
debug(my_hash)
```
@@ -869,13 +790,13 @@ third:
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.
-There are two types of form helpers: those that specifically work with model attributes and those that don't. This helper deals with those that work with model attributes; to see an example of form helpers that don't work with model attributes, check the ActionView::Helpers::FormTagHelper documentation.
+There are two types of form helpers: those that specifically work with model attributes and those that don't. This helper deals with those that work with model attributes; to see an example of form helpers that don't work with model attributes, check the `ActionView::Helpers::FormTagHelper` documentation.
-The core method of this helper, form_for, gives you the ability to create a form for a model instance; for example, let's say that you have a model Person and want to create a new instance of it:
+The core method of this helper, `form_for`, gives you the ability to create a form for a model instance; for example, let's say that you have a model Person and want to create a new instance of it:
```html+erb
# Note: a @person variable will have been created in the controller (e.g. @person = Person.new)
-<%= form_for @person, url: {action: "create"} do |f| %>
+<%= form_for @person, url: { action: "create" } do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= submit_tag 'Create' %>
@@ -895,7 +816,7 @@ The HTML generated for this would be:
The params object created when this form is submitted would look like:
```ruby
-{"action" => "create", "controller" => "people", "person" => {"first_name" => "William", "last_name" => "Smith"}}
+{ "action" => "create", "controller" => "people", "person" => { "first_name" => "William", "last_name" => "Smith" } }
```
The params hash has a nested person value, which can therefore be accessed with params[:person] in the controller.
@@ -913,10 +834,10 @@ check_box("article", "validated")
#### 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:
+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:
```html+erb
-<%= form_for @person, url: {action: "update"} do |person_form| %>
+<%= form_for @person, url: { action: "update" } do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
@@ -1051,7 +972,7 @@ end
Sample usage (selecting the associated Author for an instance of Article, `@article`):
```ruby
-collection_select(:article, :author_id, Author.all, :id, :name_with_initial, {prompt: true})
+collection_select(:article, :author_id, Author.all, :id, :name_with_initial, { prompt: true })
```
If `@article.author_id` is 1, this would return:
@@ -1207,7 +1128,7 @@ Returns a string of option tags that have been compiled by iterating over the `c
# options_from_collection_for_select(collection, value_method, text_method, selected = nil)
```
-For example, imagine a loop iterating over each person in @project.people to generate an input tag:
+For example, imagine a loop iterating over each person in `@project.people` to generate an input tag:
```ruby
options_from_collection_for_select(@project.people, "id", "name")
@@ -1223,7 +1144,7 @@ Create a select tag and a series of contained option tags for the provided objec
Example:
```ruby
-select("article", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {include_blank: true})
+select("article", "person_id", Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })
```
If `@article.person_id` is 1, this would become:
@@ -1286,7 +1207,7 @@ Creates a field set for grouping HTML form elements.
Creates a file upload field.
```html+erb
-<%= form_tag({action:"post"}, multipart: true) do %>
+<%= form_tag({ action: "post" }, multipart: true) do %>
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
<%= submit_tag %>
<% end %>
@@ -1422,22 +1343,6 @@ date_field_tag "dob"
Provides functionality for working with JavaScript in your views.
-#### button_to_function
-
-Returns a button that'll trigger a JavaScript function using the onclick handler. Examples:
-
-```ruby
-button_to_function "Greeting", "alert('Hello world!')"
-button_to_function "Delete", "if (confirm('Really?')) do_delete()"
-button_to_function "Details" do |page|
- page[:details].visual_effect :toggle_slide
-end
-```
-
-#### define_javascript_functions
-
-Includes the Action Pack JavaScript libraries inside a single `script` tag.
-
#### escape_javascript
Escape carrier returns and single and double quotes for JavaScript segments.
@@ -1458,15 +1363,6 @@ alert('All is good')
</script>
```
-#### link_to_function
-
-Returns a link that will trigger a JavaScript function using the onclick handler and return false after the fact.
-
-```ruby
-link_to_function "Greeting", "alert('Hello world!')"
-# => <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
-```
-
### NumberHelper
Provides methods for converting numbers into formatted strings. Methods are provided for phone numbers, currency, percentage, precision, positional notation, and file size.
@@ -1533,7 +1429,7 @@ This sanitize helper will HTML encode all tags and strip all attributes that are
sanitize @article.body
```
-If either the :attributes or :tags options are passed, only the mentioned tags and attributes are allowed and nothing else.
+If either the `:attributes` or `:tags` options are passed, only the mentioned tags and attributes are allowed and nothing else.
```ruby
sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style)
@@ -1601,7 +1497,7 @@ details can be found in the [Rails Security Guide](security.html#cross-site-requ
Localized Views
---------------
-Action View has the ability render different templates depending on the current locale.
+Action View has the ability to render different templates depending on the current locale.
For example, suppose you have a `ArticlesController` with a show action. By default, calling this action will render `app/views/articles/show.html.erb`. But if you set `I18n.locale = :de`, then `app/views/articles/show.de.html.erb` will be rendered instead. If the localized template isn't present, the undecorated version will be used. This means you're not required to provide localized views for all cases, but they will be preferred and used if available.
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index 31c9406d5c..29d0c32b09 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Job Basics
=================
@@ -11,7 +11,7 @@ After reading this guide, you will know:
* How to create jobs.
* How to enqueue jobs.
* How to run jobs in the background.
-* How to send emails from your application async.
+* How to send emails from your application asynchronously.
--------------------------------------------------------------------------------
@@ -78,7 +78,8 @@ end
Enqueue a job like so:
```ruby
-# Enqueue a job to be performed as soon the queueing system is free.
+# Enqueue a job to be performed as soon the queueing system is
+# free.
MyJob.perform_later record
```
@@ -114,8 +115,9 @@ You can easily set your queueing backend:
# config/application.rb
module YourApp
class Application < Rails::Application
- # Be sure to have the adapter's gem in your Gemfile and follow
- # the adapter's specific installation and deployment instructions.
+ # Be sure to have the adapter's gem in your Gemfile
+ # and follow the adapter's specific installation
+ # and deployment instructions.
config.active_job.queue_adapter = :sidekiq
end
end
@@ -153,8 +155,8 @@ class GuestsCleanupJob < ActiveJob::Base
end
# Now your job will run on queue production_low_priority on your
-# production environment and on staging_low_priority on your staging
-# environment
+# production environment and on staging_low_priority
+# on your staging environment
```
The default queue name prefix delimiter is '\_'. This can be changed by setting
@@ -176,8 +178,8 @@ class GuestsCleanupJob < ActiveJob::Base
end
# Now your job will run on queue production.low_priority on your
-# production environment and on staging.low_priority on your staging
-# environment
+# production environment and on staging.low_priority
+# on your staging environment
```
If you want more control on what queue a job will be run you can pass a `:queue`
@@ -203,7 +205,7 @@ class ProcessVideoJob < ActiveJob::Base
end
def perform(video)
- # do process video
+ # Do process video
end
end
@@ -236,13 +238,13 @@ class GuestsCleanupJob < ActiveJob::Base
queue_as :default
before_enqueue do |job|
- # do something with the job instance
+ # Do something with the job instance
end
around_perform do |job, block|
- # do something before perform
+ # Do something before perform
block.call
- # do something after perform
+ # Do something after perform
end
def perform
@@ -295,7 +297,7 @@ end
```
This works with any class that mixes in `GlobalID::Identification`, which
-by default has been mixed into Active Model classes.
+by default has been mixed into Active Record classes.
Exceptions
@@ -309,7 +311,7 @@ class GuestsCleanupJob < ActiveJob::Base
queue_as :default
rescue_from(ActiveRecord::RecordNotFound) do |exception|
- # do something with the exception
+ # Do something with the exception
end
def perform
@@ -317,3 +319,10 @@ class GuestsCleanupJob < ActiveJob::Base
end
end
```
+
+
+Job Testing
+--------------
+
+You can find detailed instructions on how to test your jobs in the
+[testing guide](testing.html#testing-jobs).
diff --git a/guides/source/active_model_basics.md b/guides/source/active_model_basics.md
index 8dee1cc5ec..4b2bfaee2f 100644
--- a/guides/source/active_model_basics.md
+++ b/guides/source/active_model_basics.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Model Basics
===================
@@ -396,7 +396,7 @@ class Person
end
```
-With the `to_xml` you have a XML representing the model.
+With the `to_xml` you have an XML representing the model.
```ruby
person = Person.new
@@ -405,7 +405,7 @@ person.name = "Bob"
person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<person>\n <name>Bob</name>\n</person>\n"
```
-From a XML string you define the attributes of the model.
+From an XML string you define the attributes of the model.
You need to have the `attributes=` method defined on your class:
```ruby
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index 9d2ba328ea..a227b54040 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record Basics
====================
@@ -20,7 +20,7 @@ After reading this guide, you will know:
What is Active Record?
----------------------
-Active Record is the M in [MVC](getting_started.html#the-mvc-architecture) - the
+Active Record is the M in [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) - 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
@@ -38,7 +38,7 @@ object on how to write to and read from the database.
### Object Relational Mapping
-Object-Relational Mapping, commonly referred to as its abbreviation ORM, is
+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
@@ -62,7 +62,7 @@ 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
+Rails, you'll need to write very little configuration (in some cases 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 time then this
should be the default way. Thus, explicit configuration would be needed
@@ -74,8 +74,8 @@ 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
+pluralization mechanisms are very powerful, being capable of pluralizing (and
+singularizing) 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:
@@ -122,7 +122,7 @@ to Active Record instances:
* `(association_name)_type` - Stores the type for
[polymorphic associations](association_basics.html#polymorphic-associations).
* `(table_name)_count` - Used to cache the number of belonging objects on
- associations. For example, a `comments_count` column in a `Articles` class that
+ associations. For example, a `comments_count` column in an `Article` class that
has many instances of `Comment` will cache the number of existent comments
for each article.
@@ -173,18 +173,18 @@ name that should be used:
```ruby
class Product < ActiveRecord::Base
- self.table_name = "PRODUCT"
+ self.table_name = "my_products"
end
```
If you do so, you will have to define manually the class name that is hosting
-the fixtures (class_name.yml) using the `set_fixture_class` method in your test
+the fixtures (my_products.yml) using the `set_fixture_class` method in your test
definition:
```ruby
-class FunnyJoke < ActiveSupport::TestCase
- set_fixture_class funny_jokes: Joke
- fixtures :funny_jokes
+class ProductTest < ActiveSupport::TestCase
+ set_fixture_class my_products: Product
+ fixtures :my_products
...
end
```
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
index 9d3a8c3af6..13989a3b33 100644
--- a/guides/source/active_record_callbacks.md
+++ b/guides/source/active_record_callbacks.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record Callbacks
=======================
@@ -68,7 +68,7 @@ class User < ActiveRecord::Base
protected
def normalize_name
- self.name = self.name.downcase.titleize
+ self.name = name.downcase.titleize
end
def set_location
diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md
index 8ae282bad2..ad069a112e 100644
--- a/guides/source/active_record_migrations.md
+++ b/guides/source/active_record_migrations.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record Migrations
========================
@@ -241,7 +241,7 @@ generates
```ruby
class AddUserRefToProducts < ActiveRecord::Migration
def change
- add_reference :products, :user, index: true
+ add_reference :products, :user, index: true, foreign_key: true
end
end
```
@@ -357,7 +357,7 @@ will append `ENGINE=BLACKHOLE` to the SQL statement used to create the table
### Creating a Join Table
-Migration method `create_join_table` creates a HABTM join table. A typical use
+Migration method `create_join_table` creates an HABTM join table. A typical use
would be:
```ruby
@@ -425,7 +425,7 @@ change_column :products, :part_number, :text
This changes the column `part_number` on products table to be a `:text` field.
Besides `change_column`, the `change_column_null` and `change_column_default`
-methods are used specifically to change the null and default values of a
+methods are used specifically to change a not null constraint and default values of a
column.
```ruby
@@ -475,11 +475,13 @@ column names can not be derived from the table names, you can use the
`:column` and `:primary_key` options.
Rails will generate a name for every foreign key starting with
-`fk_rails_` followed by 10 random characters.
+`fk_rails_` followed by 10 character which is deterministically
+generated from the `from_table` and `column`.
There is a `:name` option to specify a different name if needed.
NOTE: Active Record only supports single column foreign keys. `execute` and
-`structure.sql` are required to use composite foreign keys.
+`structure.sql` are required to use composite foreign keys. See
+[Schema Dumping and You](#schema-dumping-and-you).
Removing a foreign key is easy as well:
@@ -500,7 +502,7 @@ If the helpers provided by Active Record aren't enough you can use the `execute`
method to execute arbitrary SQL:
```ruby
-Product.connection.execute('UPDATE `products` SET `price`=`free` WHERE 1')
+Product.connection.execute("UPDATE products SET price = 'free' WHERE 1=1")
```
For more details and examples of individual methods, check the API documentation.
@@ -538,6 +540,14 @@ definitions:
`change_table` is also reversible, as long as the block does not call `change`,
`change_default` or `remove`.
+`remove_column` is reversible if you supply the column type as the third
+argument. Provide the original column options too, otherwise Rails can't
+recreate the column exactly when rolling back:
+
+```ruby
+remove_column :posts, :slug, :string, null: false, default: '', index: true
+```
+
If you're going to need to use any other methods, you should use `reversible`
or write the `up` and `down` methods instead of using the `change` method.
@@ -545,7 +555,7 @@ or write the `up` and `down` methods instead of using the `change` method.
Complex migrations may require processing that Active Record doesn't know how
to reverse. You can use `reversible` to specify what to do when running a
-migration what else to do when reverting it. For example:
+migration and what else to do when reverting it. For example:
```ruby
class ExampleMigration < ActiveRecord::Migration
@@ -597,7 +607,7 @@ schema, and 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 do an `up` followed by a `down`. For example, if you
create a table in the `up` method, you should drop it in the `down` method. It
-is wise to reverse the transformations in precisely the reverse order they were
+is wise to perform the transformations in precisely the reverse order they were
made in the `up` method. The example in the `reversible` section is equivalent to:
```ruby
@@ -695,6 +705,10 @@ of `create_table` and `reversible`, replacing `create_table`
by `drop_table`, and finally replacing `up` by `down` and vice-versa.
This is all taken care of by `revert`.
+NOTE: If you want to add check constraints like in the examples above,
+you will have to use `structure.sql` as dump method. See
+[Schema Dumping and You](#schema-dumping-and-you).
+
Running Migrations
------------------
@@ -943,10 +957,10 @@ that Active Record supports. This could be very useful if you were to
distribute an application that is able to run against multiple databases.
There is however a trade-off: `db/schema.rb` cannot express database specific
-items such as triggers, or stored procedures. While in a migration you can
-execute custom SQL statements, the schema dumper cannot reconstitute those
-statements from the database. If you are using features like this, then you
-should set the schema format to `:sql`.
+items such as triggers, stored procedures or check constraints. While in a
+migration you can execute custom SQL statements, the schema dumper cannot
+reconstitute those statements from the database. If you are using features like
+this, then you should set the schema format to `:sql`.
Instead of using Active Record's schema dumper, the database's structure will
be dumped using a tool specific to the database (via the `db:structure:dump`
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index fa0f31cbbd..dcc523eb0f 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record and PostgreSQL
============================
@@ -29,8 +29,8 @@ that are supported by the PostgreSQL adapter.
### Bytea
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-binary.html)
-* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-binarystring.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-binary.html)
+* [functions and operators](http://www.postgresql.org/docs/current/static/functions-binarystring.html)
```ruby
# db/migrate/20140207133952_create_documents.rb
@@ -49,8 +49,8 @@ Document.create payload: data
### Array
-* [type definition](http://www.postgresql.org/docs/9.3/static/arrays.html)
-* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-array.html)
+* [type definition](http://www.postgresql.org/docs/current/static/arrays.html)
+* [functions and operators](http://www.postgresql.org/docs/current/static/functions-array.html)
```ruby
# db/migrate/20140207133952_create_books.rb
@@ -83,7 +83,7 @@ Book.where("array_length(ratings, 1) >= 3")
### Hstore
-* [type definition](http://www.postgresql.org/docs/9.3/static/hstore.html)
+* [type definition](http://www.postgresql.org/docs/current/static/hstore.html)
NOTE: you need to enable the `hstore` extension to use hstore.
@@ -112,8 +112,8 @@ profile.save!
### JSON
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-json.html)
-* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-json.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-json.html)
+* [functions and operators](http://www.postgresql.org/docs/current/static/functions-json.html)
```ruby
# db/migrate/20131220144913_create_events.rb
@@ -138,10 +138,10 @@ Event.where("payload->>'kind' = ?", "user_renamed")
### Range Types
-* [type definition](http://www.postgresql.org/docs/9.3/static/rangetypes.html)
-* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-range.html)
+* [type definition](http://www.postgresql.org/docs/current/static/rangetypes.html)
+* [functions and operators](http://www.postgresql.org/docs/current/static/functions-range.html)
-This type is mapped to Ruby [`Range`](http://www.ruby-doc.org/core-2.1.1/Range.html) objects.
+This type is mapped to Ruby [`Range`](http://www.ruby-doc.org/core-2.2.2/Range.html) objects.
```ruby
# db/migrate/20130923065404_create_events.rb
@@ -173,7 +173,7 @@ event.ends_at # => Thu, 13 Feb 2014
### Composite Types
-* [type definition](http://www.postgresql.org/docs/9.3/static/rowtypes.html)
+* [type definition](http://www.postgresql.org/docs/current/static/rowtypes.html)
Currently there is no special support for composite types. They are mapped to
normal text columns:
@@ -213,7 +213,7 @@ contact.save!
### Enumerated Types
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-enum.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-enum.html)
Currently there is no special support for enumerated types. They are mapped as
normal text columns:
@@ -242,9 +242,12 @@ article.save!
### UUID
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-uuid.html)
-* [generator functions](http://www.postgresql.org/docs/9.3/static/uuid-ossp.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-uuid.html)
+* [pgcrypto generator function](http://www.postgresql.org/docs/current/static/pgcrypto.html#AEN159361)
+* [uuid-ossp generator functions](http://www.postgresql.org/docs/current/static/uuid-ossp.html)
+NOTE: you need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
+extension to use uuid.
```ruby
# db/migrate/20131220144913_create_revisions.rb
@@ -263,10 +266,32 @@ revision = Revision.first
revision.identifier # => "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
```
+You can use `uuid` type to define references in migrations
+
+```ruby
+# db/migrate/20150418012400_create_blog.rb
+create_table :posts, id: :uuid
+
+create_table :comments, id: :uuid do |t|
+ # t.belongs_to :post, type: :uuid
+ t.references :post, type: :uuid
+end
+
+# app/models/post.rb
+class Post < ActiveRecord::Base
+ has_many :comments
+end
+
+# app/models/comment.rb
+class Comment < ActiveRecord::Base
+ belongs_to :post
+end
+```
+
### Bit String Types
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-bit.html)
-* [functions and operators](http://www.postgresql.org/docs/9.3/static/functions-bitstring.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-bit.html)
+* [functions and operators](http://www.postgresql.org/docs/current/static/functions-bitstring.html)
```ruby
# db/migrate/20131220144913_create_users.rb
@@ -289,10 +314,10 @@ user.save!
### Network Address Types
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-net-types.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-net-types.html)
The types `inet` and `cidr` are mapped to Ruby
-[`IPAddr`](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/ipaddr/rdoc/IPAddr.html)
+[`IPAddr`](http://www.ruby-doc.org/stdlib-2.2.2/libdoc/ipaddr/rdoc/IPAddr.html)
objects. The `macaddr` type is mapped to normal text.
```ruby
@@ -324,7 +349,7 @@ macbook.address
### Geometric Types
-* [type definition](http://www.postgresql.org/docs/9.3/static/datatype-geometric.html)
+* [type definition](http://www.postgresql.org/docs/current/static/datatype-geometric.html)
All geometric types, with the exception of `points` are mapped to normal text.
A point is casted to an array containing `x` and `y` coordinates.
@@ -333,12 +358,13 @@ A point is casted to an array containing `x` and `y` coordinates.
UUID Primary Keys
-----------------
-NOTE: you need to enable the `uuid-ossp` extension to generate UUIDs.
+NOTE: you need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
+extension to generate random UUIDs.
```ruby
# db/migrate/20131220144913_create_devices.rb
-enable_extension 'uuid-ossp' unless extension_enabled?('uuid-ossp')
-create_table :devices, id: :uuid, default: 'uuid_generate_v4()' do |t|
+enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
+create_table :devices, id: :uuid, default: 'gen_random_uuid()' do |t|
t.string :kind
end
@@ -378,7 +404,7 @@ Document.where("to_tsvector('english', title || ' ' || body) @@ to_tsquery(?)",
Database Views
--------------
-* [view creation](http://www.postgresql.org/docs/9.3/static/sql-createview.html)
+* [view creation](http://www.postgresql.org/docs/current/static/sql-createview.html)
Imagine you need to work with a legacy database containing the following table:
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index f8c64cbd0c..e3cfabb327 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record Query Interface
=============================
@@ -257,6 +257,12 @@ It is equivalent to writing:
Client.where(first_name: 'Lifo').take
```
+The SQL equivalent of the above is:
+
+```sql
+SELECT * FROM clients WHERE (clients.first_name = 'Lifo') LIMIT 1
+```
+
The `find_by!` method behaves exactly like `find_by`, except that it will raise `ActiveRecord::RecordNotFound` if no matching record is found. For example:
```ruby
@@ -311,7 +317,7 @@ end
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`.
-Two additional options, `:batch_size` and `:start`, are available as well.
+Three additional options, `:batch_size`, `:begin_at` and `:end_at`, are available as well.
**`:batch_size`**
@@ -323,19 +329,32 @@ User.find_each(batch_size: 5000) do |user|
end
```
-**`:start`**
+**`:begin_at`**
-By default, records are fetched in ascending order of the primary key, which must be an integer. The `:start` option allows you to configure the first ID of the sequence whenever the lowest ID is not the one you need. This would be useful, for example, if you wanted to resume an interrupted batch process, provided you saved the last processed ID as a checkpoint.
+By default, records are fetched in ascending order of the primary key, which must be an integer. The `:begin_at` option allows you to configure the first ID of the sequence whenever the lowest ID is not the one you need. This would be useful, for example, if you wanted to resume an interrupted batch process, provided you saved the last processed ID as a checkpoint.
For example, to send newsletters only to users with the primary key starting from 2000, and to retrieve them in batches of 5000:
```ruby
-User.find_each(start: 2000, batch_size: 5000) do |user|
+User.find_each(begin_at: 2000, batch_size: 5000) do |user|
NewsMailer.weekly(user).deliver_now
end
```
-Another example would be if you wanted multiple workers handling the same processing queue. You could have each worker handle 10000 records by setting the appropriate `:start` option on each worker.
+Another example would be if you wanted multiple workers handling the same processing queue. You could have each worker handle 10000 records by setting the appropriate `:begin_at` option on each worker.
+
+**`:end_at`**
+
+Similar to the `:begin_at` option, `:end_at` allows you to configure the last ID of the sequence whenever the highest ID is not the one you need.
+This would be useful, for example, if you wanted to run a batch process, using a subset of records based on `:begin_at` and `:end_at`
+
+For example, to send newsletters only to users with the primary key starting from 2000 up to 10000 and to retrieve them in batches of 5000:
+
+```ruby
+User.find_each(begin_at: 2000, end_at: 10000, batch_size: 5000) do |user|
+ NewsMailer.weekly(user).deliver_now
+end
+```
#### `find_in_batches`
@@ -350,7 +369,7 @@ end
##### Options for `find_in_batches`
-The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`.
+The `find_in_batches` method accepts the same `:batch_size`, `:begin_at` and `:end_at` options as `find_each`.
Conditions
----------
@@ -510,7 +529,7 @@ Client.order("orders_count ASC, created_at DESC")
Client.order("orders_count ASC", "created_at DESC")
```
-If you want to call `order` multiple times e.g. in different context, new order will append previous one
+If you want to call `order` multiple times e.g. in different context, new order will append previous one:
```ruby
Client.order("orders_count ASC").order("created_at DESC")
@@ -636,7 +655,7 @@ GROUP BY status
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.
+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` method to the find.
For example:
@@ -879,7 +898,7 @@ For example:
Item.transaction do
i = Item.lock.first
i.name = 'Jones'
- i.save
+ i.save!
end
```
@@ -1128,7 +1147,7 @@ This would generate a query which contains a `LEFT OUTER JOIN` whereas the
If there was no `where` condition, this would generate the normal set of two queries.
NOTE: Using `where` like this will only work when you pass it a Hash. For
-SQL-fragments you need use `references` to force joined tables:
+SQL-fragments you need to use `references` to force joined tables:
```ruby
Article.includes(:comments).where("comments.visible = true").references(:comments)
@@ -1269,7 +1288,7 @@ User.active.where(state: 'finished')
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'finished'
```
-If we do want the `last where clause` to win then `Relation#merge` can
+If we do want the last `where` clause to win then `Relation#merge` can
be used.
```ruby
@@ -1324,7 +1343,7 @@ Client.unscoped {
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` for free from Active Record. If you have a `locked` field on the `Client` model, you also get `find_by_locked` and methods.
+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` for free from Active Record. If you have a `locked` field on the `Client` model, you also get `find_by_locked` method.
You can specify an exclamation point (`!`) on the end of the dynamic finders to get them to raise an `ActiveRecord::RecordNotFound` error if they do not return any records, like `Client.find_by_name!("Ryan")`
@@ -1384,8 +1403,9 @@ WHERE people.name = 'John'
LIMIT 1
```
-NOTE: Remember that, if `find_by` returns more than one registry, it will take
-just the first and ignore the others. Note the `LIMIT 1` statement above.
+NOTE: Note that if a query matches multiple records, `find_by` will
+fetch only the first one and ignore the others (see the `LIMIT 1`
+statement above).
Find or Build a New Object
--------------------------
@@ -1767,8 +1787,9 @@ EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `articles` ON `articles`.`
under MySQL.
-Active Record performs a pretty printing that emulates the one of the database
-shells. So, the same query running with the PostgreSQL adapter would yield instead
+Active Record performs a pretty printing that emulates that of the
+corresponding database shell. So, the same query running with the
+PostgreSQL adapter would yield instead
```
EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "articles" ON "articles"."user_id" = "users"."id" WHERE "users"."id" = 1
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
index 8c832bafff..7932853c11 100644
--- a/guides/source/active_record_validations.md
+++ b/guides/source/active_record_validations.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record Validations
=========================
@@ -47,7 +47,7 @@ built-in helpers for common needs, and allows you to create your own validation
methods as well.
There are several other ways to validate data before it is saved into your
-database, including native database constraints, client-side validations,
+database, including native database constraints, client-side validations and
controller-level validations. Here's a summary of the pros and cons:
* Database constraints and/or stored procedures make the validation mechanisms
@@ -122,7 +122,7 @@ database only if the object is valid:
* `update!`
The bang versions (e.g. `save!`) raise an exception if the record is invalid.
-The non-bang versions don't, `save` and `update` return `false`,
+The non-bang versions don't: `save` and `update` return `false`, and
`create` just returns the object.
### Skipping Validations
@@ -143,7 +143,7 @@ database regardless of its validity. They should be used with caution.
* `update_counters`
Note that `save` also has the ability to skip validations if passed `validate:
-false` as argument. This technique should be used with caution.
+false` as an argument. This technique should be used with caution.
* `save(validate: false)`
@@ -227,8 +227,26 @@ 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.
+Errors](#working-with-validation-errors) section.
+
+### `errors.details`
+
+To check which validations failed on an invalid attribute, you can use
+`errors.details[:attribute]`. It returns an array of hashes with an `:error`
+key to get the symbol of the validator:
+
+```ruby
+class Person < ActiveRecord::Base
+ validates :name, presence: true
+end
+
+>> person = Person.new
+>> person.valid?
+>> person.errors.details[:name] #=> [{error: :blank}]
+```
+
+Using `details` with custom validators is covered in the [Working with
+Validation Errors](#working-with-validation-errors) section.
Validation Helpers
------------------
@@ -254,7 +272,7 @@ available helpers.
This method 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
+application's terms of service, confirm that some text is read, 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).
@@ -265,6 +283,7 @@ class Person < ActiveRecord::Base
end
```
+This check is performed only if `terms_of_service` is not `nil`.
The default error message for this helper is _"must be accepted"_.
It can receive an `:accept` option, which determines the value that will be
@@ -320,7 +339,7 @@ In your view template you could use something like
This check is performed only if `email_confirmation` is not `nil`. To require
confirmation, make sure to add a presence check for the confirmation attribute
-(we'll take a look at `presence` later on this guide):
+(we'll take a look at `presence` later on in this guide):
```ruby
class Person < ActiveRecord::Base
@@ -452,7 +471,7 @@ point number. To specify that only integral numbers are allowed set
If you set `:only_integer` to `true`, then it will use the
```ruby
-/\A[+-]?\d+\Z/
+/\A[+-]?\d+\z/
```
regular expression to validate the attribute's value. Otherwise, it will try to
@@ -481,9 +500,9 @@ constraints to acceptable values:
default error message for this option is _"must be equal to %{count}"_.
* `:less_than` - Specifies the value must be less than the supplied value. The
default error message for this option is _"must be less than %{count}"_.
-* `:less_than_or_equal_to` - Specifies the value must be less than or equal the
- supplied value. The default error message for this option is _"must be less
- than or equal to %{count}"_.
+* `:less_than_or_equal_to` - Specifies the value must be less than or equal to
+ the supplied value. The default error message for this option is _"must be
+ less than or equal to %{count}"_.
* `:odd` - Specifies the value must be an odd number if set to true. The
default error message for this option is _"must be odd"_.
* `:even` - Specifies the value must be an even number if set to true. The
@@ -533,7 +552,6 @@ Since `false.blank?` is true, if you want to validate the presence of a boolean
field you should use one of the following validations:
```ruby
-validates :boolean_field_name, presence: true
validates :boolean_field_name, inclusion: { in: [true, false] }
validates :boolean_field_name, exclusion: { in: [nil] }
```
@@ -588,9 +606,7 @@ 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 on both columns in your database. See
-[the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/multiple-column-indexes.html)
-for more details about multiple column indexes.
+you must create a unique index on that column in your database.
```ruby
class Account < ActiveRecord::Base
@@ -601,7 +617,7 @@ end
The validation happens by performing an SQL query into the model's table,
searching for an existing record with the same value in that attribute.
-There is a `:scope` option that you can use to specify other attributes that
+There is a `:scope` option that you can use to specify one or more attributes that
are used to limit the uniqueness check:
```ruby
@@ -610,6 +626,7 @@ class Holiday < ActiveRecord::Base
message: "should happen once per year" }
end
```
+Should you wish to create a database constraint to prevent possible violations of a uniqueness validation using the `:scope` option, you must create a unique index on both columns in your database. See [the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/multiple-column-indexes.html) for more details about multiple column indexes or [the PostgreSQL manual](http://www.postgresql.org/docs/current/static/ddl-constraints.html) for examples of unique constraints that refer to a group of columns.
There is also a `:case_sensitive` option that you can use to define whether the
uniqueness constraint will be case sensitive or not. This option defaults to
@@ -796,7 +813,7 @@ end
Person.new.valid? # => ActiveModel::StrictValidationFailed: Name can't be blank
```
-There is also an ability to pass custom exception to `:strict` option.
+There is also the ability to pass a custom exception to the `:strict` option.
```ruby
class Person < ActiveRecord::Base
@@ -860,7 +877,7 @@ end
### Grouping Conditional validations
-Sometimes it is useful to have multiple validations use one condition, it can
+Sometimes it is useful to have multiple validations use one condition. It can
be easily achieved using `with_options`.
```ruby
@@ -872,8 +889,8 @@ class User < ActiveRecord::Base
end
```
-All validations inside of `with_options` block will have automatically passed
-the condition `if: :is_admin?`
+All validations inside of the `with_options` block will have automatically
+passed the condition `if: :is_admin?`
### Combining Validation Conditions
@@ -900,8 +917,8 @@ write your own validators or validation methods as you prefer.
### Custom Validators
-Custom validators are classes that extend `ActiveModel::Validator`. These
-classes must implement a `validate` method which takes a record as an argument
+Custom validators are classes that inherit from `ActiveModel::Validator`. These
+classes must implement the `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.
@@ -1038,7 +1055,9 @@ person.errors[:name]
### `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.
+The `add` method lets you add an error message related to a particular attribute. It takes as arguments the attribute and the error message.
+
+The `errors.full_messages` method (or its equivalent, `errors.to_a`) returns the error messages in a user-friendly format, with the capitalized attribute name prepended to each message, as shown in the examples below.
```ruby
class Person < ActiveRecord::Base
@@ -1056,12 +1075,12 @@ person.errors.full_messages
# => ["Name cannot contain the characters !@#%*()_-+="]
```
-Another way to do this is using `[]=` setter
+An equivalent to `errors#add` is to use `<<` to append a message to the `errors.messages` array for an attribute:
```ruby
class Person < ActiveRecord::Base
def a_method_used_for_validation_purposes
- errors[:name] = "cannot contain the characters !@#%*()_-+="
+ errors.messages[:name] << "cannot contain the characters !@#%*()_-+="
end
end
@@ -1074,6 +1093,43 @@ Another way to do this is using `[]=` setter
# => ["Name cannot contain the characters !@#%*()_-+="]
```
+### `errors.details`
+
+You can specify a validator type to the returned error details hash using the
+`errors.add` method.
+
+```ruby
+class Person < ActiveRecord::Base
+ def a_method_used_for_validation_purposes
+ errors.add(:name, :invalid_characters)
+ end
+end
+
+person = Person.create(name: "!@#")
+
+person.errors.details[:name]
+# => [{error: :invalid_characters}]
+```
+
+To improve the error details to contain the unallowed characters set for instance,
+you can pass additional keys to `errors.add`.
+
+```ruby
+class Person < ActiveRecord::Base
+ def a_method_used_for_validation_purposes
+ errors.add(:name, :invalid_characters, not_allowed: "!@#%*()_-+=")
+ end
+end
+
+person = Person.create(name: "!@#")
+
+person.errors.details[:name]
+# => [{error: :invalid_characters, not_allowed: "!@#%*()_-+="}]
+```
+
+All built in Rails validators populate the details hash with the corresponding
+validator type.
+
### `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.
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index ba839e1723..01bf928407 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Support Core Extensions
==============================
@@ -349,7 +349,7 @@ end
we get:
```ruby
-current_user.to_query('user') # => user=357-john-smith
+current_user.to_query('user') # => "user=357-john-smith"
```
This method escapes whatever is needed, both for the key and the value:
@@ -467,7 +467,7 @@ C.new(0, 1).instance_variable_names # => ["@x", "@y"]
NOTE: Defined in `active_support/core_ext/object/instance_variables.rb`.
-### Silencing Warnings, Streams, and Exceptions
+### Silencing Warnings 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:
@@ -475,26 +475,10 @@ The methods `silence_warnings` and `enable_warnings` change the value of `$VERBO
silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
```
-You can silence any stream while a block runs with `silence_stream`:
+Silencing exceptions is also possible with `suppress`. This method receives an arbitrary number of exception classes. If an exception is raised during the execution of the block and is `kind_of?` any of the arguments, `suppress` captures it and returns silently. Otherwise the exception is not captured:
```ruby
-silence_stream(STDOUT) do
- # STDOUT is silent here
-end
-```
-
-The `quietly` method addresses the common use case where you want to silence STDOUT and STDERR, even in subprocesses:
-
-```ruby
-quietly { system 'bundle install' }
-```
-
-For example, the railties test suite uses that one in a few places to prevent command messages from being echoed intermixed with the progress status.
-
-Silencing exceptions is also possible with `suppress`. This method receives an arbitrary number of exception classes. If an exception is raised during the execution of the block and is `kind_of?` any of the arguments, `suppress` captures it and returns silently. Otherwise the exception is reraised:
-
-```ruby
-# If the user is locked the increment is lost, no big deal.
+# If the user is locked, the increment is lost, no big deal.
suppress(ActiveRecord::StaleObjectError) do
current_user.increment! :visits
end
@@ -522,6 +506,8 @@ Extensions to `Module`
### `alias_method_chain`
+**This method is deprecated in favour of using Module#prepend.**
+
Using plain Ruby you can wrap methods with other methods, that's called _alias chaining_.
For example, let's say you'd like params to be strings in functional tests, as they are in real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap `ActionController::TestCase#process` this way in `test/test_helper.rb`:
@@ -566,8 +552,6 @@ ActionController::TestCase.class_eval do
end
```
-Rails uses `alias_method_chain` all over the code base. For example validations are added to `ActiveRecord::Base#save` by wrapping the method that way in a separate module specialized in validations.
-
NOTE: Defined in `active_support/core_ext/module/aliasing.rb`.
### Attributes
@@ -743,7 +727,7 @@ NOTE: Defined in `active_support/core_ext/module/introspection.rb`.
#### Qualified Constant Names
-The standard methods `const_defined?`, `const_get` , and `const_set` accept
+The standard methods `const_defined?`, `const_get`, and `const_set` accept
bare constant names. Active Support extends this API to be able to pass
relative qualified constant names.
@@ -1253,7 +1237,7 @@ Calling `dup` or `clone` on safe strings yields safe strings.
The method `remove` will remove all occurrences of the pattern:
```ruby
-"Hello World".remove(/Hello /) => "World"
+"Hello World".remove(/Hello /) # => "World"
```
There's also the destructive version `String#remove!`.
@@ -1952,6 +1936,8 @@ as well as adding or subtracting their results from a Time object. For example:
(4.months + 5.years).from_now
```
+NOTE: Defined in `active_support/core_ext/numeric/time.rb`
+
### Formatting
Enables the formatting of numbers in a variety of ways.
@@ -2198,6 +2184,27 @@ to_visit << node if visited.exclude?(node)
NOTE: Defined in `active_support/core_ext/enumerable.rb`.
+### `without`
+
+The method `without` returns a copy of an enumerable with the specified elements
+removed:
+
+```ruby
+["David", "Rafael", "Aaron", "Todd"].without("Aaron", "Todd") # => ["David", "Rafael"]
+```
+
+NOTE: Defined in `active_support/core_ext/enumerable.rb`.
+
+### `pluck`
+
+The method `pluck` returns an array based on the given key:
+
+```ruby
+[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) # => ["David", "Rafael", "Aaron"]
+```
+
+NOTE: Defined in `active_support/core_ext/enumerable.rb`.
+
Extensions to `Array`
---------------------
@@ -2206,14 +2213,14 @@ Extensions to `Array`
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:
```ruby
-%w(a b c d).to(2) # => %w(a b c)
+%w(a b c d).to(2) # => ["a", "b", "c"]
[].to(7) # => []
```
Similarly, `from` returns the tail from the element at the passed index to the end. If the index is greater than the length of the array, it returns an empty array.
```ruby
-%w(a b c d).from(2) # => %w(c d)
+%w(a b c d).from(2) # => ["c", "d"]
%w(a b c d).from(10) # => []
[].from(0) # => []
```
@@ -2221,7 +2228,7 @@ Similarly, `from` returns the tail from the element at the passed index to the e
The methods `second`, `third`, `fourth`, and `fifth` return the corresponding element (`first` is built-in). Thanks to social wisdom and positive constructiveness all around, `forty_two` is also available.
```ruby
-%w(a b c d).third # => c
+%w(a b c d).third # => "c"
%w(a b c d).fifth # => nil
```
@@ -2234,7 +2241,7 @@ NOTE: Defined in `active_support/core_ext/array/access.rb`.
This method is an alias of `Array#unshift`.
```ruby
-%w(a b c d).prepend('e') # => %w(e a b c d)
+%w(a b c d).prepend('e') # => ["e", "a", "b", "c", "d"]
[].prepend(10) # => [10]
```
@@ -2245,8 +2252,8 @@ NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`.
This method is an alias of `Array#<<`.
```ruby
-%w(a b c d).append('e') # => %w(a b c d e)
-[].append([1,2]) # => [[1,2]]
+%w(a b c d).append('e') # => ["a", "b", "c", "d", "e"]
+[].append([1,2]) # => [[1, 2]]
```
NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`.
@@ -2433,7 +2440,7 @@ The method `Array.wrap` wraps its argument in an array unless it is already an a
Specifically:
-* If the argument is `nil` an empty list is returned.
+* If the argument is `nil` an empty array is returned.
* Otherwise, if the argument responds to `to_ary` it is invoked, and if the value of `to_ary` is not `nil`, it is returned.
* Otherwise, an array with the argument as its single element is returned.
@@ -2445,9 +2452,9 @@ Array.wrap(0) # => [0]
This method is similar in purpose to `Kernel#Array`, but there are some differences:
-* If the argument responds to `to_ary` the method is invoked. `Kernel#Array` moves on to try `to_a` if the returned value is `nil`, but `Array.wrap` returns `nil` right away.
+* If the argument responds to `to_ary` the method is invoked. `Kernel#Array` moves on to try `to_a` if the returned value is `nil`, but `Array.wrap` returns an array with the argument as its single element right away.
* If the returned value from `to_ary` is neither `nil` nor an `Array` object, `Kernel#Array` raises an exception, while `Array.wrap` does not, it just returns the value.
-* It does not call `to_a` on the argument, though special-cases `nil` to return an empty array.
+* It does not call `to_a` on the argument, if the argument does not respond to +to_ary+ it returns an array with the argument as its single element.
The last point is particularly worth comparing for some enumerables:
@@ -2470,7 +2477,7 @@ NOTE: Defined in `active_support/core_ext/array/wrap.rb`.
### Duplicating
-The method `Array.deep_dup` duplicates itself and all objects inside
+The method `Array#deep_dup` duplicates itself and all objects inside
recursively with Active Support method `Object#deep_dup`. It works like `Array#map` with sending `deep_dup` method to each object inside.
```ruby
@@ -2692,7 +2699,7 @@ NOTE: Defined in `active_support/core_ext/hash/deep_merge.rb`.
### Deep duplicating
-The method `Hash.deep_dup` duplicates itself and all keys and values
+The method `Hash#deep_dup` duplicates itself and all keys and values
inside recursively with Active Support method `Object#deep_dup`. It works like `Enumerator#each_with_object` with sending `deep_dup` method to each pair inside.
```ruby
@@ -2888,7 +2895,7 @@ The method `transform_values` accepts a block and returns a hash that has applie
```
There's also the bang variant `transform_values!` that applies the block operations to values in the very receiver.
-NOTE: Defined in `active_support/core_text/hash/transform_values.rb`.
+NOTE: Defined in `active_support/core_ext/hash/transform_values.rb`.
### Slicing
@@ -3045,53 +3052,6 @@ The method `Range#overlaps?` says whether any two given ranges have non-void int
NOTE: Defined in `active_support/core_ext/range/overlaps.rb`.
-Extensions to `Proc`
---------------------
-
-### `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:
-
-```ruby
-Hash.instance_method(:delete) # => #<UnboundMethod: Hash#delete>
-```
-
-An unbound method is not callable as is, you need to bind it first to an object with `bind`:
-
-```ruby
-clear = Hash.instance_method(:clear)
-clear.bind({a: 1}).call # => {}
-```
-
-Active Support defines `Proc#bind` with an analogous purpose:
-
-```ruby
-Proc.new { size }.bind([]).call # => 0
-```
-
-As you see that's callable and bound to the argument, the return value is indeed a `Method`.
-
-NOTE: To do so `Proc#bind` actually creates a method under the hood. If you ever see a method with a weird name like `__bind_1256598120_237302` in a stack trace you know now where it comes from.
-
-Action Pack uses this trick in `rescue_from` for example, which accepts the name of a method and also a proc as callbacks for a given rescued exception. It has to call them in either case, so a bound method is returned by `handler_for_rescue`, thus simplifying the code in the caller:
-
-```ruby
-def handler_for_rescue(exception)
- _, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
- ...
- end
-
- case rescuer
- when Symbol
- method(rescuer)
- when Proc
- rescuer.bind(self)
- end
-end
-```
-
-NOTE: Defined in `active_support/core_ext/proc.rb`.
-
Extensions to `Date`
--------------------
@@ -3813,50 +3773,6 @@ WARNING. If the argument is an `IO` it needs to respond to `rewind` to be able t
NOTE: Defined in `active_support/core_ext/marshal.rb`.
-Extensions to `Logger`
-----------------------
-
-### `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`:
-
-```ruby
-logger = Logger.new("log/development.log")
-logger.around_info("before", "after") { |logger| logger.info("during") }
-```
-
-### `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.
-
-```ruby
-logger = Logger.new("log/development.log")
-logger.silence(Logger::INFO) do
- logger.debug("In space, no one can hear you scream.")
- logger.info("Scream all you want, small mailman!")
-end
-```
-
-### `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.
-
-```ruby
-class Logger::FormatWithTime < Logger::Formatter
- cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
-
- def self.call(severity, timestamp, progname, msg)
- "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
- end
-end
-
-logger = Logger.new("log/development.log")
-logger.formatter = Logger::FormatWithTime
-logger.info("<- is the current time")
-```
-
-NOTE: Defined in `active_support/core_ext/logger.rb`.
-
Extensions to `NameError`
-------------------------
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index 0aa74e387d..373dbbb9aa 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Support Instrumentation
==============================
@@ -19,7 +19,7 @@ After reading this guide, you will know:
Introduction to instrumentation
-------------------------------
-The instrumentation API provided by Active Support 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.
+The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the [Rails framework](#rails-framework-hooks). With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
For example, there is a hook provided within Active Record that is called every time Active Record uses an SQL query on a database. This hook could be **subscribed** to, and used to track the number of queries during a certain action. There's another hook around the processing of an action of a controller. This could be used, for instance, to track how long a specific action has taken.
@@ -218,7 +218,7 @@ Action View
```ruby
{
- identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb",
+ identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
}
```
@@ -252,6 +252,20 @@ INFO. The adapters will add their own data as well.
| `:name` | Record's class |
| `:connection_id` | `self.object_id` |
+### instantiation.active_record
+
+| Key | Value |
+| ---------------- | ----------------------------------------- |
+| `:record_count` | Number of records that instantiated |
+| `:class_name` | Record's class |
+
+```ruby
+{
+ record_count: 1,
+ class_name: "User"
+}
+```
+
Action Mailer
-------------
@@ -307,7 +321,7 @@ Action Mailer
}
```
-ActiveResource
+Active Resource
--------------
### request.active_resource
diff --git a/guides/source/api_app.md b/guides/source/api_app.md
new file mode 100644
index 0000000000..0a6335ed88
--- /dev/null
+++ b/guides/source/api_app.md
@@ -0,0 +1,435 @@
+Using Rails for API-only Apps
+=============================
+
+In this guide you will learn:
+
+- What Rails provides for API-only applications
+- How to configure Rails to start without any browser features
+- How to decide which middlewares you will want to include
+- How to decide which modules to use in your controller
+
+endprologue.
+
+### What is an API app?
+
+Traditionally, when people said that they used Rails as an “API”, they
+meant providing a programmatically accessible API alongside their web
+application.\
+For example, GitHub provides [an API](http://developer.github.com) that
+you can use from your own custom clients.
+
+With the advent of client-side frameworks, more developers are using
+Rails to build a backend that is shared between their web application
+and other native applications.
+
+For example, Twitter uses its [public API](https://dev.twitter.com) in
+its web application, which is built as a static site that consumes JSON
+resources.
+
+Instead of using Rails to generate dynamic HTML that will communicate
+with the server through forms and links, many developers are treating
+their web application as just another client, delivered as static HTML,
+CSS and JavaScript, and consuming a simple JSON API
+
+This guide covers building a Rails application that serves JSON
+resources to an API client **or** client-side framework.
+
+### Why use Rails for JSON APIs?
+
+The first question a lot of people have when thinking about building a
+JSON API using Rails is: “isn’t using Rails to spit out some JSON
+overkill? Shouldn’t I just use something like Sinatra?”
+
+For very simple APIs, this may be true. However, even in very HTML-heavy
+applications, most of an application’s logic is actually outside of the
+view layer.
+
+The reason most people use Rails is that it provides a set of defaults
+that allows us to get up and running quickly without having to make a
+lot of trivial decisions.
+
+Let’s take a look at some of the things that Rails provides out of the
+box that are still applicable to API applications.
+
+Handled at the middleware layer:
+
+- Reloading: Rails applications support transparent reloading. This
+ works even if your application gets big and restarting the server
+ for every request becomes non-viable.
+- Development Mode: Rails application come with smart defaults for
+ development, making development pleasant without compromising
+ production-time performance.
+- Test Mode: Ditto test mode.
+- Logging: Rails applications log every request, with a level of
+ verbosity appropriate for the current mode. Rails logs in
+ development include information about the request environment,
+ database queries, and basic performance information.
+- Security: Rails detects and thwarts [IP spoofing
+ attacks](http://en.wikipedia.org/wiki/IP_address_spoofing) and
+ handles cryptographic signatures in a [timing
+ attack](http://en.wikipedia.org/wiki/Timing_attack) aware way. Don’t
+ know what an IP spoofing attack or a timing attack is? Exactly.
+- Parameter Parsing: Want to specify your parameters as JSON instead
+ of as a URL-encoded String? No problem. Rails will decode the JSON
+ for you and make it available in *params*. Want to use nested
+ URL-encoded params? That works too.
+- Conditional GETs: Rails handles conditional *GET*, (*ETag* and
+ *Last-Modified*), processing request headers and returning the
+ correct response headers and status code. All you need to do is use
+ the
+ [stale?](http://api.rubyonrails.org/classes/ActionController/ConditionalGet.html#method-i-stale-3F)
+ check in your controller, and Rails will handle all of the HTTP
+ details for you.
+- Caching: If you use *dirty?* with public cache control, Rails will
+ automatically cache your responses. You can easily configure the
+ cache store.
+- HEAD requests: Rails will transparently convert *HEAD* requests into
+ *GET* requests, and return just the headers on the way out. This
+ makes *HEAD* work reliably in all Rails APIs.
+
+While you could obviously build these up in terms of existing Rack
+middlewares, I think this list demonstrates that the default Rails
+middleware stack provides a lot of value, even if you’re “just
+generating JSON”.
+
+Handled at the ActionPack layer:
+
+- Resourceful Routing: If you’re building a RESTful JSON API, you want
+ to be using the Rails router. Clean and conventional mapping from
+ HTTP to controllers means not having to spend time thinking about
+ how to model your API in terms of HTTP.
+- URL Generation: The flip side of routing is URL generation. A good
+ API based on HTTP includes URLs (see [the GitHub gist
+ API](http://developer.github.com/v3/gists/) for an example).
+- Header and Redirection Responses: *head :no\_content* and
+ *redirect\_to user\_url(current\_user)* come in handy. Sure, you
+ could manually add the response headers, but why?
+- Caching: Rails provides page, action and fragment caching. Fragment
+ caching is especially helpful when building up a nested JSON object.
+- Basic, Digest and Token Authentication: Rails comes with
+ out-of-the-box support for three kinds of HTTP authentication.
+- Instrumentation: Rails 3.0 added an instrumentation API that will
+ trigger registered handlers for a variety of events, such as action
+ processing, sending a file or data, redirection, and database
+ queries. The payload of each event comes with relevant information
+ (for the action processing event, the payload includes the
+ controller, action, params, request format, request method and the
+ request’s full path).
+- Generators: This may be passé for advanced Rails users, but it can
+ be nice to generate a resource and get your model, controller, test
+ stubs, and routes created for you in a single command.
+- Plugins: Many third-party libraries come with support for Rails that
+ reduces or eliminates the cost of setting up and gluing together the
+ library and the web framework. This includes things like overriding
+ default generators, adding rake tasks, and honoring Rails choices
+ (like the logger and cache backend).
+
+Of course, the Rails boot process also glues together all registered
+components. For example, the Rails boot process is what uses your
+*config/database.yml* file when configuring ActiveRecord.
+
+**The short version is**: you may not have thought about which parts of
+Rails are still applicable even if you remove the view layer, but the
+answer turns out to be “most of it”.
+
+### The Basic Configuration
+
+If you’re building a Rails application that will be an API server first
+and foremost, you can start with a more limited subset of Rails and add
+in features as needed.
+
+You can generate a new api Rails app:
+
+<shell>\
+\$ rails new my\_api --api\
+</shell>
+
+This will do three main things for you:
+
+- Configure your application to start with a more limited set of
+ middleware than normal. Specifically, it will not include any
+ middleware primarily useful for browser applications (like cookie
+ support) by default.
+- Make *ApplicationController* inherit from *ActionController::API*
+ instead of *ActionController::Base*. As with middleware, this will
+ leave out any *ActionController* modules that provide functionality
+ primarily used by browser applications.
+- Configure the generators to skip generating views, helpers and
+ assets when you generate a new resource.
+
+If you want to take an existing app and make it an API app, follow the
+following steps.
+
+In *config/application.rb* add the following line at the top of the
+*Application* class:
+
+<ruby>\
+config.api\_only!\
+</ruby>
+
+Change *app/controllers/application\_controller.rb*:
+
+<ruby>
+
+1. instead of\
+ class ApplicationController \< ActionController::Base\
+ end
+
+<!-- -->
+
+1. do\
+ class ApplicationController \< ActionController::API\
+ end\
+ </ruby>
+
+### Choosing Middlewares
+
+An API application comes with the following middlewares by default.
+
+- *Rack::Cache*: Caches responses with public *Cache-Control* headers
+ using HTTP caching semantics. See below for more information.
+- *Rack::Sendfile*: Uses a front-end server’s file serving support
+ from your Rails application.
+- *Rack::Lock*: If your application is not marked as threadsafe
+ (*config.threadsafe!*), this middleware will add a mutex around your
+ requests.
+- *ActionDispatch::RequestId*:
+- *Rails::Rack::Logger*:
+- *Rack::Runtime*: Adds a header to the response listing the total
+ runtime of the request.
+- *ActionDispatch::ShowExceptions*: Rescue exceptions and re-dispatch
+ them to an exception handling application
+- *ActionDispatch::DebugExceptions*: Log exceptions
+- *ActionDispatch::RemoteIp*: Protect against IP spoofing attacks
+- *ActionDispatch::Reloader*: In development mode, support code
+ reloading.
+- *ActionDispatch::ParamsParser*: Parse XML, YAML and JSON parameters
+ when the request’s *Content-Type* is one of those.
+- *ActionDispatch::Head*: Dispatch *HEAD* requests as *GET* requests,
+ and return only the status code and headers.
+- *Rack::ConditionalGet*: Supports the *stale?* feature in Rails
+ controllers.
+- *Rack::ETag*: Automatically set an *ETag* on all string responses.
+ This means that if the same response is returned from a controller
+ for the same URL, the server will return a *304 Not Modified*, even
+ if no additional caching steps are taken. This is primarily a
+ client-side optimization; it reduces bandwidth costs but not server
+ processing time.
+
+Other plugins, including *ActiveRecord*, may add additional middlewares.
+In general, these middlewares are agnostic to the type of app you are
+building, and make sense in an API-only Rails application.
+
+You can get a list of all middlewares in your application via:
+
+<shell>\
+\$ rake middleware\
+</shell>
+
+#### Using Rack::Cache
+
+When used with Rails, *Rack::Cache* uses the Rails cache store for its
+entity and meta stores. This means that if you use memcache, for your
+Rails app, for instance, the built-in HTTP cache will use memcache.
+
+To make use of *Rack::Cache*, you will want to use *stale?* in your
+controller. Here’s an example of *stale?* in use.
+
+<ruby>\
+def show\
+ @post = Post.find(params[:id])
+
+if stale?(:last\_modified =\> `post.updated_at)
+ render json: `post\
+ end\
+end\
+</ruby>
+
+The call to *stale?* will compare the *If-Modified-Since* header in the
+request with *@post.updated\_at*. If the header is newer than the last
+modified, this action will return a *304 Not Modified* response.
+Otherwise, it will render the response and include a *Last-Modified*
+header with the response.
+
+Normally, this mechanism is used on a per-client basis. *Rack::Cache*
+allows us to share this caching mechanism across clients. We can enable
+cross-client caching in the call to *stale?*
+
+<ruby>\
+def show\
+ @post = Post.find(params[:id])
+
+if stale?(:last\_modified =\> `post.updated_at, :public => true)
+ render json: `post\
+ end\
+end\
+</ruby>
+
+This means that *Rack::Cache* will store off *Last-Modified* value for a
+URL in the Rails cache, and add an *If-Modified-Since* header to any
+subsequent inbound requests for the same URL.
+
+Think of it as page caching using HTTP semantics.
+
+NOTE: The *Rack::Cache* middleware is always outside of the *Rack::Lock*
+mutex, even in single-threaded apps.
+
+#### Using Rack::Sendfile
+
+When you use the *send\_file* method in a Rails controller, it sets the
+*X-Sendfile* header. *Rack::Sendfile* is responsible for actually
+sending the file.
+
+If your front-end server supports accelerated file sending,
+*Rack::Sendfile* will offload the actual file sending work to the
+front-end server.
+
+You can configure the name of the header that your front-end server uses
+for this purposes using *config.action\_dispatch.x\_sendfile\_header* in
+the appropriate environment config file.
+
+You can learn more about how to use *Rack::Sendfile* with popular
+front-ends in [the Rack::Sendfile
+documentation](http://rubydoc.info/github/rack/rack/master/Rack/Sendfile)
+
+The values for popular servers once they are configured to support
+accelerated file sending:
+
+<ruby>
+
+1. Apache and lighttpd\
+ config.action\_dispatch.x\_sendfile\_header = “X-Sendfile”
+
+<!-- -->
+
+1. nginx\
+ config.action\_dispatch.x\_sendfile\_header = “X-Accel-Redirect”\
+ </ruby>
+
+Make sure to configure your server to support these options following
+the instructions in the *Rack::Sendfile* documentation.
+
+NOTE: The *Rack::Sendfile* middleware is always outside of the
+*Rack::Lock* mutex, even in single-threaded apps.
+
+#### Using ActionDispatch::ParamsParser
+
+*ActionDispatch::ParamsParser* will take parameters from the client in
+JSON and make them available in your controller as *params*.
+
+To use this, your client will need to make a request with JSON-encoded
+parameters and specify the *Content-Type* as *application/json*.
+
+Here’s an example in jQuery:
+
+<plain>\
+jQuery.ajax({\
+ type: ‘POST’,\
+ url: ‘/people’\
+ dataType: ‘json’,\
+ contentType: ‘application/json’,\
+ data: JSON.stringify({ person: { firstName: “Yehuda”, lastName: “Katz”
+} }),
+
+success: function(json) { }\
+});\
+</plain>
+
+*ActionDispatch::ParamsParser* will see the *Content-Type* and your
+params will be *{ :person =\> { :firstName =\> “Yehuda”, :lastName =\>
+“Katz” } }*.
+
+#### Other Middlewares
+
+Rails ships with a number of other middlewares that you might want to
+use in an API app, especially if one of your API clients is the browser:
+
+- *Rack::MethodOverride*: Allows the use of the *\_method* hack to
+ route POST requests to other verbs.
+- *ActionDispatch::Cookies*: Supports the *cookie* method in
+ *ActionController*, including support for signed and encrypted
+ cookies.
+- *ActionDispatch::Flash*: Supports the *flash* mechanism in
+ *ActionController*.
+- *ActionDispatch::BestStandards*: Tells Internet Explorer to use the
+ most standards-compliant available renderer. In production mode, if
+ ChromeFrame is available, use ChromeFrame.
+- Session Management: If a *config.session\_store* is supplied, this
+ middleware makes the session available as the *session* method in
+ *ActionController*.
+
+Any of these middlewares can be adding via:
+
+<ruby>\
+config.middleware.use Rack::MethodOverride\
+</ruby>
+
+#### Removing Middlewares
+
+If you don’t want to use a middleware that is included by default in the
+API-only middleware set, you can remove it using
+*config.middleware.delete*:
+
+<ruby>\
+config.middleware.delete ::Rack::Sendfile\
+</ruby>
+
+Keep in mind that removing these features may remove support for certain
+features in *ActionController*.
+
+### Choosing Controller Modules
+
+An API application (using *ActionController::API*) comes with the
+following controller modules by default:
+
+- *ActionController::UrlFor*: Makes *url\_for* and friends available
+- *ActionController::Redirecting*: Support for *redirect\_to*
+- *ActionController::Rendering*: Basic support for rendering
+- *ActionController::Renderers::All*: Support for *render :json* and
+ friends
+- *ActionController::ConditionalGet*: Support for *stale?*
+- *ActionController::ForceSSL*: Support for *force\_ssl*
+- *ActionController::RackDelegation*: Support for the *request* and
+ *response* methods returning *ActionDispatch::Request* and
+ *ActionDispatch::Response* objects.
+- *ActionController::DataStreaming*: Support for *send\_file* and
+ *send\_data*
+- *AbstractController::Callbacks*: Support for *before\_filter* and
+ friends
+- *ActionController::Instrumentation*: Support for the instrumentation
+ hooks defined by *ActionController* (see [the
+ source](https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/instrumentation.rb)
+ for more).
+- *ActionController::Rescue*: Support for *rescue\_from*.
+
+Other plugins may add additional modules. You can get a list of all
+modules included into *ActionController::API* in the rails console:
+
+<shell>\
+\$ irb\
+\>\> ActionController::API.ancestors -
+ActionController::Metal.ancestors\
+</shell>
+
+#### Adding Other Modules
+
+All ActionController modules know about their dependent modules, so you
+can feel free to include any modules into your controllers, and all
+dependencies will be included and set up as well.
+
+Some common modules you might want to add:
+
+- *AbstractController::Translation*: Support for the *l* and *t*
+ localization and translation methods. These delegate to
+ *I18n.translate* and *I18n.localize*.
+- *ActionController::HTTPAuthentication::Basic* (or *Digest*
+ or +Token): Support for basic, digest or token HTTP authentication.
+- *AbstractController::Layouts*: Support for layouts when rendering.
+- *ActionController::MimeResponds*: Support for content negotiation
+ (*respond\_to*, *respond\_with*).
+- *ActionController::Cookies*: Support for *cookies*, which includes
+ support for signed and encrypted cookies. This requires the cookie
+ middleware.
+
+The best place to add a module is in your *ApplicationController*. You
+can also add modules to individual controllers.
diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md
index d481700709..46c9013087 100644
--- a/guides/source/api_documentation_guidelines.md
+++ b/guides/source/api_documentation_guidelines.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
API Documentation Guidelines
============================
@@ -16,7 +16,8 @@ RDoc
----
The [Rails API documentation](http://api.rubyonrails.org) is generated with
-[RDoc](http://docs.seattlerb.org/rdoc/).
+[RDoc](http://docs.seattlerb.org/rdoc/). To generate it, make sure you are
+in the rails root directory, run `bundle install` and execute:
```bash
bundle exec rake rdoc
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 64d1c31083..4a610e8458 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
The Asset Pipeline
==================
@@ -149,7 +149,7 @@ clients to fetch them again, even when the content of those assets has not chang
Fingerprinting fixes these problems by avoiding query strings, and by ensuring
that filenames are consistent based on their content.
-Fingerprinting is enabled by default for production and disabled for all other
+Fingerprinting is enabled by default for both the development and production
environments. You can enable or disable it in your configuration through the
`config.assets.digest` option.
@@ -209,7 +209,7 @@ precompiling works.
NOTE: You must have an ExecJS 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.
+your operating system. Check [ExecJS](https://github.com/rails/execjs#readme) documentation to know all supported JavaScript runtimes.
You can also disable generation of controller specific asset files by adding the
following to your `config/application.rb` configuration:
@@ -643,7 +643,7 @@ above. By default Rails assumes assets have been precompiled and will be
served as static assets by your web server.
During the precompilation phase an MD5 is generated from the contents of the
-compiled files, and inserted into the filenames as they are written to disc.
+compiled files, and inserted into the filenames as they are written to disk.
These fingerprinted names are used by the Rails helpers in place of the manifest
name.
@@ -667,8 +667,7 @@ anymore, delete these options from the `javascript_include_tag` and
`stylesheet_link_tag`.
The fingerprinting behavior is controlled by the `config.assets.digest`
-initialization option (which defaults to `true` for production and `false` for
-everything else).
+initialization option (which defaults to `true` for production and development).
NOTE: Under normal circumstances the default `config.assets.digest` option
should not be changed. If there are no digests in the filenames, and far-future
@@ -729,27 +728,6 @@ include, you can add them to the `precompile` array in `config/initializers/asse
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
```
-Or, you can opt to precompile all assets with something like this:
-
-```ruby
-# config/initializers/assets.rb
-Rails.application.config.assets.precompile << Proc.new do |path|
- if path =~ /\.(css|js)\z/
- full_path = Rails.application.assets.resolve(path).to_path
- app_assets_path = Rails.root.join('app', 'assets').to_path
- if full_path.starts_with? app_assets_path
- logger.info "including asset: " + full_path
- true
- else
- logger.info "excluding asset: " + full_path
- false
- end
- else
- false
- end
-end
-```
-
NOTE. Always specify an expected compiled filename that ends with .js or .css,
even if you want to add Sass or CoffeeScript files to the precompile array.
@@ -812,41 +790,6 @@ location ~ ^/assets/ {
}
```
-#### 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.
-
-NGINX is able to do this automatically enabling `gzip_static`:
-
-```nginx
-location ~ ^/(assets)/ {
- root /path/to/public;
- gzip_static on; # to serve pre-gzipped version
- expires max;
- add_header Cache-Control public;
-}
-```
-
-This directive is available if the core module that provides this feature was
-compiled with the web server. Ubuntu/Debian packages, even `nginx-light`, have
-the module compiled. Otherwise, you may need to perform a manual compilation:
-
-```bash
-./configure --with-http_gzip_static_module
-```
-
-If you're compiling NGINX with Phusion Passenger you'll need to pass that option
-when prompted.
-
-A robust configuration for Apache is possible but tricky; please Google around.
-(Or help update this Guide if you have a good configuration example for Apache.)
-
### Local Precompilation
There are several reasons why you might want to precompile your assets locally.
@@ -942,7 +885,7 @@ focus on serving application code as fast as possible.
#### Set up a CDN to Serve Static Assets
To set up your CDN you have to have your application running in production on
-the internet at a publically available URL, for example `example.com`. Next
+the internet at a publicly available URL, for example `example.com`. Next
you'll need to sign up for a CDN service from a cloud hosting provider. When you
do this you need to configure the "origin" of the CDN to point back at your
website `example.com`, check your provider for documentation on configuring the
@@ -995,7 +938,7 @@ http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
If the CDN has a copy of `smile.png` it will serve it to the browser and your
server doesn't even know it was requested. If the CDN does not have a copy it
-will try to find it a the "origin" `example.com/assets/smile.png` and then store
+will try to find it at the "origin" `example.com/assets/smile.png` and then store
it for future use.
If you want to serve only some assets from your CDN, you can use custom `:host`
@@ -1158,7 +1101,7 @@ The following line invokes `uglifier` for JavaScript compression.
config.assets.js_compressor = :uglifier
```
-NOTE: You will need an [ExecJS](https://github.com/sstephenson/execjs#readme)
+NOTE: You will need an [ExecJS](https://github.com/rails/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.
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index 95c7e747ef..05dd0d2a04 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Active Record Associations
==========================
@@ -146,6 +146,17 @@ class CreateSuppliers < ActiveRecord::Migration
end
```
+Depending on the use case, you might also need to create a unique index and/or
+a foreign key constraint on the supplier column for the accounts table. In this
+case, the column definition might look like this:
+
+```ruby
+create_table :accounts do |t|
+ t.belongs_to :supplier, index: true, unique: true, foreign_key: true
+ # ...
+end
+```
+
### 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:
@@ -171,7 +182,7 @@ class CreateCustomers < ActiveRecord::Migration
end
create_table :orders do |t|
- t.belongs_to :customer, index:true
+ t.belongs_to :customer, index: true
t.datetime :order_date
t.timestamps null: false
end
@@ -424,7 +435,7 @@ end
The simplest rule of thumb is that you should set up a `has_many :through` relationship if you need to work with the relationship model as an independent entity. If you don't need to do anything with the relationship model, it may be simpler to set up a `has_and_belongs_to_many` relationship (though you'll need to remember to create the joining table in the database).
-You should use `has_many :through` if you need validations, callbacks, or extra attributes on the join model.
+You should use `has_many :through` if you need validations, callbacks or extra attributes on the join model.
### Polymorphic Associations
@@ -460,7 +471,7 @@ class CreatePictures < ActiveRecord::Migration
t.timestamps null: false
end
- add_index :pictures, :imageable_id
+ add_index :pictures, [:imageable_type, :imageable_id]
end
end
```
@@ -579,7 +590,7 @@ If you create an association some time after you build the underlying model, you
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.
-WARNING: The precedence between model names is calculated using the `<` operator for `String`. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers" (because the underscore '_' is lexicographically _less_ than 's' in common encodings).
+WARNING: The precedence between model names is calculated using the `<=>` operator for `String`. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers" (because the underscore '\_' is lexicographically _less_ than 's' in common encodings).
Whatever the name, you must manually generate the join table with an appropriate migration. For example, consider these associations:
@@ -609,7 +620,7 @@ class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
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.
+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 model IDs, or exceptions about conflicting IDs, chances are you forgot that bit.
### Controlling Association Scope
@@ -691,7 +702,7 @@ c.first_name = 'Manny'
c.first_name == o.customer.first_name # => false
```
-This happens because c and o.customer are two different in-memory representations of the same data, and neither one is automatically refreshed from changes to the other. Active Record provides the `:inverse_of` option so that you can inform it of these relations:
+This happens because `c` and `o.customer` are two different in-memory representations of the same data, and neither one is automatically refreshed from changes to the other. Active Record provides the `:inverse_of` option so that you can inform it of these relations:
```ruby
class Customer < ActiveRecord::Base
@@ -726,10 +737,10 @@ Most associations with standard names will be supported. However, associations
that contain the following options will not have their inverses set
automatically:
-* :conditions
-* :through
-* :polymorphic
-* :foreign_key
+* `:conditions`
+* `:through`
+* `:polymorphic`
+* `:foreign_key`
Detailed Association Reference
------------------------------
@@ -782,7 +793,7 @@ If the associated object has already been retrieved from the database for this o
##### `association=(associate)`
-The `association=` 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.
+The `association=` method assigns an associated object to this object. Behind the scenes, this means extracting the primary key from the associated object and setting this object's foreign key to the same value.
```ruby
@order.customer = @customer
@@ -829,10 +840,12 @@ The `belongs_to` association supports these options:
* `:counter_cache`
* `:dependent`
* `:foreign_key`
+* `:primary_key`
* `:inverse_of`
* `:polymorphic`
* `:touch`
* `:validate`
+* `:optional`
##### `:autosave`
@@ -874,18 +887,26 @@ end
With this declaration, Rails will keep the cache value up to date, and then return that value in response to the `size` method.
-Although the `:counter_cache` option is specified on the model that includes the `belongs_to` declaration, the actual column must be added to the _associated_ model. In the case above, you would need to add a column named `orders_count` to the `Customer` model. You can override the default column name if you need to:
+Although the `:counter_cache` option is specified on the model that includes
+the `belongs_to` declaration, the actual column must be added to the
+_associated_ (`has_many`) model. In the case above, you would need to add a
+column named `orders_count` to the `Customer` model.
+
+You can override the default column name by specifying a custom column name in
+the `counter_cache` declaration instead of `true`. For example, to use
+`count_of_orders` instead of `orders_count`:
```ruby
class Order < ActiveRecord::Base
belongs_to :customer, counter_cache: :count_of_orders
end
class Customer < ActiveRecord::Base
- has_many :orders, counter_cache: :count_of_orders
+ has_many :orders
end
```
-NOTE: You only need to specify the :counter_cache option on the "has_many side" of the association when using a custom name for the counter cache.
+NOTE: You only need to specify the :counter_cache option on the `belongs_to`
+side of the association.
Counter cache columns are added to the containing model's list of read-only attributes through `attr_readonly`.
@@ -912,6 +933,26 @@ 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.
+##### `:primary_key`
+
+By convention, Rails assumes that the `id` column is used to hold the primary key
+of its tables. The `:primary_key` option allows you to specify a different column.
+
+For example, given we have a `users` table with `guid` as the primary key. If we want a separate `todos` table to hold the foreign key `user_id` in the `guid` column, then we can use `primary_key` to achieve this like so:
+
+```ruby
+class User < ActiveRecord::Base
+ self.primary_key = 'guid' # primary key is guid and not id
+end
+
+class Todo < ActiveRecord::Base
+ belongs_to :user, primary_key: 'guid'
+end
+```
+
+When we execute `@user.todos.create` then the `@todo` record will have its
+`user_id` value as the `guid` value of `@user`.
+
##### `: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.
@@ -932,7 +973,7 @@ Passing `true` to the `:polymorphic` option indicates that this is a polymorphic
##### `: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:
+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:
```ruby
class Order < ActiveRecord::Base
@@ -956,6 +997,11 @@ end
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.
+##### `:optional`
+
+If you set the `:optional` option to `true`, then the presence of the associated
+object won't be validated. By default, this option is set to `false`.
+
#### 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:
@@ -1092,7 +1138,7 @@ If the associated object has already been retrieved from the database for this o
##### `association=(associate)`
-The `association=` 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.
+The `association=` method assigns an associated object to this object. Behind the scenes, this means extracting the primary key from this object and setting the associated object's foreign key to the same value.
```ruby
@supplier.account = @account
@@ -1173,8 +1219,8 @@ Controls what happens to the associated object when its owner is destroyed:
It's necessary not to set or leave `:nullify` option for those associations
that have `NOT NULL` database constraints. If you don't set `dependent` to
destroy such associations you won't be able to change the associated object
-because initial associated object foreign key will be set to unallowed `NULL`
-value.
+because the initial associated object's foreign key will be set to the
+unallowed `NULL` value.
##### `:foreign_key`
@@ -1421,7 +1467,14 @@ The `collection_singular_ids=` method makes the collection contain only the obje
##### `collection.clear`
-The `collection.clear` 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`.
+The `collection.clear` method removes all objects from the collection according to the strategy specified by the `dependent` option. If no option is given, it follows the default strategy. The default strategy for `has_many :through` associations is `delete_all`, and for `has_many` associations is to set the foreign keys to `NULL`.
+
+```ruby
+@customer.orders.clear
+```
+
+WARNING: Objects will be deleted if they're associated with `dependent: :destroy`,
+just like `dependent: :delete_all`.
##### `collection.empty?`
@@ -1460,7 +1513,9 @@ The `collection.where` method finds objects within the collection based on the c
##### `collection.exists?(...)`
-The `collection.exists?` method checks whether an object meeting the supplied conditions exists in the collection. It uses the same syntax and options as `ActiveRecord::Base.exists?`.
+The `collection.exists?` method checks whether an object meeting the supplied
+conditions exists in the collection. It uses the same syntax and options as
+[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
##### `collection.build(attributes = {}, ...)`
@@ -1490,7 +1545,7 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Customer < ActiveRecord::Base
- has_many :orders, dependent: :delete_all, validate: :false
+ has_many :orders, dependent: :delete_all, validate: false
end
```
@@ -1571,9 +1626,10 @@ end
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.
-Let's say that `users` table has `id` as the primary_key but it also has
-`guid` column. And the requirement is that `todos` table should hold
-`guid` column value and not `id` value. This can be achieved like this
+Let's say the `users` table has `id` as the primary_key but it also
+has a `guid` column. The requirement is that the `todos` table should
+hold the `guid` column value as the foreign key and not `id`
+value. This can be achieved like this:
```ruby
class User < ActiveRecord::Base
@@ -1581,8 +1637,8 @@ class User < ActiveRecord::Base
end
```
-Now if we execute `@user.todos.create` then `@todo` record will have
-`user_id` value as the `guid` value of `@user`.
+Now if we execute `@todo = @user.todos.create` then the `@todo`
+record's `user_id` value will be the `guid` value of `@user`.
##### `:source`
@@ -1622,7 +1678,7 @@ You can use any of the standard [querying methods](active_record_querying.html)
* `order`
* `readonly`
* `select`
-* `uniq`
+* `distinct`
##### `where`
@@ -1958,7 +2014,9 @@ The `collection.where` method finds objects within the collection based on the c
##### `collection.exists?(...)`
-The `collection.exists?` method checks whether an object meeting the supplied conditions exists in the collection. It uses the same syntax and options as `ActiveRecord::Base.exists?`.
+The `collection.exists?` method checks whether an object meeting the supplied
+conditions exists in the collection. It uses the same syntax and options as
+[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
##### `collection.build(attributes = {})`
@@ -1986,8 +2044,8 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Parts < ActiveRecord::Base
- has_and_belongs_to_many :assemblies, autosave: true,
- readonly: true
+ has_and_belongs_to_many :assemblies, -> { readonly },
+ autosave: true
end
```
@@ -1999,7 +2057,6 @@ The `has_and_belongs_to_many` association supports these options:
* `:foreign_key`
* `:join_table`
* `:validate`
-* `:readonly`
##### `:association_foreign_key`
@@ -2243,3 +2300,67 @@ Extensions can refer to the internals of the association proxy using these three
* `proxy_association.owner` returns the object that the association is a part of.
* `proxy_association.reflection` returns the reflection object that describes the association.
* `proxy_association.target` returns the associated object for `belongs_to` or `has_one`, or the collection of associated objects for `has_many` or `has_and_belongs_to_many`.
+
+Single Table Inheritance
+------------------------
+
+Sometimes, you may want to share fields and behavior between different models.
+Let's say we have Car, Motorcycle and Bicycle models. We will want to share
+the `color` and `price` fields and some methods for all of them, but having some
+specific behavior for each, and separated controllers too.
+
+Rails makes this quite easy. First, let's generate the base Vehicle model:
+
+```bash
+$ rails generate model vehicle type:string color:string price:decimal{10.2}
+```
+
+Did you note we are adding a "type" field? Since all models will be saved in a
+single database table, Rails will save in this column the name of the model that
+is being saved. In our example, this can be "Car", "Motorcycle" or "Bicycle."
+STI won't work without a "type" field in the table.
+
+Next, we will generate the three models that inherit from Vehicle. For this,
+we can use the `--parent=PARENT` option, which will generate a model that
+inherits from the specified parent and without equivalent migration (since the
+table already exists).
+
+For example, to generate the Car model:
+
+```bash
+$ rails generate model car --parent=Vehicle
+```
+
+The generated model will look like this:
+
+```ruby
+class Car < Vehicle
+end
+```
+
+This means that all behavior added to Vehicle is available for Car too, as
+associations, public methods, etc.
+
+Creating a car will save it in the `vehicles` table with "Car" as the `type` field:
+
+```ruby
+Car.create color: 'Red', price: 10000
+```
+
+will generate the following SQL:
+
+```sql
+INSERT INTO "vehicles" ("type", "color", "price") VALUES ("Car", "Red", 10000)
+```
+
+Querying car records will just search for vehicles that are cars:
+
+```ruby
+Car.all
+```
+
+will run a query like:
+
+```sql
+SELECT "vehicles".* FROM "vehicles" WHERE "vehicles"."type" IN ('Car')
+```
diff --git a/guides/source/autoloading_and_reloading_constants.md b/guides/source/autoloading_and_reloading_constants.md
index 489ea681e2..2b6d7e4044 100644
--- a/guides/source/autoloading_and_reloading_constants.md
+++ b/guides/source/autoloading_and_reloading_constants.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Autoloading and Reloading Constants
===================================
@@ -80,7 +80,8 @@ end
```
The *nesting* at any given place is the collection of enclosing nested class and
-module objects outwards. For example, in the previous example, the nesting at
+module objects outwards. The nesting at any given place can be inspected with
+`Module.nesting`. For example, in the previous example, the nesting at
(1) is
```ruby
@@ -113,6 +114,16 @@ certain nesting does not necessarily correlate with the namespaces at the spot.
Even more, they are totally independent, take for instance
```ruby
+module X
+ module Y
+ end
+end
+
+module A
+ module B
+ end
+end
+
module X::Y
module A::B
# (3)
@@ -140,9 +151,10 @@ executed, and popped after it.
* A singleton class opened with `class << object` gets pushed, and popped later.
-* When any of the `*_eval` family of methods is called using a string argument,
+* When `instance_eval` is called using a string argument,
the singleton class of the receiver is pushed to the nesting of the eval'ed
-code.
+code. When `class_eval` or `module_eval` is called using a string argument,
+the receiver is pushed to the nesting of the eval'ed code.
* The nesting at the top-level of code interpreted by `Kernel#load` is empty
unless the `load` call receives a true value as second argument, in which case
@@ -153,8 +165,6 @@ the blocks that may be passed to `Class.new` and `Module.new` do not get the
class or module being defined pushed to their nesting. That's one of the
differences between defining classes and modules in one way or another.
-The nesting at any given place can be inspected with `Module.nesting`.
-
### Class and Module Definitions are Constant Assignments
Let's suppose the following snippet creates a class (rather than reopening it):
@@ -236,7 +246,7 @@ end
```
`Post` is not syntax for a class. Rather, `Post` is a regular Ruby constant. If
-all is good, the constant evaluates to an object that responds to `all`.
+all is good, the constant is evaluated to an object that responds to `all`.
That is why we talk about *constant* autoloading, Rails has the ability to
load constants on the fly.
@@ -291,7 +301,9 @@ order. The ancestors of those elements are ignored.
2. If not found, then the algorithm walks up the ancestor chain of the cref.
-3. If not found, `const_missing` is invoked on the cref. The default
+3. If not found and the cref is a module, the constant is looked up in `Object`.
+
+4. If not found, `const_missing` is invoked on the cref. The default
implementation of `const_missing` raises `NameError`, but it can be overridden.
Rails autoloading **does not emulate this algorithm**, but its starting point is
@@ -314,7 +326,7 @@ relative: `::Billing::Invoice`. That would force `Billing` to be looked up
only as a top-level constant.
`Invoice` on the other hand is qualified by `Billing` and we are going to see
-its resolution next. Let's call *parent* to that qualifying class or module
+its resolution next. Let's define *parent* to be that qualifying class or module
object, that is, `Billing` in the example above. The algorithm for qualified
constants goes like this:
@@ -330,7 +342,7 @@ checked.
Rails autoloading **does not emulate this algorithm**, but its starting point is
the name of the constant to be autoloaded, and the parent. See more in
-[Qualified References](#qualified-references).
+[Qualified References](#autoloading-algorithms-qualified-references).
Vocabulary
@@ -451,9 +463,11 @@ Also, this collection is configurable via `config.autoload_paths`. For example,
by adding this to `config/application.rb`:
```ruby
-config.autoload_paths += "#{Rails.root}/lib"
+config.autoload_paths << "#{Rails.root}/lib"
```
+`config.autoload_paths` is not changeable from environment-specific configuration files.
+
The value of `autoload_paths` can be inspected. In a just generated application
it is (edited):
@@ -685,12 +699,12 @@ creates an empty module and assigns it to the `Admin` constant on the fly.
### Generic Procedure
Relative references are reported to be missing in the cref where they were hit,
-and qualified references are reported to be missing in their parent. (See
+and qualified references are reported to be missing in their parent (see
[Resolution Algorithm for Relative
Constants](#resolution-algorithm-for-relative-constants) at the beginning of
this guide for the definition of *cref*, and [Resolution Algorithm for Qualified
Constants](#resolution-algorithm-for-qualified-constants) for the definition of
-*parent*.)
+*parent*).
The procedure to autoload constant `C` in an arbitrary situation is as follows:
@@ -868,8 +882,8 @@ end
```
To resolve `User` Ruby checks `Admin` in the former case, but it does not in
-the latter because it does not belong to the nesting. (See [Nesting](#nesting)
-and [Resolution Algorithms](#resolution-algorithms).)
+the latter because it does not belong to the nesting (see [Nesting](#nesting)
+and [Resolution Algorithms](#resolution-algorithms)).
Unfortunately Rails autoloading does not know the nesting in the spot where the
constant was missing and so it is not able to act as Ruby would. In particular,
@@ -1284,7 +1298,7 @@ c.user # NameError: uninitialized constant C::User
```
because it detects that a parent namespace already has the constant (see [Qualified
-References](#autoloading-algorithms-qualified-references).)
+References](#autoloading-algorithms-qualified-references)).
As with pure Ruby, within the body of a direct descendant of `BasicObject` use
always absolute constant paths:
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 61b991df61..782406659d 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Caching with Rails: An overview
===============================
@@ -22,7 +22,7 @@ fragment caching. Rails provides by default fragment caching. In order to use
page and action caching, you will need to add `actionpack-page_caching` and
`actionpack-action_caching` to your Gemfile.
-To start playing with caching you'll want to ensure that `config.action_controller.perform_caching` is set to `true`, if you're running in development mode. This flag is normally set in the corresponding `config/environments/*.rb` and caching is disabled by default for development and test, and enabled for production.
+To start playing with caching you'll want to ensure that `config.action_controller.perform_caching` is set to `true` if you're running in development mode. This flag is normally set in the corresponding `config/environments/*.rb` and caching is disabled by default for development and test, and enabled for production.
```ruby
config.action_controller.perform_caching = true
@@ -32,7 +32,7 @@ config.action_controller.perform_caching = true
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.
-INFO: Page Caching has been removed from Rails 4. See the [actionpack-page_caching gem](https://github.com/rails/actionpack-page_caching). See [DHH's key-based cache expiration overview](http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works) for the newly-preferred method.
+INFO: Page Caching has been removed from Rails 4. See the [actionpack-page_caching gem](https://github.com/rails/actionpack-page_caching).
### Action Caching
@@ -144,7 +144,7 @@ It's called "Russian Doll Caching" because it nests multiple fragments. The adva
### Low-Level Caching
-Sometimes you need to cache a particular value or query result, instead of caching view fragments. Rails caching mechanism works great for storing __any__ kind of information.
+Sometimes you need to cache a particular value or query result instead of caching view fragments. Rails' caching mechanism works great for storing __any__ kind of information.
The most efficient way to implement low-level caching is using the `Rails.cache.fetch` method. This method does both reading and writing to the cache. When passed only a single argument, the key is fetched and value from the cache is returned. If a block is passed, the result of the block will be cached to the given key and the result is returned.
@@ -160,7 +160,7 @@ class Product < ActiveRecord::Base
end
```
-NOTE: Notice that in this example we used `cache_key` method, so the resulting cache-key will be something like `products/233-20140225082222765838000/competing_price`. `cache_key` generates a string based on the model’s `id` and `updated_at` attributes. This is a common convention and has the benefit of invalidating the cache whenever the product is updated. In general, when you use low-level caching for instance level information, you need to generate a cache key.
+NOTE: Notice that in this example we used the `cache_key` method, so the resulting cache-key will be something like `products/233-20140225082222765838000/competing_price`. `cache_key` generates a string based on the model’s `id` and `updated_at` attributes. This is a common convention and has the benefit of invalidating the cache whenever the product is updated. In general, when you use low-level caching for instance level information, you need to generate a cache key.
### SQL Caching
@@ -184,6 +184,10 @@ class ProductsController < ApplicationController
end
```
+The second time the same query is run against the database, it's not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it's pulled from memory.
+
+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.
+
Cache Stores
------------
@@ -215,7 +219,7 @@ There are some common options used by all cache implementations. These can be pa
* `:compress` - This option can be used to indicate that compression should be used in the cache. This can be useful for transferring large cache entries over a slow network.
-* `:compress_threshold` - This options is used in conjunction with the `:compress` option to indicate a threshold under which cache entries should not be compressed. This defaults to 16 kilobytes.
+* `:compress_threshold` - This option is used in conjunction with the `:compress` option to indicate a threshold under which cache entries should not be compressed. This defaults to 16 kilobytes.
* `:expires_in` - This option sets an expiration time in seconds for the cache entry when it will be automatically removed from the cache.
@@ -223,7 +227,7 @@ There are some common options used by all cache implementations. These can be pa
### 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.
+This cache store keeps entries in memory in the same Ruby process. The cache store has a bounded size specified by the `:size` option 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.
```ruby
config.cache_store = :memory_store, { size: 64.megabytes }
@@ -239,7 +243,7 @@ This cache store uses the file system to store entries. The path to the director
config.cache_store = :file_store, "/path/to/cache/directory"
```
-With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts.
+With this cache store, multiple server processes on the same host can share a cache. Server processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts.
Note that the cache will grow until the disk is full unless you periodically clear out old entries.
@@ -251,7 +255,7 @@ This cache store uses Danga's `memcached` server to provide a centralized cache
When initializing the cache, you need to specify the addresses for all memcached servers in your cluster. If none is specified, it will assume memcached is running on the local host on the default port, but this is not an ideal set up for larger sites.
-The `write` and `fetch` methods on this cache accept two additional options that take advantage of features specific to memcached. You can specify `:raw` to send a value directly to the server with no serialization. The value must be a string or number. You can use memcached direct operation like `increment` and `decrement` only on raw values. You can also specify `:unless_exist` if you don't want memcached to overwrite an existing entry.
+The `write` and `fetch` methods on this cache accept two additional options that take advantage of features specific to memcached. You can specify `:raw` to send a value directly to the server with no serialization. The value must be a string or number. You can use memcached direct operations like `increment` and `decrement` only on raw values. You can also specify `:unless_exist` if you don't want memcached to overwrite an existing entry.
```ruby
config.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"
@@ -289,7 +293,7 @@ For more information about Ehcache for JRuby and Rails, see [http://ehcache.org/
### 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.
+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.
```ruby
config.cache_store = :null_store
@@ -299,7 +303,7 @@ config.cache_store = :null_store
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.
-To use a custom cache store, simple set the cache store to a new instance of the class.
+To use a custom cache store, simply set the cache store to a new instance of the class.
```ruby
config.cache_store = MyCacheStore.new
@@ -307,7 +311,7 @@ config.cache_store = MyCacheStore.new
### 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.
+The keys used in a cache can be any object that responds to either `:cache_key` or `: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.
You can use Hashes and Arrays of values as cache keys.
@@ -349,7 +353,7 @@ class ProductsController < ApplicationController
end
```
-Instead of an options hash, you can also simply pass in a model, Rails will use the `updated_at` and `cache_key` methods for setting `last_modified` and `etag`:
+Instead of an options hash, you can also simply pass in a model. Rails will use the `updated_at` and `cache_key` methods for setting `last_modified` and `etag`:
```ruby
class ProductsController < ApplicationController
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index 7567a38aef..0f5a9e4e39 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
The Rails Command Line
======================
@@ -64,10 +64,10 @@ $ cd commandsapp
$ bin/rails server
=> Booting WEBrick
=> Rails 5.0.0 application starting in development on http://localhost:3000
-=> Call with -d to detach
+=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2013-08-07 02:00:01] INFO WEBrick 1.3.1
-[2013-08-07 02:00:01] INFO ruby 2.0.0 (2013-06-27) [x86_64-darwin11.2.0]
+[2013-08-07 02:00:01] INFO ruby 2.2.2 (2015-06-27) [x86_64-darwin11.2.0]
[2013-08-07 02:00:01] INFO WEBrick::HTTPServer#start: pid=69680 port=3000
```
@@ -338,6 +338,12 @@ You can specify the environment in which the `runner` command should operate usi
$ bin/rails runner -e staging "Model.long_running_method"
```
+You can even execute ruby code written in a file with runner.
+
+```bash
+$ bin/rails runner lib/code_to_be_run.rb
+```
+
### `rails destroy`
Think of `destroy` as the opposite of `generate`. It'll figure out what generate did, and undo it.
@@ -396,8 +402,8 @@ INFO: You can also use `rake -T` to get the list of tasks.
$ bin/rake about
About your application's environment
Rails version 5.0.0
-Ruby version 2.2.0 (x86_64-linux)
-RubyGems version 2.4.5
+Ruby version 2.2.2 (x86_64-linux)
+RubyGems version 2.4.6
Rack version 1.6
JavaScript Runtime Node.js (V8)
Middleware Rack::Sendfile, ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::Head, Rack::ConditionalGet, Rack::ETag
@@ -417,15 +423,7 @@ If you want to clear `public/assets` completely, you can use `rake assets:clobbe
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.
-
-### `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.
-
-* `rake doc:app` generates documentation for your application in `doc/app`.
-* `rake doc:guides` generates Rails guides in `doc/guides`.
-* `rake doc:rails` generates API documentation for Rails in `doc/api`.
+More information about migrations can be found in the [Migrations](active_record_migrations.html) guide.
### `notes`
@@ -472,7 +470,7 @@ app/models/article.rb:
NOTE. When using specific annotations and custom annotations, the annotation name (FIXME, BUG etc) is not displayed in the output lines.
-By default, `rake notes` will look in the `app`, `config`, `lib`, `bin` and `test` directories. If you would like to search other directories, you can provide them as a comma separated list in an environment variable `SOURCE_ANNOTATION_DIRECTORIES`.
+By default, `rake notes` will look in the `app`, `config`, `db`, `lib` and `test` directories. If you would like to search other directories, you can provide them as a comma separated list in an environment variable `SOURCE_ANNOTATION_DIRECTORIES`.
```bash
$ export SOURCE_ANNOTATION_DIRECTORIES='spec,vendor'
@@ -528,8 +526,8 @@ end
To pass arguments to your custom rake task:
```ruby
-task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
- # You can use args from here
+task :task_name, [:arg_1] => [:prerequisite_1, :prerequisite_2] do |task, args|
+ argument_1 = args.arg_1
end
```
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 5baab8a4b5..bb6c395c96 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Configuring Rails Applications
==============================
@@ -88,8 +88,6 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
end
```
-* `config.dependency_loading` is a flag that allows you to disable constant autoloading setting it to false. It only has effect if `config.cache_classes` is true, which it is by default in production mode.
-
* `config.eager_load` when true, eager loads all registered `config.eager_load_namespaces`. This includes your application, engines, Rails frameworks and any other registered namespace.
* `config.eager_load_namespaces` registers namespaces that are eager loaded when `config.eager_load` is true. All namespaces in the list must respond to the `eager_load!` method.
@@ -110,9 +108,11 @@ numbers. New applications filter out passwords by adding the following `config.f
* `config.log_formatter` defines the formatter of the Rails logger. This option defaults to an instance of `ActiveSupport::Logger::SimpleFormatter` for all modes except production, where it defaults to `Logger::Formatter`.
-* `config.log_level` defines the verbosity of the Rails logger. This option defaults to `:debug` for all environments.
+* `config.log_level` defines the verbosity of the Rails logger. This option
+defaults to `:debug` for all environments. The available log levels are: `:debug`,
+`:info`, `:warn`, `:error`, `:fatal`, and `:unknown`.
-* `config.log_tags` accepts a list of methods that the `request` object responds to. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications.
+* `config.log_tags` accepts a list of: methods that the `request` object responds to, a `Proc` that accepts the `request` object, or something that responds to `to_s`. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications.
* `config.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to an instance of `ActiveSupport::Logger`.
@@ -161,8 +161,6 @@ pipeline is enabled. It is set to true by default.
* `config.assets.cache_store` defines the cache store that Sprockets will use. The default is the Rails file store.
-* `config.assets.version` is an option string that is used in MD5 hash generation. This can be changed to force all files to be recompiled.
-
* `config.assets.compile` is a boolean that can be used to turn on live Sprockets compilation in production.
* `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.
@@ -185,13 +183,15 @@ The full set of methods that can be used in this block are as follows:
* `helper` defines whether or not to generate helpers. Defaults to `true`.
* `integration_tool` defines which integration tool to use. Defaults to `nil`.
* `javascripts` turns on the hook for JavaScript files in generators. Used in Rails for when the `scaffold` generator is run. Defaults to `true`.
-* `javascript_engine` configures the engine to be used (for eg. coffee) when generating assets. Defaults to `nil`.
+* `javascript_engine` configures the engine to be used (for eg. coffee) when generating assets. Defaults to `:js`.
* `orm` defines which orm to use. Defaults to `false` and will use Active Record by default.
* `resource_controller` defines which generator to use for generating a controller when using `rails generate resource`. Defaults to `:controller`.
+* `resource_route` defines whether a resource route definition should be generated
+ or not. Defaults to `true`.
* `scaffold_controller` different from `resource_controller`, defines which generator to use for generating a _scaffolded_ controller when using `rails generate scaffold`. Defaults to `:scaffold_controller`.
* `stylesheets` turns on the hook for stylesheets in generators. Used in Rails for when the `scaffold` generator is run, but this hook can be used in other generates as well. Defaults to `true`.
* `stylesheet_engine` configures the stylesheet engine (for eg. sass) to be used when generating assets. Defaults to `:css`.
-* `test_framework` defines which test framework to use. Defaults to `false` and will use Test::Unit by default.
+* `test_framework` defines which test framework to use. Defaults to `false` and will use Minitest by default.
* `template_engine` defines which template engine to use, such as ERB or Haml. Defaults to `:erb`.
### Configuring Middleware
@@ -199,7 +199,7 @@ The full set of methods that can be used in this block are as follows:
Every Rails application comes with a standard set of middleware which it uses in this order in the development environment:
* `ActionDispatch::SSL` forces every request to be under HTTPS protocol. Will be available if `config.force_ssl` is set to `true`. Options passed to this can be configured by using `config.ssl_options`.
-* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.serve_static_files` is `false`.
+* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.serve_static_files` is `false`. Set `config.static_index` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.static_index` to `"main"`.
* `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time. Only enabled when `config.cache_classes` is `false`.
* `ActiveSupport::Cache::Strategy::LocalCache` serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
* `Rack::Runtime` sets an `X-Runtime` header, containing the time (in seconds) taken to execute the request.
@@ -286,7 +286,7 @@ All these configuration options are delegated to the `I18n` library.
* `config.active_record.lock_optimistically` controls whether Active Record will use optimistic locking and is true by default.
-* `config.active_record.cache_timestamp_format` controls the format of the timestamp value in the cache key. Default is `:number`.
+* `config.active_record.cache_timestamp_format` controls the format of the timestamp value in the cache key. Default is `:nsec`.
* `config.active_record.record_timestamps` is a boolean value which controls whether or not timestamping of `create` and `update` operations on a model occur. The default value is `true`.
@@ -300,6 +300,18 @@ All these configuration options are delegated to the `I18n` library.
`config/environments/production.rb` which is generated by Rails. The
default value is true if this configuration is not set.
+* `config.active_record.dump_schemas` controls which database schemas will be dumped when calling db:structure:dump.
+ The options are `:schema_search_path` (the default) which dumps any schemas listed in schema_search_path,
+ `:all` which always dumps all schemas regardless of the schema_search_path,
+ or a string of comma separated schemas.
+
+* `config.active_record.belongs_to_required_by_default` is a boolean value and controls whether `belongs_to` association is required by default.
+
+* `config.active_record.warn_on_records_fetched_greater_than` allows setting a
+ warning threshold for query result size. If the number of records returned
+ by a query exceeds the threshold, a warning is logged. This can be used to
+ identify queries which might be causing memory bloat.
+
The MySQL adapter adds one additional configuration option:
* `ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns in a MySQL database to be booleans and is true by default.
@@ -410,13 +422,23 @@ encrypted cookies salt value. Defaults to `'signed encrypted cookie'`.
end
```
-* `config.action_view.default_form_builder` tells Rails which form builder to use by default. The default is `ActionView::Helpers::FormBuilder`. If you want your form builder class to be loaded after initialization (so it's reloaded on each request in development), you can pass it as a `String`
+* `config.action_view.default_form_builder` tells Rails which form builder to
+ use by default. The default is `ActionView::Helpers::FormBuilder`. If you
+ want your form builder class to be loaded after initialization (so it's
+ reloaded on each request in development), you can pass it as a `String`.
* `config.action_view.logger` accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action View. Set to `nil` to disable logging.
* `config.action_view.erb_trim_mode` gives the trim mode to be used by ERB. It defaults to `'-'`, which turns on trimming of tail spaces and newline when using `<%= -%>` or `<%= =%>`. See the [Erubis documentation](http://www.kuwata-lab.com/erubis/users-guide.06.html#topics-trimspaces) for more information.
-* `config.action_view.embed_authenticity_token_in_remote_forms` allows you to set the default behavior for `authenticity_token` in forms with `:remote => true`. By default it's set to false, which means that remote forms will not include `authenticity_token`, which is helpful when you're fragment-caching the form. Remote forms get the authenticity from the `meta` tag, so embedding is unnecessary unless you support browsers without JavaScript. In such case you can either pass `:authenticity_token => true` as a form option or set this config setting to `true`
+* `config.action_view.embed_authenticity_token_in_remote_forms` allows you to
+ set the default behavior for `authenticity_token` in forms with `remote:
+ true`. By default it's set to false, which means that remote forms will not
+ include `authenticity_token`, which is helpful when you're fragment-caching
+ the form. Remote forms get the authenticity from the `meta` tag, so embedding
+ is unnecessary unless you support browsers without JavaScript. In such case
+ you can either pass `authenticity_token: true` as a form option or set this
+ config setting to `true`.
* `config.action_view.prefix_partial_path_with_controller_namespace` determines whether or not partials are looked up from a subdirectory in templates rendered from namespaced controllers. For example, consider a controller named `Admin::ArticlesController` which renders this template:
@@ -426,7 +448,8 @@ encrypted cookies salt value. Defaults to `'signed encrypted cookie'`.
The default setting is `true`, which uses the partial at `/admin/articles/_article.erb`. Setting the value to `false` would render `/articles/_article.erb`, which is the same behavior as rendering from a non-namespaced controller such as `ArticlesController`.
-* `config.action_view.raise_on_missing_translations` determines whether an error should be raised for missing translations
+* `config.action_view.raise_on_missing_translations` determines whether an
+ error should be raised for missing translations.
### Configuring Action Mailer
@@ -493,15 +516,18 @@ There are a number of settings available on `config.action_mailer`:
config.action_mailer.show_previews = false
```
+* `config.action_mailer.deliver_later_queue_name` specifies the queue name for
+ mailers. By default this is `mailers`.
+
### Configuring Active Support
There are a few configuration options available in Active Support:
* `config.active_support.bare` enables or disables the loading of `active_support/all` when booting Rails. Defaults to `nil`, which means `active_support/all` is loaded.
-* `config.active_support.test_order` sets the order that test cases are executed. Possible values are `:sorted` and `:random`. Currently defaults to `:sorted`. In Rails 5.0, the default will be changed to `:random` instead.
+* `config.active_support.test_order` sets the order that test cases are executed. Possible values are `:random` and `:sorted`. This option is set to `:random` in `config/environments/test.rb` in newly-generated applications. If you have an application that does not specify a `test_order`, it will default to `:sorted`, *until* Rails 5.0, when the default will become `:random`.
-* `config.active_support.escape_html_entities_in_json` enables or disables the escaping of HTML entities in JSON serialization. Defaults to `false`.
+* `config.active_support.escape_html_entities_in_json` enables or disables the escaping of HTML entities in JSON serialization. Defaults to `true`.
* `config.active_support.use_standard_json_time_format` enables or disables serializing dates to ISO 8601 format. Defaults to `true`.
@@ -519,6 +545,58 @@ There are a few configuration options available in Active Support:
* `ActiveSupport::Deprecation.silenced` sets whether or not to display deprecation warnings.
+### Configuring Active Job
+
+`config.active_job` provides the following configuration options:
+
+* `config.active_job.queue_adapter` sets the adapter for the queueing backend. The default adapter is `:inline` which will perform jobs immediately. For an up-to-date list of built-in adapters see the [ActiveJob::QueueAdapters API documentation](http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html).
+
+ ```ruby
+ # Be sure to have the adapter's gem in your Gemfile
+ # and follow the adapter's specific installation
+ # and deployment instructions.
+ config.active_job.queue_adapter = :sidekiq
+ ```
+
+* `config.active_job.default_queue_name` can be used to change the default queue name. By default this is `"default"`.
+
+ ```ruby
+ config.active_job.default_queue_name = :medium_priority
+ ```
+
+* `config.active_job.queue_name_prefix` allows you to set an optional, non-blank, queue name prefix for all jobs. By default it is blank and not used.
+
+ The following configuration would queue the given job on the `production_high_priority` queue when run in production:
+
+ ```ruby
+ config.active_job.queue_name_prefix = Rails.env
+ ```
+
+ ```ruby
+ class GuestsCleanupJob < ActiveJob::Base
+ queue_as :high_priority
+ #....
+ end
+ ```
+
+* `config.active_job.queue_name_delimiter` has a default value of `'_'`. If `queue_name_prefix` is set, then `queue_name_delimiter` joins the prefix and the non-prefixed queue name.
+
+ The following configuration would queue the provided job on the `video_server.low_priority` queue:
+
+ ```ruby
+ # prefix must be set for delimiter to be used
+ config.active_job.queue_name_prefix = 'video_server'
+ config.active_job.queue_name_delimiter = '.'
+ ```
+
+ ```ruby
+ class EncoderJob < ActiveJob::Base
+ queue_as :low_priority
+ #....
+ end
+ ```
+
+* `config.active_job.logger` accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Active Job. You can retrieve this logger by calling `logger` on either an Active Job class or an Active Job instance. Set to `nil` to disable logging.
### Configuring a Database
@@ -692,7 +770,7 @@ development:
pool: 5
```
-Prepared Statements are enabled by default on PostgreSQL. You can be disable prepared statements by setting `prepared_statements` to `false`:
+Prepared Statements are enabled by default on PostgreSQL. You can disable prepared statements by setting `prepared_statements` to `false`:
```yaml
production:
@@ -817,15 +895,6 @@ server {
Be sure to read the [NGINX documentation](http://nginx.org/en/docs/) for the most up-to-date information.
-#### Considerations when deploying to a subdirectory
-
-Deploying to a subdirectory in production has implications on various parts of
-Rails.
-
-* development environment:
-* testing environment:
-* serving static assets:
-* asset pipeline:
Rails Environment Settings
--------------------------
@@ -955,6 +1024,11 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `active_record.set_dispatch_hooks` Resets all reloadable connections to the database if `config.cache_classes` is set to `false`.
+* `active_job.logger` Sets `ActiveJob::Base.logger` - if it's not already set -
+ to `Rails.logger`.
+
+* `active_job.set_configs` Sets up Active Job by using the settings in `config.active_job` by `send`'ing the method names as setters to `ActiveJob::Base` and passing the values through.
+
* `action_mailer.logger` Sets `ActionMailer::Base.logger` - if it's not already set - to `Rails.logger`.
* `action_mailer.set_configs` Sets up Action Mailer by using the settings in `config.action_mailer` by `send`'ing the method names as setters to `ActionMailer::Base` and passing the values through.
@@ -973,8 +1047,6 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `load_environment_config` Loads the `config/environments` file for the current environment.
-* `append_asset_paths` Finds asset paths for the application and all attached railties and keeps a track of the available directories in `config.static_asset_paths`.
-
* `prepend_helpers_path` Adds the directory `app/helpers` from the application, railties and engines to the lookup path for helpers for the application.
* `load_config_initializers` Loads all Ruby files from `config/initializers` in the application, railties and engines. The files in this directory can be used to hold configuration settings that should be made after all of the frameworks are loaded.
@@ -1049,3 +1121,23 @@ These configuration points are then available through the configuration object:
Rails.configuration.x.super_debugger # => true
Rails.configuration.x.super_debugger.not_set # => nil
```
+
+Search Engines Indexing
+-----------------------
+
+Sometimes, you may want to prevent some pages of your application to be visible
+on search sites like Google, Bing, Yahoo or Duck Duck Go. The robots that index
+these sites will first analyze the `http://your-site.com/robots.txt` file to
+know which pages it is allowed to index.
+
+Rails creates this file for you inside the `/public` folder. By default, it allows
+search engines to index all pages of your application. If you want to block
+indexing on all pages of you application, use this:
+
+```
+User-agent: *
+Disallow: /
+```
+
+To block just specific pages, it's necessary to use a more complex syntax. Learn
+it on the [official documentation](http://www.robotstxt.org/robotstxt.html).
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index db3f19f8ac..3279c99c42 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Contributing to Ruby on Rails
=============================
@@ -26,21 +26,25 @@ NOTE: Bugs in the most recent released version of Ruby on Rails are likely to ge
### 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 has already been reported. If you are unable to find any open GitHub issues addressing the problem you found, your next step will be to [open a new one](https://github.com/rails/rails/issues/new). (See the next section for reporting security issues.)
+If you've found a problem in Ruby on Rails which is not a security risk, do a search on GitHub under [Issues](https://github.com/rails/rails/issues) in case it has already been reported. If you are unable to find any open GitHub issues addressing the problem you found, your next step will be to [open a new one](https://github.com/rails/rails/issues/new). (See the next section for reporting security issues.)
Your issue report should contain a title and a clear description of the issue at the bare minimum. You should include as much relevant information as possible and should at least post a code sample that demonstrates the issue. It would be even better if you could include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
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.
-### Create a Self-Contained gist for Active Record and Action Controller Issues
+### Create an Executable Test Case
-If you are filing a bug report, please use
-[Active Record template for gems](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_gem.rb) or
-[Action Controller template for gems](https://github.com/rails/rails/blob/master/guides/bug_report_templates/action_controller_gem.rb)
-if the bug is found in a published gem, and
-[Active Record template for master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_master.rb) or
-[Action Controller template for master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/action_controller_master.rb)
-if the bug happens in the master branch.
+Having a way to reproduce your issue will be very helpful for others to help confirm, investigate and ultimately fix your issue. You can do this by providing an executable test case. To make this process easier, we have prepared several bug report templates for you to use as a starting point:
+
+* Template for Active Record (models, database) issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_master.rb)
+* Template for Action Pack (controllers, routing) issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/action_controller_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/action_controller_master.rb)
+* Generic template for other issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/generic_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/generic_master.rb)
+
+These templates include the boilerplate code to set up a test case against either a released version of Rails (`*_gem.rb`) or edge Rails (`*_master.rb`).
+
+Simply copy the content of the appropriate template into a `.rb` file and make the necessary changes to demonstrate the issue. You can execute it by running `ruby the_file.rb` in your terminal. If all goes well, you should see your test case failing.
+
+You can then share your executable test case as a [gist](https://gist.github.com), or simply paste the content into the issue description.
### Special Treatment for Security Issues
@@ -62,7 +66,7 @@ the core team will have to make a judgement call. That said, the distinction
generally just affects which release your patch will get in to; we love feature
submissions! They just won't get backported to maintenance branches.
-If you'd like feedback on an idea for a feature before doing the work for make
+If you'd like feedback on an idea for a feature before doing the work to 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
@@ -75,17 +79,17 @@ discussions new features require.
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:
+As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the [issues list](https://github.com/rails/rails/issues) in GitHub Issues, you'll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:
### 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.
-If something is very vague, can you help squash it down into something specific? Maybe you can provide additional information to help reproduce a bug, or help by eliminating needless steps that aren't required to demonstrate the problem.
+If an issue is very vague, can you help narrow it down to something more specific? Maybe you can provide additional information to help reproduce a bug, or help by eliminating needless steps that aren't required to demonstrate the problem.
If you find a bug report without a test, it's very useful to contribute a failing test. This is also a great way to get started exploring the source code: looking at the existing test files will teach you how to write more tests. New tests are best contributed in the form of a patch, as explained later on in the "Contributing to the Rails Code" section.
-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.
+Anything you can do to make bug reports more succinct or easier to reproduce helps folks trying to write code to fix those bugs - whether you end up writing the code yourself or not.
### Testing Patches
@@ -113,7 +117,7 @@ Once you're happy that the pull request contains a good change, comment on the G
>I like the way you've restructured that code in generate_finder_sql - much nicer. The tests look good too.
-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.
+If your comment simply reads "+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.
Contributing to the Rails Documentation
---------------------------------------
@@ -173,6 +177,14 @@ $ 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.
+### Bundle install
+
+Install the required gems.
+
+```bash
+$ bundle install
+```
+
### Running an Application Against Your Local Branch
In case you need a dummy Rails app to test changes, the `--dev` flag of `rails new` generates an application that uses your local branch:
@@ -236,11 +248,11 @@ This will generate a report with the following information:
```
Calculating -------------------------------------
- addition 69114 i/100ms
- addition with send 64062 i/100ms
+ addition 132.013k i/100ms
+ addition with send 125.413k i/100ms
-------------------------------------------------
- addition 5307644.4 (±3.5%) i/s - 26539776 in 5.007219s
- addition with send 3702897.9 (±3.5%) i/s - 18513918 in 5.006723s
+ addition 9.677M (± 1.7%) i/s - 48.449M
+ addition with send 6.794M (± 1.1%) i/s - 33.987M
```
Please see the benchmark/ips [README](https://github.com/evanphx/benchmark-ips/blob/master/README.md) for more information.
@@ -347,9 +359,9 @@ $ RUBYOPT=-W0 bundle exec rake test
The CHANGELOG is an important part of every release. It keeps the list of changes for every Rails version.
-You should add an entry to the CHANGELOG of the framework that you modified if you're adding or removing a feature, committing a bug fix or adding deprecation notices. Refactorings and documentation changes generally should not go to the CHANGELOG.
+You should add an entry **to the top** of the CHANGELOG of the framework that you modified if you're adding or removing a feature, committing a bug fix or adding deprecation notices. Refactorings and documentation changes generally should not go to the CHANGELOG.
-A CHANGELOG entry should summarize what was changed and should end with author's name and it should go on top of a CHANGELOG. You can use multiple lines if you need more space and you can attach code examples indented with 4 spaces. If a change is related to a specific issue, you should attach the issue's number. Here is an example CHANGELOG entry:
+A CHANGELOG entry should summarize what was changed and should end with the author's name. You can use multiple lines if you need more space and you can attach code examples indented with 4 spaces. If a change is related to a specific issue, you should attach the issue's number. Here is an example CHANGELOG entry:
```
* Summary of a change that briefly describes what was changed. You can use multiple
@@ -366,7 +378,12 @@ A CHANGELOG entry should summarize what was changed and should end with author's
*Your Name*
```
-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.
+Your name can be added directly after the last word if there are no code
+examples or multiple paragraphs. Otherwise, it's best to make a new paragraph.
+
+### Updating the Gemfile.lock
+
+Some changes require the dependencies to be upgraded. In these cases make sure you run `bundle update` to get the right version of the dependency and commit the `Gemfile.lock` file within your changes.
### Sanity Check
@@ -386,21 +403,27 @@ When you're happy with the code on your computer, you need to commit the changes
$ git commit -a
```
-At this point, your editor should be fired up and you can write a message for this commit. Well formatted and descriptive commit messages are extremely helpful for the others, especially when figuring out why given change was made, so please take the time to write it.
+This should fire up your editor to write a commit message. When you have
+finished, save and close to continue.
+
+A well-formatted and descriptive commit message is very helpful to others for
+understanding why the change was made, so please take the time to write it.
-Good commit message should be formatted according to the following example:
+A good commit message looks like this:
```
Short summary (ideally 50 characters or less)
-More detailed description, if necessary. It should be wrapped to 72
-characters. Try to be as descriptive as you can, even if you think that
-the commit content is obvious, it may not be obvious to others. You
-should add such description also if it's already present in bug tracker,
-it should not be necessary to visit a webpage to check the history.
+More detailed description, if necessary. It should be wrapped to
+72 characters. Try to be as descriptive as you can. Even if you
+think that the commit content is obvious, it may not be obvious
+to others. Add any description that is already present in the
+relevant issues; it should not be necessary to visit a webpage
+to check the history.
+
+The description section can have multiple paragraphs.
-Description can have multiple paragraphs and you can use code examples
-inside, just indent it with 4 spaces:
+Code examples can be embedded by indenting them with 4 spaces:
class ArticlesController
def index
@@ -410,13 +433,15 @@ inside, just indent it with 4 spaces:
You can also add bullet points:
-- you can use dashes or asterisks
+- make a bullet point by starting a line with either a dash (-)
+ or an asterisk (*)
-- also, try to indent next line of a point for readability, if it's too
- long to fit in 72 characters
+- wrap lines at 72 characters, and indent any additional lines
+ with 2 spaces for readability
```
-TIP. Please squash your commits into a single commit when appropriate. This simplifies future cherry picks, and also keeps the git log clean.
+TIP. Please squash your commits into a single commit when appropriate. This
+simplifies future cherry picks and keeps the git log clean.
### Update Your Branch
@@ -507,7 +532,7 @@ pull request". The Rails core team will be notified about your submission.
Most pull requests will go through a few iterations before they get merged.
Different contributors will sometimes have different opinions, and often
-patches will need revised before they can get merged.
+patches will need to be revised before they can get merged.
Some contributors to Rails have email notifications from GitHub turned on, but
others do not. Furthermore, (almost) everyone who works on Rails is a
@@ -554,8 +579,7 @@ following:
```bash
$ git fetch upstream
$ git checkout my_pull_request
-$ git rebase upstream/master
-$ git rebase -i
+$ git rebase -i upstream/master
< Choose 'squash' for all of your commits except the first one. >
< Edit the commit message to make sense, and describe all your changes. >
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index cef9ac083b..dc1df8f229 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Debugging Rails Applications
============================
@@ -17,7 +17,7 @@ After reading this guide, you will know:
View Helpers for Debugging
--------------------------
-One common task is to inspect the contents of a variable. In Rails, you can do this with three methods:
+One common task is to inspect the contents of a variable. Rails provides three different ways to do this:
* `debug`
* `to_yaml`
@@ -54,7 +54,7 @@ Title: Rails debugging guide
### `to_yaml`
-Displaying an instance variable, or any other object or method, in YAML format can be achieved this way:
+Alternatively, calling `to_yaml` on any object converts it to YAML. You can pass this converted object into the `simple_format` helper method to format the output. This is how `debug` does its magic.
```html+erb
<%= simple_format @article.to_yaml %>
@@ -64,9 +64,7 @@ Displaying an instance variable, or any other object or method, in YAML format c
</p>
```
-The `to_yaml` method converts the method to YAML format leaving it more readable, and then the `simple_format` helper is used to render each line as in the console. This is how `debug` method does its magic.
-
-As a result of this, you will have something like this in your view:
+The above code will render something like this:
```yaml
--- !ruby/object Article
@@ -94,7 +92,7 @@ Another useful method for displaying object values is `inspect`, especially when
</p>
```
-Will be rendered as follows:
+Will render:
```
[1, 2, 3, 4, 5]
@@ -109,9 +107,9 @@ It can also be useful to save information to log files at runtime. Rails maintai
### What is the Logger?
-Rails makes use of the `ActiveSupport::Logger` class to write log information. You can also substitute another logger such as `Log4r` if you wish.
+Rails makes use of the `ActiveSupport::Logger` class to write log information. Other loggers, such as `Log4r`, may also be substituted.
-You can specify an alternative logger in your `environment.rb` or any environment file:
+You can specify an alternative logger in `environment.rb` or any other environment file, for example:
```ruby
Rails.logger = Logger.new(STDOUT)
@@ -129,16 +127,21 @@ TIP: By default, each log is created under `Rails.root/log/` and the log file is
### 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.
+When something is logged, it's printed into the corresponding log if the log
+level of the message is equal to or higher than the configured log level. If you
+want to know the current log level, you can call the `Rails.logger.level`
+method.
-The available log levels are: `:debug`, `:info`, `:warn`, `:error`, `:fatal`, and `:unknown`, corresponding to the log level numbers from 0 up to 5 respectively. To change the default log level, use
+The available log levels are: `:debug`, `:info`, `:warn`, `:error`, `:fatal`,
+and `:unknown`, corresponding to the log level numbers from 0 up to 5,
+respectively. To change the default log level, use
```ruby
config.log_level = :warn # In any environment initializer, or
Rails.logger.level = 0 # at any time
```
-This is useful when you want to log under development or staging, but you don't want to flood your production log with unnecessary information.
+This is useful when you want to log under development or staging without flooding your production log with unnecessary information.
TIP: The default Rails log level is `debug` in all environments.
@@ -202,7 +205,7 @@ Adding extra logging like this makes it easy to search for unexpected or unusual
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.
+in Active Support helps you do exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such applications.
```ruby
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
@@ -212,34 +215,33 @@ logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "
```
### Impact of Logs on Performance
-Logging will always have a small impact on performance of your rails app,
- particularly when logging to disk. However, there are a few subtleties:
+Logging will always have a small impact on the performance of your Rails app,
+ particularly when logging to disk. Additionally, there are a few subtleties:
Using the `:debug` level will have a greater performance penalty than `:fatal`,
as a far greater number of strings are being evaluated and written to the
log output (e.g. disk).
-Another potential pitfall is that if you have many calls to `Logger` like this
- in your code:
+Another potential pitfall is too many calls to `Logger` in your code:
```ruby
logger.debug "Person attributes hash: #{@person.attributes.inspect}"
```
-In the above example, There will be a performance impact even if the allowed
+In the above example, there will be a performance impact even if the allowed
output level doesn't include debug. The reason is that Ruby has to evaluate
these strings, which includes instantiating the somewhat heavy `String` object
-and interpolating the variables, and which takes time.
+and interpolating the variables.
Therefore, it's recommended to pass blocks to the logger methods, as these are
-only evaluated if the output level is the same or included in the allowed level
+only evaluated if the output level is the same as — or included in — the allowed level
(i.e. lazy loading). The same code rewritten would be:
```ruby
logger.debug {"Person attributes hash: #{@person.attributes.inspect}"}
```
-The contents of the block, and therefore the string interpolation, is only
-evaluated if debug is enabled. This performance savings is only really
+The contents of the block, and therefore the string interpolation, are only
+evaluated if debug is enabled. This performance savings are only really
noticeable with large amounts of logging, but it's a good practice to employ.
Debugging with the `byebug` gem
@@ -253,8 +255,7 @@ 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.
+use this guide to learn how to move from the code you have written into the underlying Rails code.
### Setup
@@ -285,7 +286,7 @@ As soon as your application calls the `byebug` 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 `(byebug)`.
Before the prompt, the code around the line that is about to be run will be
-displayed and the current line will be marked by '=>'. Like this:
+displayed and the current line will be marked by '=>', like this:
```
[1, 10] in /PathTo/project/app/controllers/articles_controller.rb
@@ -316,7 +317,7 @@ For example:
=> Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option)
=> Ctrl-C to shutdown server
[2014-04-11 13:11:47] INFO WEBrick 1.3.1
-[2014-04-11 13:11:47] INFO ruby 2.1.1 (2014-02-24) [i686-linux]
+[2014-04-11 13:11:47] INFO ruby 2.2.2 (2015-04-13) [i686-linux]
[2014-04-11 13:11:47] INFO WEBrick::HTTPServer#start: pid=6370 port=3000
@@ -339,7 +340,7 @@ Processing by ArticlesController#index as HTML
(byebug)
```
-Now it's time to explore and dig into your application. A good place to start is
+Now it's time to explore your application. A good place to start is
by asking the debugger for help. Type: `help`
```
@@ -360,9 +361,9 @@ continue edit frame kill pp reload skip undisplay
TIP: To view the help menu for any command use `help <command-name>` at the
debugger prompt. For example: _`help list`_. You can abbreviate any debugging
command by supplying just enough letters to distinguish them from other
-commands, so you can also use `l` for the `list` command, for example.
+commands. For example, you can use `l` for the `list` command.
-To see the previous ten lines you should type `list-` (or `l-`)
+To see the previous ten lines you should type `list-` (or `l-`).
```
(byebug) l-
@@ -381,7 +382,7 @@ To see the previous ten lines you should type `list-` (or `l-`)
```
-This way you can move inside the file, being able to see the code above and over
+This way you can move inside the file and see the code above
the line where you added the `byebug` call. Finally, to see where you are in
the code again you can type `list=`
@@ -411,8 +412,7 @@ contexts as you go through the different parts of the stack.
The debugger creates a context when a stopping point or an event is reached. The
context has information about the suspended program which enables the debugger
to inspect the frame stack, evaluate variables from the perspective of the
-debugged program, and contains information about the place where the debugged
-program is stopped.
+debugged program, and know the place where the debugged program is stopped.
At any time you can call the `backtrace` command (or its alias `where`) to print
the backtrace of the application. This can be very helpful to know how you got
@@ -476,9 +476,8 @@ character and the number indicates the current thread of execution.
* `thread resume _n_` resumes thread _n_.
* `thread switch _n_` switches the current thread context to _n_.
-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.
+This command is very helpful when you are debugging concurrent threads and need
+to verify that there are no race conditions in your code.
### Inspecting Variables
@@ -532,19 +531,22 @@ command later in this guide).
And then ask again for the instance_variables:
```
-(byebug) instance_variables.include? "@articles"
-true
+(byebug) instance_variables
+[:@_action_has_layout, :@_routes, :@_headers, :@_status, :@_request,
+ :@_response, :@_env, :@_prefixes, :@_lookup_context, :@_action_name,
+ :@_response_body, :@marked_for_same_origin_verification, :@_config,
+ :@articles]
```
Now `@articles` is included in the instance variables, because the line defining it
was executed.
TIP: You can also step into **irb** mode with the command `irb` (of course!).
-This way an irb session will be started within the context you invoked it. But
+This will start an irb session within the context you invoked it. But
be warned: this is an experimental feature.
The `var` method is the most convenient way to show variables and their values.
-Let's let `byebug` to help us with it.
+Let's have `byebug` help us with it.
```
(byebug) help var
@@ -556,7 +558,7 @@ v[ar] l[ocal] show local variables
```
This is a great way to inspect the values of the current context variables. For
-example, to check that we have no local variables currently defined.
+example, to check that we have no local variables currently defined:
```
(byebug) var local
@@ -587,14 +589,14 @@ tracking the values of a variable while the execution goes on.
1: @articles = nil
```
-The variables inside the displaying list will be printed with their values after
+The variables inside the displayed 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).
### 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
+available variables. But let's continue and move on with the application
execution.
Use `step` (abbreviated `s`) to continue running your program until the next
@@ -651,8 +653,8 @@ Next went up a frame because previous frame finished
(byebug)
```
-If we use `step` in the same situation, we will literally go the next ruby
-instruction to be executed. In this case, the activesupport's `week` method.
+If we use `step` in the same situation, we will literally go to the next Ruby
+instruction to be executed. In this case, Active Support's `week` method.
```
(byebug) step
@@ -672,8 +674,7 @@ instruction to be executed. In this case, the activesupport's `week` method.
(byebug)
```
-This is one of the best ways to find bugs in your code, or perhaps in Ruby on
-Rails.
+This is one of the best ways to find bugs in your code.
### Breakpoints
@@ -780,12 +781,12 @@ will be stopped and you will have to start it again.
### Settings
-`byebug` has a few available options to tweak its behaviour:
+`byebug` has a few available options to tweak its behavior:
-* `set autoreload`: Reload source code when changed (default: true).
-* `set autolist`: Execute `list` command on every breakpoint (default: true).
+* `set autoreload`: Reload source code when changed (defaults: true).
+* `set autolist`: Execute `list` command on every breakpoint (defaults: true).
* `set listsize _n_`: Set number of source lines to list by default to _n_
-(default: 10)
+(defaults: 10)
* `set forcestep`: Make sure the `next` and `step` commands always move to a new
line.
@@ -800,10 +801,67 @@ set forcestep
set listsize 25
```
+Debugging with the `web-console` gem
+------------------------------------
+
+Web Console is a bit like `byebug`, but it runs in the browser. In any page you
+are developing, you can request a console in the context of a view or a
+controller. The console would be rendered next to your HTML content.
+
+### Console
+
+Inside any controller action or view, you can invoke the console by
+calling the `console` method.
+
+For example, in a controller:
+
+```ruby
+class PostsController < ApplicationController
+ def new
+ console
+ @post = Post.new
+ end
+end
+```
+
+Or in a view:
+
+```html+erb
+<% console %>
+
+<h2>New Post</h2>
+```
+
+This will render a console inside your view. You don't need to care about the
+location of the `console` call; it won't be rendered on the spot of its
+invocation but next to your HTML content.
+
+The console executes pure Ruby code: You can define and instantiate
+custom classes, create new models and inspect variables.
+
+NOTE: Only one console can be rendered per request. Otherwise `web-console`
+will raise an error on the second `console` invocation.
+
+### Inspecting Variables
+
+You can invoke `instance_variables` to list all the instance variables
+available in your context. If you want to list all the local variables, you can
+do that with `local_variables`.
+
+### Settings
+
+* `config.web_console.whitelisted_ips`: Authorized list of IPv4 or IPv6
+addresses and networks (defaults: `127.0.0.1/8, ::1`).
+* `config.web_console.whiny_requests`: Log a message when a console rendering
+is prevented (defaults: `true`).
+
+Since `web-console` evaluates plain Ruby code remotely on the server, don't try
+to use it in production.
+
Debugging Memory Leaks
----------------------
-A Ruby application (on Rails or not), can leak memory - either in the Ruby code
+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 tool
@@ -832,9 +890,9 @@ application. Here is a list of useful plugins for debugging:
* [Footnotes](https://github.com/josevalim/rails-footnotes) Every Rails page has
footnotes that give request information and link back to your source via
TextMate.
-* [Query Trace](https://github.com/ntalbott/query_trace/tree/master) Adds query
+* [Query Trace](https://github.com/ruckus/active-record-query-trace/tree/master) Adds query
origin tracing to your logs.
-* [Query Reviewer](https://github.com/nesquena/query_reviewer) This rails plugin
+* [Query Reviewer](https://github.com/nesquena/query_reviewer) This Rails plugin
not only runs "EXPLAIN" before each of your select queries in development, but
provides a small DIV in the rendered output of each page with the summary of
warnings for each query that it analyzed.
@@ -846,7 +904,7 @@ standard Rails error page with a new one containing more contextual information,
like source code and variable inspection.
* [RailsPanel](https://github.com/dejan/rails_panel) Chrome extension for Rails
development that will end your tailing of development.log. Have all information
-about your Rails app requests in the browser - in the Developer Tools panel.
+about your Rails app requests in the browser — in the Developer Tools panel.
Provides insight to db/rendering/total times, parameter list, rendered views and
more.
@@ -856,6 +914,7 @@ References
* [ruby-debug Homepage](http://bashdb.sourceforge.net/ruby-debug/home-page.html)
* [debugger Homepage](https://github.com/cldwalker/debugger)
* [byebug Homepage](https://github.com/deivid-rodriguez/byebug)
+* [web-console Homepage](https://github.com/rails/web-console)
* [Article: Debugging a Rails application with ruby-debug](http://www.sitepoint.com/debug-rails-app-ruby-debug/)
* [Ryan Bates' debugging ruby (revised) screencast](http://railscasts.com/episodes/54-debugging-ruby-revised)
* [Ryan Bates' stack trace screencast](http://railscasts.com/episodes/24-the-stack-trace)
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 9eacc3a2fe..295e48f493 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Development Dependencies Install
================================
@@ -21,14 +21,14 @@ The easiest and recommended way to get a development environment ready to hack i
The Hard Way
------------
-In case you can't use the Rails development box, see section above, these are the steps to manually build a development box for Ruby on Rails core development.
+In case you can't use the Rails development box, see section below, these are the steps to manually build a development box for Ruby on Rails core development.
### 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:
* [Try Git course](http://try.github.io/) is an interactive course that will teach you the basics.
-* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git
+* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git.
* [Everyday Git](http://schacon.github.io/git/everyday.html) will teach you just enough about Git to get by.
* The [PeepCode screencast](https://peepcode.com/products/git) on Git is easier to follow.
* [GitHub](http://help.github.com) offers links to a variety of Git resources.
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 67032a31f5..9145aee009 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -11,7 +11,7 @@
-
name: Active Record Basics
url: active_record_basics.html
- description: This guide will get you started with models, persistence to database and the Active Record pattern and library.
+ description: This guide will get you started with models, persistence to database, and the Active Record pattern and library.
-
name: Active Record Migrations
url: active_record_migrations.html
@@ -19,7 +19,7 @@
-
name: Active Record Validations
url: active_record_validations.html
- description: This guide covers how you can use Active Record validations
+ description: This guide covers how you can use Active Record validations.
-
name: Active Record Callbacks
url: active_record_callbacks.html
@@ -33,7 +33,7 @@
url: active_record_querying.html
description: This guide covers the database query interface provided by Active Record.
-
- name: Active Model basics
+ name: Active Model Basics
url: active_model_basics.html
description: This guide covers the use of model classes without Active Record.
work_in_progress: true
@@ -74,7 +74,7 @@
-
name: Rails Internationalization API
url: i18n.html
- description: This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.
+ description: This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country, and so on.
-
name: Action Mailer Basics
url: action_mailer_basics.html
@@ -82,7 +82,7 @@
-
name: Active Job Basics
url: active_job_basics.html
- description: This guide provides you with all you need to get started in creating, enqueueing and executing background jobs.
+ description: This guide provides you with all you need to get started creating, enqueuing, and executing background jobs.
-
name: Testing Rails Applications
work_in_progress: true
@@ -116,7 +116,7 @@
name: The Rails Initialization Process
work_in_progress: true
url: initialization.html
- description: This guide explains the internals of the Rails initialization process as of Rails 4
+ description: This guide explains the internals of the Rails initialization process as of Rails 4.
-
name: Autoloading and Reloading Constants
url: autoloading_and_reloading_constants.html
diff --git a/guides/source/engines.md b/guides/source/engines.md
index 731178787f..3b1588b75a 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Getting Started with Engines
============================
@@ -368,7 +368,7 @@ called `Blorgh::ArticlesController` (at
`app/controllers/blorgh/articles_controller.rb`) and its related views at
`app/views/blorgh/articles`. This generator also generates a test for the
controller (`test/controllers/blorgh/articles_controller_test.rb`) and a helper
-(`app/helpers/blorgh/articles_controller.rb`).
+(`app/helpers/blorgh/articles_helper.rb`).
Everything this generator has created is neatly namespaced. The controller's
class is defined within the `Blorgh` module:
@@ -402,15 +402,6 @@ Finally, the assets for this resource are generated in two files:
`app/assets/stylesheets/blorgh/articles.css`. You'll see how to use these a little
later.
-By default, the scaffold styling is not applied to the engine because the
-engine's layout file, `app/views/layouts/blorgh/application.html.erb`, doesn't
-load it. To make the scaffold styling apply, insert this line into the `<head>`
-tag of this layout:
-
-```erb
-<%= stylesheet_link_tag "scaffold" %>
-```
-
You can see what the engine has so far by running `rake db:migrate` at the root
of our engine to run the migration generated by the scaffold generator, and then
running `rails server` in `test/dummy`. When you open
@@ -591,7 +582,7 @@ the comments, however, is not quite right yet. If you were to create a comment
right now, you would see this error:
```
-Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder],
+Missing partial blorgh/comments/_comment with {:handlers=>[:erb, :builder],
:formats=>[:html], :locale=>[:en, :en]}. Searched in: *
"/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" *
"/Users/ryan/Sites/side_projects/blorgh/app/views"
@@ -600,7 +591,7 @@ Missing partial blorgh/comments/comment with {:handlers=>[:erb, :builder],
The engine is unable to find the partial required for rendering the comments.
Rails looks first in the application's (`test/dummy`) `app/views` directory and
then in the engine's `app/views` directory. When it can't find it, it will throw
-this error. The engine knows to look for `blorgh/comments/comment` because the
+this error. The engine knows to look for `blorgh/comments/_comment` because the
model object it is receiving is from the `Blorgh::Comment` class.
This partial will be responsible for rendering just the comment text, for now.
@@ -698,8 +689,8 @@ haven't been copied over already. The first run for this command will output
something such as this:
```bash
-Copied migration [timestamp_1]_create_blorgh_articles.rb from blorgh
-Copied migration [timestamp_2]_create_blorgh_comments.rb from blorgh
+Copied migration [timestamp_1]_create_blorgh_articles.blorgh.rb from blorgh
+Copied migration [timestamp_2]_create_blorgh_comments.blorgh.rb from blorgh
```
The first timestamp (`[timestamp_1]`) will be the current time, and the second
@@ -831,11 +822,9 @@ Notice that only _one_ migration was copied over here. This is because the first
two migrations were copied over the first time this command was run.
```
-NOTE Migration [timestamp]_create_blorgh_articles.rb from blorgh has been
-skipped. Migration with the same name already exists. NOTE Migration
-[timestamp]_create_blorgh_comments.rb from blorgh has been skipped. Migration
-with the same name already exists. Copied migration
-[timestamp]_add_author_id_to_blorgh_articles.rb from blorgh
+NOTE Migration [timestamp]_create_blorgh_articles.blorgh.rb from blorgh has been skipped. Migration with the same name already exists.
+NOTE Migration [timestamp]_create_blorgh_comments.blorgh.rb from blorgh has been skipped. Migration with the same name already exists.
+Copied migration [timestamp]_add_author_id_to_blorgh_articles.blorgh.rb from blorgh
```
Run the migration using:
@@ -890,7 +879,9 @@ engine this would be done by changing
`app/controllers/blorgh/application_controller.rb` to look like:
```ruby
-class Blorgh::ApplicationController < ApplicationController
+module Blorgh
+ class ApplicationController < ::ApplicationController
+ end
end
```
@@ -1199,7 +1190,7 @@ end
```
```ruby
-# Blorgh/lib/concerns/models/article
+# Blorgh/lib/concerns/models/article.rb
module Blorgh::Concerns::Models::Article
extend ActiveSupport::Concern
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index a8dcd3ee4f..8f7d97844e 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Form Helpers
============
@@ -241,7 +241,7 @@ Upon form submission the value entered by the user will be stored in `params[:pe
WARNING: You must pass the name of an instance variable, i.e. `:person` or `"person"`, not an actual instance of your model object.
-Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the [Active Record Validations](./active_record_validations.html#displaying-validation-errors-in-views) guide.
+Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the [Active Record Validations](active_record_validations.html#displaying-validation-errors-in-views) guide.
### Binding a Form to an Object
@@ -275,14 +275,14 @@ There are a few things to note here:
The resulting HTML is:
```html
-<form accept-charset="UTF-8" action="/articles/create" method="post" class="nifty_form">
+<form accept-charset="UTF-8" action="/articles" method="post" class="nifty_form">
<input id="article_title" name="article[title]" type="text" />
<textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea>
<input name="commit" type="submit" value="Create" />
</form>
```
-The name passed to `form_for` controls the key used in `params` to access the form's values. Here the name is `article` and so all the inputs have names of the form `article[attribute_name]`. Accordingly, in the `create` action `params[:article]` will be a hash with keys `:title` and `:body`. You can read more about the significance of input names in the parameter_names section.
+The name passed to `form_for` controls the key used in `params` to access the form's values. Here the name is `article` and so all the inputs have names of the form `article[attribute_name]`. Accordingly, in the `create` action `params[:article]` will be a hash with keys `:title` and `:body`. You can read more about the significance of input names in the [parameter_names section](#understanding-parameter-naming-conventions).
The helper methods called on the form builder are identical to the model object helpers except that it is not necessary to specify which object is being edited since this is already managed by the form builder.
@@ -291,8 +291,8 @@ You can create a similar binding without actually creating `<form>` tags with th
```erb
<%= form_for @person, url: {action: "create"} do |person_form| %>
<%= person_form.text_field :name %>
- <%= fields_for @person.contact_detail do |contact_details_form| %>
- <%= contact_details_form.text_field :phone_number %>
+ <%= fields_for @person.contact_detail do |contact_detail_form| %>
+ <%= contact_detail_form.text_field :phone_number %>
<% end %>
<% end %>
```
@@ -300,7 +300,7 @@ You can create a similar binding without actually creating `<form>` tags with th
which produces the following output:
```html
-<form accept-charset="UTF-8" action="/people/create" class="new_person" id="new_person" method="post">
+<form accept-charset="UTF-8" action="/people" class="new_person" id="new_person" method="post">
<input id="person_name" name="person[name]" type="text" />
<input id="contact_detail_phone_number" name="contact_detail[phone_number]" type="text" />
</form>
@@ -441,7 +441,7 @@ Whenever Rails sees that the internal value of an option being generated matches
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer `2` you cannot pass `"2"` to `options_for_select` - you must pass `2`. Be aware of values extracted from the `params` hash as they are all strings.
-WARNING: when `:include_blank` or `:prompt` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
+WARNING: When `:include_blank` or `:prompt` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
You can add arbitrary attributes to the options using hashes:
@@ -687,7 +687,14 @@ class LabellingFormBuilder < ActionView::Helpers::FormBuilder
end
```
-If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `builder: LabellingFormBuilder` option.
+If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `builder: LabellingFormBuilder` option:
+
+```ruby
+def labeled_form_for(record, options = {}, &block)
+ options.merge! builder: LabellingFormBuilder
+ form_for record, options, &block
+end
+```
The form builder used also determines what happens when you do
@@ -722,7 +729,7 @@ The two basic structures are arrays and hashes. Hashes mirror the syntax used fo
the `params` hash will contain
-```erb
+```ruby
{'person' => {'name' => 'Henry'}}
```
diff --git a/guides/source/generators.md b/guides/source/generators.md
index 05bf07b4c8..14f451cbc9 100644
--- a/guides/source/generators.md
+++ b/guides/source/generators.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Creating and Customizing Rails Generators & Templates
=====================================================
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index d80622ef00..e64a788ac2 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Getting Started with Rails
==========================
@@ -23,7 +23,7 @@ application from scratch. It does not assume that you have any prior experience
with Rails. However, to get the most out of it, you need to have some
prerequisites installed:
-* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 1.9.3 or newer.
+* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 2.2.2 or newer.
* The [RubyGems](https://rubygems.org) packaging system, which is installed with Ruby
versions 1.9 and later. To learn more about RubyGems, please read the [RubyGems Guides](http://guides.rubygems.org).
* A working installation of the [SQLite3 Database](https://www.sqlite.org).
@@ -50,7 +50,7 @@ code while accomplishing more than many other languages and frameworks.
Experienced Rails developers also report that it makes web application
development more fun.
-Rails is opinionated software. It makes the assumption that there is the "best"
+Rails is opinionated software. It makes the assumption that there is a "best"
way to do things, and it's designed to encourage that way - and in some cases to
discourage alternatives. If you learn "The Rails Way" you'll probably discover a
tremendous increase in productivity. If you persist in bringing old habits from
@@ -97,7 +97,7 @@ For more installation methods for most Operating Systems take a look at
```bash
$ ruby -v
-ruby 2.0.0p353
+ruby 2.2.2p95
```
Many popular UNIX-like OSes ship with an acceptable version of SQLite3.
@@ -193,6 +193,9 @@ following in the `blog` directory:
$ bin/rails server
```
+TIP: If you are using Windows, you have to pass the scripts under the `bin`
+folder directly to the Ruby interpreter e.g. `ruby bin\rails server`.
+
TIP: Compiling CoffeeScript and JavaScript asset compression requires you
have a JavaScript runtime available on your system, in the absence
of a runtime you will see an `execjs` error during asset compilation.
@@ -201,7 +204,7 @@ Rails adds the `therubyracer` gem to the generated `Gemfile` in a
commented line for new apps and you can uncomment if you need it.
`therubyrhino` is the recommended runtime for JRuby users and is added by
default to the `Gemfile` in apps generated under JRuby. You can investigate
-all the supported runtimes at [ExecJS](https://github.com/sstephenson/execjs#readme).
+all the supported runtimes at [ExecJS](https://github.com/rails/execjs#readme).
This will fire up WEBrick, a web server distributed with Ruby by default. To see
your application in action, open a browser window and navigate to
@@ -318,9 +321,9 @@ root 'welcome#index'
application to the welcome controller's index action and `get 'welcome/index'`
tells Rails to map requests to <http://localhost:3000/welcome/index> to the
welcome controller's index action. This was created earlier when you ran the
-controller generator (`rails generate controller welcome index`).
+controller generator (`bin/rails generate controller welcome index`).
-Launch the web server again if you stopped it to generate the controller (`rails
+Launch the web server again if you stopped it to generate the controller (`bin/rails
server`) and navigate to <http://localhost:3000> in your browser. You'll see the
"Hello, Rails!" message you put into `app/views/welcome/index.html.erb`,
indicating that this new route is indeed going to `WelcomeController`'s `index`
@@ -353,7 +356,7 @@ Rails.application.routes.draw do
end
```
-If you run `rake routes`, you'll see that it has defined routes for all the
+If you run `bin/rake routes`, you'll see that it has defined routes for all the
standard RESTful actions. The meaning of the prefix column (and other columns)
will be seen later, but for now notice that Rails has inferred the
singular form `article` and makes meaningful use of the distinction.
@@ -374,7 +377,7 @@ edit_article GET /articles/:id/edit(.:format) articles#edit
In the next section, you will add the ability to create new articles in your
application and be able to view them. This is the "C" and the "R" from CRUD:
-creation and reading. The form for doing this will look like this:
+create and read. The form for doing this will look like this:
![The new article form](images/getting_started/new_article.png)
@@ -397,7 +400,7 @@ a controller called `ArticlesController`. You can do this by running this
command:
```bash
-$ bin/rails g controller articles
+$ bin/rails generate controller articles
```
If you open up the newly generated `app/controllers/articles_controller.rb`
@@ -553,7 +556,7 @@ this:
In this example, the `articles_path` helper is passed to the `:url` option.
To see what Rails will do with this, we look back at the output of
-`rake routes`:
+`bin/rake routes`:
```bash
$ bin/rake routes
@@ -663,7 +666,7 @@ models, as that will be done automatically by Active Record.
### Running a Migration
-As we've just seen, `rails generate model` created a _database migration_ file
+As we've just seen, `bin/rails generate model` created a _database migration_ file
inside the `db/migrate` directory. Migrations are Ruby classes that are
designed to make it simple to create and modify database tables. Rails uses
rake commands to run migrations, and it's possible to undo a migration after
@@ -716,7 +719,7 @@ NOTE. Because you're working in the development environment by default, this
command will apply to the database defined in the `development` section of your
`config/database.yml` file. If you would like to execute migrations in another
environment, for instance in production, you must explicitly pass it when
-invoking the command: `rake db:migrate RAILS_ENV=production`.
+invoking the command: `bin/rake db:migrate RAILS_ENV=production`.
### Saving data in the controller
@@ -803,7 +806,7 @@ 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 `show` action
before proceeding.
-As we have seen in the output of `rake routes`, the route for `show` action is
+As we have seen in the output of `bin/rake routes`, the route for `show` action is
as follows:
```
@@ -833,7 +836,7 @@ class ArticlesController < ApplicationController
def new
end
- # snipped for brevity
+ # snippet for brevity
```
A couple of things to note. We use `Article.find` to find the article we're
@@ -865,7 +868,7 @@ Visit <http://localhost:3000/articles/new> and give it a try!
### Listing all articles
We still need a way to list all our articles, so let's do that.
-The route for this as per output of `rake routes` is:
+The route for this as per output of `bin/rake routes` is:
```
articles GET /articles(.:format) articles#index
@@ -889,7 +892,7 @@ class ArticlesController < ApplicationController
def new
end
- # snipped for brevity
+ # snippet for brevity
```
And then finally, add the view for this action, located at
@@ -908,6 +911,7 @@ And then finally, add the view for this action, located at
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
+ <td><%= link_to 'Show', article_path(article) %></td>
</tr>
<% end %>
</table>
@@ -1236,10 +1240,9 @@ article we want to show the form back to the user.
We reuse the `article_params` method that we defined earlier for the create
action.
-TIP: You don't need to pass all attributes to `update`. For
-example, if you'd call `@article.update(title: 'A new title')`
-Rails would only update the `title` attribute, leaving all other
-attributes untouched.
+TIP: It is not necessary to pass all the attributes to `update`. For example,
+if `@article.update(title: 'A new title')` was called, Rails would only update
+the `title` attribute, leaving all other attributes untouched.
Finally, we want to show a link to the `edit` action in the list of all the
articles, so let's add that now to `app/views/articles/index.html.erb` to make
@@ -1271,8 +1274,8 @@ bottom of the template:
```html+erb
...
-<%= link_to 'Back', articles_path %> |
-<%= link_to 'Edit', edit_article_path(@article) %>
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
```
And here's how our app looks so far:
@@ -1359,7 +1362,7 @@ Then do the same for the `app/views/articles/edit.html.erb` view:
We're now ready to cover the "D" part of CRUD, deleting articles from the
database. Following the REST convention, the route for
-deleting articles as per output of `rake routes` is:
+deleting articles as per output of `bin/rake routes` is:
```ruby
DELETE /articles/:id(.:format) articles#destroy
@@ -1475,16 +1478,20 @@ Finally, add a 'Destroy' link to your `index` action template
```
Here we're using `link_to` in a different way. We pass the named route as the
-second argument, and then the options as another argument. The `:method` and
-`:'data-confirm'` options are used as HTML5 attributes so that when the link is
-clicked, Rails will first show a confirm dialog to the user, and then submit the
-link with method `delete`. This is done via the JavaScript file `jquery_ujs`
-which is automatically included into your application's layout
-(`app/views/layouts/application.html.erb`) when you generated the application.
-Without this file, the confirmation dialog box wouldn't appear.
+second argument, and then the options as another argument. The `method: :delete`
+and `data: { confirm: 'Are you sure?' }` options are used as HTML5 attributes so
+that when the link is clicked, Rails will first show a confirm dialog to the
+user, and then submit the link with method `delete`. This is done via the
+JavaScript file `jquery_ujs` which is automatically included in your
+application's layout (`app/views/layouts/application.html.erb`) when you
+generated the application. Without this file, the confirmation dialog box won't
+appear.
![Confirm Dialog](images/getting_started/confirm_dialog.png)
+TIP: Learn more about jQuery Unobtrusive Adapter (jQuery UJS) on
+[Working With JavaScript in Rails](working_with_javascript_in_rails.html) guide.
+
Congratulations, you can now create, show, list, update and destroy
articles.
@@ -1502,7 +1509,7 @@ comments on articles.
We're going to see the same generator that we used before when creating
the `Article` model. This time we'll create a `Comment` model to hold
-reference of article comments. Run this command in your terminal:
+reference to an article. Run this command in your terminal:
```bash
$ bin/rails generate model Comment commenter:string body:text article:references
@@ -1514,7 +1521,7 @@ This command will generate four files:
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| db/migrate/20140120201010_create_comments.rb | Migration to create the comments table in your database (your name will include a different timestamp) |
| app/models/comment.rb | The Comment model |
-| test/models/comment_test.rb | Testing harness for the comments model |
+| test/models/comment_test.rb | Testing harness for the comment model |
| test/fixtures/comments.yml | Sample comments for use in testing |
First, take a look at `app/models/comment.rb`:
@@ -1681,8 +1688,8 @@ So first, we'll wire up the Article show template
</p>
<% end %>
-<%= link_to 'Back', articles_path %> |
-<%= link_to 'Edit', edit_article_path(@article) %>
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
```
This adds a form on the `Article` show page that creates a new comment by
@@ -1762,8 +1769,8 @@ add that to the `app/views/articles/show.html.erb`.
</p>
<% end %>
-<%= link_to 'Edit Article', edit_article_path(@article) %> |
-<%= link_to 'Back to Articles', articles_path %>
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
```
Now you can add articles and comments to your blog and have them show up in the
@@ -1828,8 +1835,8 @@ following:
</p>
<% end %>
-<%= link_to 'Edit Article', edit_article_path(@article) %> |
-<%= link_to 'Back to Articles', articles_path %>
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
```
This will now render the partial in `app/views/comments/_comment.html.erb` once
@@ -1878,8 +1885,8 @@ Then you make the `app/views/articles/show.html.erb` look like the following:
<h2>Add a comment:</h2>
<%= render 'comments/form' %>
-<%= link_to 'Edit Article', edit_article_path(@article) %> |
-<%= link_to 'Back to Articles', articles_path %>
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
```
The second render just defines the partial template we want to render,
@@ -1995,7 +2002,7 @@ class ArticlesController < ApplicationController
@articles = Article.all
end
- # snipped for brevity
+ # snippet for brevity
```
We also want to allow only authenticated users to delete comments, so in the
@@ -2011,7 +2018,7 @@ class CommentsController < ApplicationController
# ...
end
- # snipped for brevity
+ # snippet for brevity
```
Now if you try to create a new article, you will be greeted with a basic HTTP
@@ -2048,19 +2055,6 @@ resources:
* The [Ruby on Rails mailing list](http://groups.google.com/group/rubyonrails-talk)
* The [#rubyonrails](irc://irc.freenode.net/#rubyonrails) channel on irc.freenode.net
-Rails also comes with built-in help that you can generate using the rake
-command-line utility:
-
-* 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.
-
-TIP: To be able to generate the Rails Guides locally with the `doc:guides` rake
-task you need to install the Redcarpet and Nokogiri gems. Add it to your `Gemfile` and run
-`bundle install` and you're ready to go.
Configuration Gotchas
---------------------
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index bd6babff41..9f0ed1a85b 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Rails Internationalization (I18n) API
=====================================
@@ -40,7 +40,7 @@ Internationalization is a complex problem. Natural languages differ in so many w
* providing support for English and similar languages out of the box
* making it easy to customize and extend everything for other languages
-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.
+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**. _Localization_ of a Rails application means defining translated values for these strings in desired languages.
### The Overall Architecture of the Library
@@ -84,13 +84,13 @@ So, let's internationalize a simple Rails application from the ground up in the
Setup the Rails Application for Internationalization
----------------------------------------------------
-There are just a few simple steps to get up and running with I18n support for your application.
+There are a few steps to get up and running with I18n support for a Rails application.
### 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.
+Following the _convention over configuration_ philosophy, Rails I18n provides reasonable default translation strings. When different translation strings are needed, they can be overridden.
-Rails adds all `.rb` and `.yml` files from the `config/locales` directory to your **translations load path**, automatically.
+Rails adds all `.rb` and `.yml` files from the `config/locales` directory to the **translations load path**, automatically.
The default `en.yml` locale in this directory contains a sample pair of translation strings:
@@ -101,15 +101,15 @@ en:
This means, that in the `:en` locale, the key _hello_ will map to the _Hello world_ string. Every string inside Rails is internationalized in this way, see for instance Active Model validation messages in the [`activemodel/lib/active_model/locale/en.yml`](https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml) file or time and date formats in the [`activesupport/lib/active_support/locale/en.yml`](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml) file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.
-The I18n library will use **English** as a **default locale**, i.e. if you don't set a different locale, `:en` will be used for looking up translations.
+The I18n library will use **English** as a **default locale**, i.e. if a different locale is not set, `:en` will be used for looking up translations.
NOTE: The i18n library takes a **pragmatic approach** to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en)), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Few gems such as [Globalize3](https://github.com/globalize/globalize) may help you implement it.
-The **translations load path** (`I18n.load_path`) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.
+The **translations load path** (`I18n.load_path`) is an array of paths to files that will be loaded automatically. Configuring this path allows for customization of translations directory structure and file naming scheme.
-NOTE: The backend will lazy-load these translations when a translation is looked up for the first time. This makes it possible to just swap the backend with something else even after translations have already been announced.
+NOTE: The backend lazy-loads these translations when a translation is looked up for the first time. This backend can be swapped with something else even after translations have already been announced.
-The default `application.rb` file has instructions on how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines.
+The default `application.rb` file has instructions on how to add locales from another directory and how to set a different default locale.
```ruby
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
@@ -117,31 +117,25 @@ The default `application.rb` file has instructions on how to add locales from an
# config.i18n.default_locale = :de
```
-### 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.
-
-To tell the I18n library where it can find your custom translation files you can specify the load path anywhere in your application - just make sure it gets run before any translations are actually looked up. You might also want to change the default locale. The simplest thing possible is to put the following into an initializer:
+The load path must be specified before any translations are looked up. To change the default locale from an initializer instead of `application.rb`:
```ruby
-# in config/initializers/locale.rb
+# config/initializers/locale.rb
-# tell the I18n library where to find your translations
+# Where the I18n library should search for translation files
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
-# set default locale to something other than :en
+# Set default locale to something other than :en
I18n.default_locale = :pt
```
-### 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.
+### Managing the Locale across Requests
-However, you would probably like to **provide support for more locales** in your application. In such case, you need to set and pass the locale between requests.
+The default locale is used for all translations unless `I18n.locale` is explicitly set.
-WARNING: You may be tempted to store the chosen locale in a _session_ or a *cookie*. However, **do not do this**. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [*RESTful*](http://en.wikipedia.org/wiki/Representational_State_Transfer). Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
+A localized application will likely need to provide support for multiple locales. To accomplish this, the locale should be set at the beginning of each request so that all strings are translated using the desired locale during the lifetime of that request.
-The _setting part_ is easy. You can set the locale in a `before_action` in the `ApplicationController` like this:
+The locale can be set in a `before_action` in the `ApplicationController`:
```ruby
before_action :set_locale
@@ -151,11 +145,11 @@ def set_locale
end
```
-This requires you to pass the locale as a URL query parameter as in `http://example.com/books?locale=pt`. (This is, for example, Google's approach.) So `http://localhost:3000?locale=pt` will load the Portuguese localization, whereas `http://localhost:3000?locale=de` would load the German localization, and so on. You may skip the next section and head over to the **Internationalize your application** section, if you want to try things out by manually placing the locale in the URL and reloading the page.
+This example illustrates this using a URL query parameter to set the locale (e.g. `http://example.com/books?locale=pt`). With this approach, `http://localhost:3000?locale=pt` renders the Portuguese localization, while `http://localhost:3000?locale=de` loads a German localization.
-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.
+The locale can be set using one of many different approaches.
-### 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:
@@ -201,14 +195,14 @@ end
If your application includes a locale switching menu, you would then have something like this in it:
```ruby
-link_to("Deutsch", "#{APP_CONFIG[:deutsch_website_url]}#{request.env['REQUEST_URI']}")
+link_to("Deutsch", "#{APP_CONFIG[:deutsch_website_url]}#{request.env['PATH_INFO']}")
```
assuming you would set `APP_CONFIG[:deutsch_website_url]` to some value like `http://www.application.de`.
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).
-### Setting the Locale from the URL Params
+#### Setting the Locale from 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_action_ 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.
@@ -266,14 +260,23 @@ Do take special care about the **order of your routes**, so this route declarati
NOTE: Have a look at various gems which simplify working with routes: [routing_filter](https://github.com/svenfuchs/routing-filter/tree/master), [rails-translate-routes](https://github.com/francesc/rails-translate-routes), [route_translator](https://github.com/enriclluelles/route_translator).
-### Setting the Locale from the Client Supplied Information
+#### Setting the Locale from User Preferences
-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.
+An application with authenticated users may allow users to set a locale preference through the application's interface. With this approach, a user's selected locale preference is persisted in the database and used to set the locale for authenticated requests by that user.
+```ruby
+def set_locale
+ I18n.locale = current_user.try(:locale) || I18n.default_locale
+end
+```
+
+#### Choosing an Implied Locale
-#### Using `Accept-Language`
+When an explicit locale has not been set for a request (e.g. via one of the above methods), an application should attempt to infer the desired locale.
-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_).
+##### Inferring Locale from the Language Header
+
+The `Accept-Language` HTTP header indicates the preferred language for request's response. Browsers [set this header value based on the user's language preference settings](http://www.w3.org/International/questions/qa-lang-priorities), making it a good first choice when inferring a locale.
A trivial implementation of using an `Accept-Language` header would be:
@@ -290,24 +293,27 @@ private
end
```
-Of course, in a production environment you would need much more robust code, and could use a gem 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).
-#### Using GeoIP (or Similar) Database
+In practice, more robust code is necessary to do this reliably. Iain Hecker's [http_accept_language](https://github.com/iain/http_accept_language/tree/master) library or Ryan Tomayko's [locale](https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb) Rack middleware provide solutions to this problem.
+
+##### Inferring the Locale from IP Geolocation
-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.
+The IP address of the client making the request can be used to infer the client's region and thus their locale. Services such as [GeoIP Lite Country](http://www.maxmind.com/app/geolitecountry) or gems like [geocoder](https://github.com/alexreisner/geocoder) can be used to implement this approach.
-#### User Profile
+In general, this approach is far less reliable than using the language header and is not recommended for most web applications.
-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.
+#### Storing the Locale from the Session or Cookies
-Internationalizing your Application
+WARNING: You may be tempted to store the chosen locale in a _session_ or a *cookie*. However, **do not do this**. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [*RESTful*](http://en.wikipedia.org/wiki/Representational_State_Transfer). Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
+
+Internationalization and Localization
-----------------------------------
-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.
+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.
-Let's _internationalize_ our application, i.e. abstract every locale-specific parts, and then _localize_ it, i.e. provide necessary translations for these abstracts.
+Next we need to _internationalize_ our application by abstracting every locale-specific element. Finally, we need to _localize_ it by providing necessary translations for these abstracts.
-You most probably have something like this in one of your applications:
+Given the following example:
```ruby
# config/routes.rb
@@ -344,9 +350,9 @@ end
![rails i18n demo untranslated](images/i18n/demo_untranslated.png)
-### Adding Translations
+### Abstracting Localized Code
-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:
+There are two strings in our code that are in English and that users will be rendered in our response ("Hello Flash" and "Hello World"). In order to internationalize this code, these strings need to be replaced by calls to Rails' `#t` helper with an appropriate key for each string:
```ruby
# app/controllers/home_controller.rb
@@ -363,13 +369,15 @@ end
<p><%= flash[:notice] %></p>
```
-When you now render this view, it will show an error message which tells you that the translations for the keys `:hello_world` and `:hello_flash` are missing.
+Now, when this view is rendered, it will show an error message which tells you that the translations for the keys `:hello_world` and `:hello_flash` are missing.
![rails i18n demo translation missing](images/i18n/demo_translation_missing.png)
NOTE: Rails adds a `t` (`translate`) helper method to your views so that you do not need to spell out `I18n.t` all the time. Additionally this helper will catch missing translations and wrap the resulting error message into a `<span class="translation_missing">`.
-So let's add the missing translations into the dictionary files (i.e. do the "localization" part):
+### Providing Translations for Internationalized Strings
+
+Add the missing translations into the translation dictionary files:
```yaml
# config/locales/en.yml
@@ -383,11 +391,11 @@ pirate:
hello_flash: Ahoy Flash
```
-There you go. Because you haven't changed the default_locale, I18n will use English. Your application now shows:
+Because the `default_locale` hasn't changed, translations use the `:en` locale and the response renders the english strings:
![rails i18n demo translated to English](images/i18n/demo_translated_en.png)
-And when you change the URL to pass the pirate locale (`http://localhost:3000?locale=pirate`), you'll get:
+If the locale is set via the URL to the pirate locale (`http://localhost:3000?locale=pirate`), the response renders the pirate strings:
![rails i18n demo translated to pirate](images/i18n/demo_translated_pirate.png)
@@ -395,21 +403,64 @@ 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.)
-### Passing variables to translations
+### Passing Variables to Translations
-You can use variables in the translation messages and pass their values from the view.
+One key consideration for successfully internationalizing an application is to
+avoid making incorrect assumptions about grammar rules when abstracting localized
+code. Grammar rules that seem fundamental in one locale may not hold true in
+another one.
+
+Improper abstraction is shown in the following example, where assumptions are
+made about the ordering of the different parts of the translation. Note that Rails
+provides a `number_to_currency` helper to handle the following case.
```erb
-# app/views/home/index.html.erb
-<%=t 'greet_username', user: "Bill", message: "Goodbye" %>
+# app/views/products/show.html.erb
+<%= "#{t('currency')}#{@product.price}" %>
+```
+
+```yaml
+# config/locales/en.yml
+en:
+ currency: "$"
+
+# config/locales/es.yml
+es:
+ currency: "€"
+```
+
+If the product's price is 10 then the proper translation for Spanish is "10 €"
+instead of "€10" but the abstraction cannot give it.
+
+To create proper abstraction, the I18n gem ships with a feature called variable
+interpolation that allows you to use variables in translation definitions and
+pass the values for these variables to the translation method.
+
+Proper abstraction is shown in the following example:
+
+```erb
+# app/views/products/show.html.erb
+<%= t('product_price', price: @product.price) %>
```
```yaml
# config/locales/en.yml
en:
- greet_username: "%{message}, %{user}!"
+ product_price: "$%{price}"
+
+# config/locales/es.yml
+es:
+ product_price: "%{price} €"
```
+All grammatical and punctuation decisions are made in the definition itself, so
+the abstraction can give a proper translation.
+
+NOTE: The `default` and `scope` keywords are reserved and can't be used as
+variable names. If used, 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.
+
### 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.
@@ -449,7 +500,10 @@ You can make use of this feature, e.g. when working with a large amount of stati
### 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.
+When you are using the default SimpleStore shipped with the i18n library,
+dictionaries are stored in plain-text files on the disk. 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.
For example, your `config/locales` directory could look like this:
@@ -489,7 +543,9 @@ NOTE: The default locale loading mechanism in Rails does not load locale files i
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.
+You should have a good understanding of using the i18n library now and know how
+to internationalize a basic Rails application. In the following chapters, we'll
+cover its features in more depth.
These chapters will show examples using both the `I18n.translate` method as well as the [`translate` view helper method](http://api.rubyonrails.org/classes/ActionView/Helpers/TranslationHelper.html#method-i-translate) (noting the additional feature provide by the view helper method).
@@ -530,7 +586,7 @@ Thus the following calls are equivalent:
```ruby
I18n.t 'activerecord.errors.messages.record_invalid'
-I18n.t 'errors.messages.record_invalid', scope: :active_record
+I18n.t 'errors.messages.record_invalid', scope: :activerecord
I18n.t :record_invalid, scope: 'activerecord.errors.messages'
I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]
```
@@ -588,20 +644,26 @@ you can look up the `books.index.title` value **inside** `app/views/books/index.
NOTE: Automatic translation scoping by partial is only available from the `translate` view helper method.
-### Interpolation
+"Lazy" lookup can also be used in controllers:
-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.
+```yaml
+en:
+ books:
+ create:
+ success: Book created!
+```
-All options besides `:default` and `:scope` that are passed to `#translate` will be interpolated to the translation:
+This is useful for setting flash messages for instance:
```ruby
-I18n.backend.store_translations :en, thanks: 'Thanks %{name}!'
-I18n.translate :thanks, name: 'Jeremy'
-# => 'Thanks Jeremy!'
+class BooksController < ApplicationController
+ def create
+ # ...
+ redirect_to books_url, notice: t('.success')
+ end
+end
```
-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.
-
### 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.
@@ -687,7 +749,7 @@ you can safely pass the username as set by the user:
```erb
<%# This is safe, it is going to be escaped if needed. %>
-<%= t('welcome_html', username: @current_user.username %>
+<%= t('welcome_html', username: @current_user.username) %>
```
Safe strings on the other hand are interpolated verbatim.
@@ -809,7 +871,7 @@ So, for example, instead of the default error message `"cannot be blank"` you co
| validation | with option | message | interpolation |
| ------------ | ------------------------- | ------------------------- | ------------- |
-| confirmation | - | :confirmation | - |
+| confirmation | - | :confirmation | attribute |
| acceptance | - | :accepted | - |
| presence | - | :blank | - |
| absence | - | :present | - |
@@ -829,6 +891,7 @@ So, for example, instead of the default error message `"cannot be blank"` you co
| numericality | :equal_to | :equal_to | count |
| numericality | :less_than | :less_than | count |
| numericality | :less_than_or_equal_to | :less_than_or_equal_to | count |
+| numericality | :other_than | :other_than | count |
| numericality | :only_integer | :not_an_integer | - |
| numericality | :odd | :odd | - |
| numericality | :even | :even | - |
@@ -1009,7 +1072,7 @@ In other contexts you might want to change this behavior, though. E.g. the defau
module I18n
class JustRaiseExceptionHandler < ExceptionHandler
def call(exception, locale, key, options)
- if exception.is_a?(MissingTranslation)
+ if exception.is_a?(MissingTranslationData)
raise exception.to_exception
else
super
@@ -1026,7 +1089,7 @@ This would re-raise only the `MissingTranslationData` exception, passing all oth
However, if you are using `I18n::Backend::Pluralization` this handler will also raise `I18n::MissingTranslationData: translation missing: en.i18n.plural.rule` exception that should normally be ignored to fall back to the default pluralization rule for English locale. To avoid this you may use additional check for translation key:
```ruby
-if exception.is_a?(MissingTranslation) && key.to_s != 'i18n.plural.rule'
+if exception.is_a?(MissingTranslationData) && key.to_s != 'i18n.plural.rule'
raise exception.to_exception
else
super
@@ -1072,11 +1135,8 @@ Resources
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)
-
-If you found this guide useful, please consider recommending its authors on [workingwithrails](http://www.workingwithrails.com).
-
+* [Sven Fuchs](http://svenfuchs.com) (initial author)
+* [Karel Minařík](http://www.karmi.cz)
Footnotes
---------
diff --git a/guides/source/initialization.md b/guides/source/initialization.md
index a93ceb7fb5..43083ebb86 100644
--- a/guides/source/initialization.md
+++ b/guides/source/initialization.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
The Rails Initialization Process
================================
@@ -34,7 +34,7 @@ Launch!
Let's start to boot and initialize the app. A Rails application is usually
started by running `rails console` or `rails server`.
-### `railties/bin/rails`
+### `railties/exe/rails`
The `rails` in the command `rails server` is a ruby executable in your load
path. This executable contains the following lines:
@@ -45,7 +45,7 @@ load Gem.bin_path('railties', 'rails', version)
```
If you try out this command in a Rails console, you would see that this loads
-`railties/bin/rails`. A part of the file `railties/bin/rails.rb` has the
+`railties/exe/rails`. A part of the file `railties/exe/rails.rb` has the
following code:
```ruby
@@ -53,11 +53,11 @@ require "rails/cli"
```
The file `railties/lib/rails/cli` in turn calls
-`Rails::AppRailsLoader.exec_app_rails`.
+`Rails::AppLoader.exec_app`.
-### `railties/lib/rails/app_rails_loader.rb`
+### `railties/lib/rails/app_loader.rb`
-The primary goal of the function `exec_app_rails` is to execute your app's
+The primary goal of the function `exec_app` is to execute your app's
`bin/rails`. If the current directory does not have a `bin/rails`, it will
navigate upwards until it finds a `bin/rails` executable. Thus one can invoke a
`rails` command from anywhere inside a rails application.
@@ -106,6 +106,7 @@ A standard Rails application depends on several gems, specifically:
* activemodel
* activerecord
* activesupport
+* activejob
* arel
* builder
* bundler
@@ -163,7 +164,7 @@ throwing an error message. If the command is valid, a method of the same name
is called.
```ruby
-COMMAND_WHITELIST = %(plugin generate destroy console server dbconsole application runner new version help)
+COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole application runner new version help)
def run_command!(command)
command = parse_command(command)
@@ -532,6 +533,7 @@ require "rails"
action_controller
action_view
action_mailer
+ active_job
rails/test_unit
sprockets
).each do |framework|
@@ -555,9 +557,8 @@ I18n and Rails configuration are all being defined here.
The rest of `config/application.rb` defines the configuration for the
`Rails::Application` which will be used once the application is fully
initialized. When `config/application.rb` has finished loading Rails and defined
-the application namespace, we go back to `config/environment.rb`,
-where the application is initialized. For example, if the application was called
-`Blog`, here we would find `Rails.application.initialize!`, which is
+the application namespace, we go back to `config/environment.rb`. Here, the
+application is initialized with `Rails.application.initialize!`, which is
defined in `rails/application.rb`.
### `railties/lib/rails/application.rb`
diff --git a/guides/source/kindle/welcome.html.erb b/guides/source/kindle/welcome.html.erb
index 610a71570f..ef3397f58f 100644
--- a/guides/source/kindle/welcome.html.erb
+++ b/guides/source/kindle/welcome.html.erb
@@ -2,4 +2,6 @@
<h3>Kindle Edition</h3>
-The Kindle Edition of the Rails Guides should be considered a work in progress. Feedback is really welcome. Please see the "Feedback" section at the end of each guide for instructions.
+<div>
+ The Kindle Edition of the Rails Guides should be considered a work in progress. Feedback is really welcome. Please see the "Feedback" section at the end of each guide for instructions.
+</div>
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index c3cde49630..94cd7297e2 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Layouts and Rendering in Rails
==============================
@@ -103,34 +103,6 @@ In most cases, the `ActionController::Base#render` method does the heavy lifting
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.
-#### Rendering Nothing
-
-Perhaps the simplest thing you can do with `render` is to render nothing at all:
-
-```ruby
-render nothing: true
-```
-
-If you look at the response for this using cURL, you will see the following:
-
-```bash
-$ curl -i 127.0.0.1:3000/books
-HTTP/1.1 200 OK
-Connection: close
-Date: Sun, 24 Jan 2010 09:25:18 GMT
-Transfer-Encoding: chunked
-Content-Type: */*; charset=utf-8
-X-Runtime: 0.014297
-Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
-Cache-Control: no-cache
-
-$
-```
-
-We see there is an empty response (no data after the `Cache-Control` line), but the request was successful because Rails has set the response to 200 OK. You can set the `:status` option on render to change this response. Rendering nothing can be useful for Ajax requests where all you want to send back to the browser is an acknowledgment that the request was completed.
-
-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.
-
#### Rendering an Action's View
If you want to render the view that corresponds to a different template within the same controller, you can use `render` with the name of the view:
@@ -255,7 +227,7 @@ extension for the layout file.
#### Rendering HTML
-You can send a HTML string back to the browser by using the `:html` option to
+You can send an HTML string back to the browser by using the `:html` option to
`render`:
```ruby
@@ -316,12 +288,13 @@ NOTE: Unless overridden, your response returned from this render option will be
#### Options for `render`
-Calls to the `render` method generally accept four options:
+Calls to the `render` method generally accept five options:
* `:content_type`
* `:layout`
* `:location`
* `:status`
+* `:formats`
##### The `:content_type` Option
@@ -427,9 +400,19 @@ Rails understands both numeric status codes and the corresponding symbols shown
| | 510 | :not_extended |
| | 511 | :network_authentication_required |
-NOTE: If you try to render content along with a non-content status code
+NOTE: If you try to render content along with a non-content status code
(100-199, 204, 205 or 304), it will be dropped from the response.
+##### The `:formats` Option
+
+Rails uses the format specified in the request (or `:html` by default). You can
+change this passing the `:formats` option with a symbol or an array:
+
+```ruby
+render formats: :xml
+render formats: [:json, :xml]
+```
+
#### 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.
@@ -553,6 +536,42 @@ In this application:
* `OldArticlesController#show` will use no layout at all
* `OldArticlesController#index` will use the `old` layout
+##### Template Inheritance
+
+Similar to the Layout Inheritance logic, if a template or partial is not found in the conventional path, the controller will look for a template or partial to render in its inheritance chain. For example:
+
+```ruby
+# in app/controllers/application_controller
+class ApplicationController < ActionController::Base
+end
+
+# in app/controllers/admin_controller
+class AdminController < ApplicationController
+end
+
+# in app/controllers/admin/products_controller
+class Admin::ProductsController < AdminController
+ def index
+ end
+end
+```
+
+The lookup order for a `admin/products#index` action will be:
+
+* `app/views/admin/products/`
+* `app/views/admin/`
+* `app/views/application/`
+
+This makes `app/views/application/` a great place for your shared partials, which can then be rendered in your ERB as such:
+
+```erb
+<%# app/views/admin/products/index.html.erb %>
+<%= render @products || "empty_list" %>
+
+<%# app/views/application/_empty_list.html.erb %>
+There are no items in this list <em>yet</em>.
+```
+
#### 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.
@@ -1028,9 +1047,14 @@ One way to use partials is to treat them as the equivalent of subroutines: as a
<%= render "shared/footer" %>
```
-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.
+Here, the `_ad_banner.html.erb` and `_footer.html.erb` partials could contain
+content that is shared by many pages in your application. You don't need to see
+the details of these sections when you're concentrating on a particular page.
-As you already could see from the previous sections of this guide, `yield` is a very powerful tool for cleaning up your layouts. Keep in mind that it's pure ruby, so you can use it almost everywhere. For example, we can use it to DRY form layout definition for several similar resources:
+As seen in the previous sections of this guide, `yield` is a very powerful tool
+for cleaning up your layouts. Keep in mind that it's pure Ruby, so you can use
+it almost everywhere. For example, we can use it to DRY up form layout
+definitions for several similar resources:
* `users/index.html.erb`
@@ -1039,7 +1063,7 @@ As you already could see from the previous sections of this guide, `yield` is a
<p>
Name contains: <%= f.text_field :name_contains %>
</p>
- <%= end %>
+ <% end %>
```
* `roles/index.html.erb`
@@ -1049,7 +1073,7 @@ As you already could see from the previous sections of this guide, `yield` is a
<p>
Title contains: <%= f.text_field :title_contains %>
</p>
- <%= end %>
+ <% end %>
```
* `shared/_search_filters.html.erb`
@@ -1114,6 +1138,36 @@ You can also pass local variables into partials, making them even more powerful
Although the same partial will be rendered into both views, Action View's submit helper will return "Create Zone" for the new action and "Update Zone" for the edit action.
+To pass a local variable to a partial in only specific cases use the `local_assigns`.
+
+* `index.html.erb`
+
+ ```erb
+ <%= render user.articles %>
+ ```
+
+* `show.html.erb`
+
+ ```erb
+ <%= render article, full: true %>
+ ```
+
+* `_articles.html.erb`
+
+ ```erb
+ <%= content_tag_for :article, article do |article| %>
+ <h2><%= article.title %></h2>
+
+ <% if local_assigns[:full] %>
+ <%= simple_format article.body %>
+ <% else %>
+ <%= truncate article.body %>
+ <% end %>
+ <% end %>
+ ```
+
+This way it is possible to use the partial without the need to declare all local variables.
+
Every partial also has a local variable with the same name as the partial (minus the underscore). You can pass an object in to this local variable via the `:object` option:
```erb
diff --git a/guides/source/maintenance_policy.md b/guides/source/maintenance_policy.md
index 45cdc549f7..50308f505a 100644
--- a/guides/source/maintenance_policy.md
+++ b/guides/source/maintenance_policy.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Maintenance Policy for Ruby on Rails
====================================
diff --git a/guides/source/nested_model_forms.md b/guides/source/nested_model_forms.md
index 44236ad239..121cf2b185 100644
--- a/guides/source/nested_model_forms.md
+++ b/guides/source/nested_model_forms.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Rails Nested Model Forms
========================
@@ -106,7 +106,7 @@ Consider the following typical RESTful controller which will prepare a new Perso
class PeopleController < ApplicationController
def new
@person = Person.new
- @person.built_address
+ @person.build_address
2.times { @person.projects.build }
end
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index bd884441ac..4e630a39f3 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
The Basics of Creating Rails Plugins
====================================
@@ -265,7 +265,7 @@ module Yaffle
end
end
-ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle
+ActiveRecord::Base.include(Yaffle::ActsAsYaffle)
```
You can then return to the root directory (`cd ../..`) of your plugin and rerun the tests using `rake`.
@@ -308,7 +308,7 @@ module Yaffle
end
end
-ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle
+ActiveRecord::Base.include(Yaffle::ActsAsYaffle)
```
When you run `rake`, you should see the tests all pass:
@@ -382,7 +382,7 @@ module Yaffle
end
end
-ActiveRecord::Base.send :include, Yaffle::ActsAsYaffle
+ActiveRecord::Base.include(Yaffle::ActsAsYaffle)
```
Run `rake` one final time and you should see:
diff --git a/guides/source/profiling.md b/guides/source/profiling.md
index 695b09647f..ce093f78ba 100644
--- a/guides/source/profiling.md
+++ b/guides/source/profiling.md
@@ -1,4 +1,4 @@
-*DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+*DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
A Guide to Profiling Rails Applications
=======================================
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index 0db777b9bb..b7364536c3 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Rails Application Templates
===========================
@@ -215,7 +215,7 @@ CODE
### yes?(question) or no?(question)
-These methods let you ask questions from templates and decide the flow based on the user's answer. Let's say you want to freeze rails only if the user wants to:
+These methods let you ask questions from templates and decide the flow based on the user's answer. Let's say you want to Freeze Rails only if the user wants to:
```ruby
rake("rails:freeze:gems") if yes?("Freeze rails gems?")
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index 561a3d9392..993cd5ac44 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Rails on Rack
=============
@@ -254,7 +254,7 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
**`ActionDispatch::RequestId`**
-* Makes a unique `X-Request-Id` header available to the response and enables the `ActionDispatch::Request#uuid` method.
+* Makes a unique `X-Request-Id` header available to the response and enables the `ActionDispatch::Request#request_id` method.
**`Rails::Rack::Logger`**
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 893cedeefc..52f11f92bd 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Rails Routing from the Outside In
=================================
@@ -177,6 +177,8 @@ WARNING: A [long-standing bug](https://github.com/rails/rails/issues/1769) preve
```ruby
form_for @geocoder, url: geocoder_path do |f|
+
+# snippet for brevity
```
### Controller Namespaces and Routing
@@ -229,7 +231,7 @@ or, for a single case:
resources :articles, path: '/admin/articles'
```
-In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `PostsController`:
+In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `ArticlesController`:
| HTTP Verb | Path | Controller#Action | Named Helper |
| --------- | ------------------------ | -------------------- | ---------------------- |
@@ -807,6 +809,21 @@ As long as `Sprockets` responds to `call` and returns a `[status, headers, body]
NOTE: For the curious, `'articles#index'` actually expands out to `ArticlesController.action(:index)`, which returns a valid Rack application.
+If you specify a Rack application as the endpoint for a matcher, remember that
+the route will be unchanged in the receiving application. With the following
+route your Rack application should expect the route to be '/admin':
+
+```ruby
+match '/admin', to: AdminApp, via: :all
+```
+
+If you would prefer to have your Rack application receive requests at the root
+path instead, use mount:
+
+```ruby
+mount AdminApp, at: '/admin'
+```
+
### Using `root`
You can specify what Rails should route `'/'` to with the `root` method:
@@ -909,7 +926,7 @@ The `:as` option lets you override the normal naming for the named route helpers
resources :photos, as: 'images'
```
-will recognize incoming paths beginning with `/photos` and route the requests to `PhotosController`, but use the value of the :as option to name the helpers.
+will recognize incoming paths beginning with `/photos` and route the requests to `PhotosController`, but use the value of the `:as` option to name the helpers.
| HTTP Verb | Path | Controller#Action | Named Helper |
| --------- | ---------------- | ----------------- | -------------------- |
@@ -1006,7 +1023,7 @@ TIP: If your application has many RESTful routes, using `:only` and `:except` to
### Translated Paths
-Using `scope`, we can alter path names generated by resources:
+Using `scope`, we can alter path names generated by `resources`:
```ruby
scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
diff --git a/guides/source/ruby_on_rails_guides_guidelines.md b/guides/source/ruby_on_rails_guides_guidelines.md
index 0ecf8a80df..50866350f8 100644
--- a/guides/source/ruby_on_rails_guides_guidelines.md
+++ b/guides/source/ruby_on_rails_guides_guidelines.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails Guides Guidelines
===============================
@@ -64,7 +64,9 @@ The guides and the API should be coherent and consistent where appropriate. In p
HTML Guides
-----------
-Before generating the guides, make sure that you have the latest version of Bundler installed on your system. As of this writing, you must install Bundler 1.3.5 on your device.
+Before generating the guides, make sure that you have the latest version of
+Bundler installed on your system. As of this writing, you must install Bundler
+1.3.5 or later on your device.
To install the latest version of Bundler, run `gem install bundler`.
@@ -82,6 +84,8 @@ or
bundle exec rake guides:generate:html
```
+Resulting HTML files can be found in the `./output` directory.
+
To process `my_guide.md` and nothing else use the `ONLY` environment variable:
```
diff --git a/guides/source/security.md b/guides/source/security.md
index e4cc79df55..93580d4d4e 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Ruby on Rails Security Guide
============================
@@ -449,14 +449,16 @@ Depending on your web application, there may be more ways to hijack the user's a
### 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 they are human, but reveal that a robot is a robot._
+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 registration forms from attackers and comment forms from automatic spam bots by asking the user to type the letters of a distorted image. This is the positive CAPTCHA, but there is also the negative CAPTCHA. The idea of a negative CAPTCHA is not for a user to prove that they are human, but reveal that a robot is a robot._
-But not only spam robots (bots) are a problem, but also automatic login bots. A popular CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](https://github.com/ambethia/recaptcha/) is also a Rails plug-in with the same name as the API.
+A popular positive CAPTCHA API is [reCAPTCHA](http://recaptcha.net/) which displays two distorted images of words from old books. It also adds an angled line, rather than a distorted background and high levels of warping on the text as earlier CAPTCHAs did, because the latter were broken. As a bonus, using reCAPTCHA helps to digitize old books. [ReCAPTCHA](https://github.com/ambethia/recaptcha/) is also a Rails plug-in with the same name as the API.
You will get two keys from the API, a public and a private key, which you have to put into your Rails environment. After that you can use the recaptcha_tags method in the view, and the verify_recaptcha method in the controller. Verify_recaptcha will return false if the validation fails.
-The problem with CAPTCHAs is, they are annoying. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. The idea of negative CAPTCHAs is not to ask a user to proof that they are human, but reveal that a spam robot is a bot.
+The problem with CAPTCHAs is that they have a negative impact on the user experience. Additionally, some visually impaired users have found certain kinds of distorted CAPTCHAs difficult to read. Still, positive CAPTCHAs are one of the best methods to prevent all kinds of bots from submitting forms.
-Most bots are really dumb, they crawl the web and put their spam into every form's field they can find. Negative CAPTCHAs take advantage of that and include a "honeypot" field in the form which will be hidden from the human user by CSS or JavaScript.
+Most bots are really dumb. They crawl the web and put their spam into every form's field they can find. Negative CAPTCHAs take advantage of that and include a "honeypot" field in the form which will be hidden from the human user by CSS or JavaScript.
+
+Note that negative CAPTCHAs are only effective against dumb bots and won't suffice to protect critical applications from targeted bots. Still, the negative and positive CAPTCHAs can be combined to increase the performance, e.g., if the "honeypot" field is not empty (bot detected), you won't need to verify the positive CAPTCHA, which would require a HTTPS request to Google ReCaptcha before computing the response.
Here are some ideas how to hide honeypot fields by JavaScript and/or CSS:
@@ -570,7 +572,7 @@ NOTE: _When sanitizing, protecting or verifying something, prefer whitelists ove
A blacklist can be a list of bad e-mail addresses, non-public actions or bad HTML tags. This is opposed to a whitelist which lists the good e-mail addresses, public actions, good HTML tags and so on. Although sometimes it is not possible to create a whitelist (in a SPAM filter, for example), _prefer to use whitelist approaches_:
-* Use before_action only: [...] instead of except: [...]. This way you don't forget to turn it off for newly added actions.
+* Use before_action except: [...] instead of only: [...] for security-related actions. This way you don't forget to enable security checks for newly added actions.
* Allow &lt;strong&gt; instead of removing &lt;script&gt; against Cross-Site Scripting (XSS). See below for details.
* Don't try to correct user input by blacklists:
* This will make the attack work: "&lt;sc&lt;script&gt;ript&gt;".gsub("&lt;script&gt;", "")
@@ -710,7 +712,7 @@ The log files on www.attacker.com will read like this:
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.
+You can mitigate these attacks (in the obvious way) by adding the **httpOnly** 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](https://www.owasp.org/index.php/HTTPOnly#Browsers_Supporting_HttpOnly), though.
##### Defacement
@@ -923,7 +925,7 @@ HTTP/1.1 200 OK [Second New response created by attacker begins]
Content-Type: text/html
-&lt;html&gt;&lt;font color=red&gt;hey&lt;/font&gt;&lt;/html&gt; [Arbitary malicious input is
+&lt;html&gt;&lt;font color=red&gt;hey&lt;/font&gt;&lt;/html&gt; [Arbitrary malicious input is
Keep-Alive: timeout=15, max=100 shown as the redirected page]
Connection: Keep-Alive
Transfer-Encoding: chunked
@@ -969,7 +971,7 @@ request:
| `{ "person": [null, null, ...] }` | `{ :person => [] }` |
| `{ "person": ["foo", null] }` | `{ :person => ["foo"] }` |
-It is possible to return to old behaviour and disable `deep_munge` configuring
+It is possible to return to old behavior and disable `deep_munge` configuring
your application if you are aware of the risk and know how to handle it:
```ruby
@@ -1029,7 +1031,7 @@ 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:
-* The Ruby on Rails security project posts security news regularly: [http://www.rorsecurity.info](http://www.rorsecurity.info)
* Subscribe to the Rails security [mailing list](http://groups.google.com/group/rubyonrails-security)
* [Keep up to date on the other application layers](http://secunia.com/) (they have a weekly newsletter, too)
-* A [good security blog](http://ha.ckers.org/blog/) including the [Cross-Site scripting Cheat Sheet](http://ha.ckers.org/xss.html)
+* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet)
+
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 21b0b37efa..230e8162f3 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
A Guide to Testing Rails Applications
=====================================
@@ -59,9 +59,9 @@ You can find comprehensive documentation in the [Fixtures API documentation](htt
#### 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.
+_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 and 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.
+You'll find fixtures under your `test/fixtures` directory. When you run `rails generate model` to create a new model, Rails automatically creates fixture stubs in this directory.
#### YAML
@@ -82,7 +82,7 @@ steve:
profession: guy with keyboard
```
-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.
+Each fixture is given a name followed by an indented list of colon-separated key/value pairs. Records are typically separated by a blank line. You can place comments in a fixture file by using the # character in the first column.
If you are working with [associations](/association_basics.html), you can simply
define a reference node between two different fixtures. Here's an example with
@@ -120,9 +120,9 @@ user_<%= n %>:
Rails by default automatically loads all fixtures from the `test/fixtures` directory for your models and controllers test. Loading involves three steps:
-* Remove any existing data from the table corresponding to the fixture
-* Load the fixture data into the table
-* Dump the fixture data into a method in case you want to access it directly
+1. Remove any existing data from the table corresponding to the fixture
+2. Load the fixture data into the table
+3. Dump the fixture data into a method in case you want to access it directly
TIP: In order to remove existing data from the database, Rails tries to disable referential integrity triggers (like foreign keys and check constraints). If you are getting annoying permission errors on running tests, make sure the database user has privilege to disable these triggers in testing environment. (In PostgreSQL, only superusers can disable all triggers. Read more about PostgreSQL permissions [here](http://blog.endpoint.com/2012/10/postgres-system-triggers-error.html))
@@ -138,35 +138,26 @@ users(:david)
users(:david).id
# one can also access methods available on the User class
-email(david.girlfriend.email, david.location_tonight)
+email(david.partner.email, david.location_tonight)
```
-### Rake Tasks for Running your Tests
-
-Rails comes with a number of built-in rake tasks to help with testing. The
-table below lists the commands included in the default Rakefile when a Rails
-project is created.
-
-| Tasks | Description |
-| ----------------------- | ----------- |
-| `rake test` | Runs all tests in the `test` directory. You can also run `rake` and Rails will run all tests by default |
-| `rake test:controllers` | Runs all the controller tests from `test/controllers` |
-| `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional` |
-| `rake test:helpers` | Runs all the helper tests from `test/helpers` |
-| `rake test:integration` | Runs all the integration tests from `test/integration` |
-| `rake test:jobs` | Runs all the job tests from `test/jobs` |
-| `rake test:mailers` | Runs all the mailer tests from `test/mailers` |
-| `rake test:models` | Runs all the model tests from `test/models` |
-| `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit` |
-| `rake test:db` | Runs all tests in the `test` directory and resets the db |
+### Console Tasks for Running your Tests
+
+Rails comes with a CLI command to run tests.
+Here are some examples of how to use it:
+
+```bash
+$ bin/rails test # run all tests in the `test` directory
+$ bin/rails test test/controllers # run all tests from specific directory
+$ bin/rails test test/models/post_test.rb # run specific test
+$ bin/rails test test/models/post_test.rb:44 # run specific test and line
+```
We will cover each of types Rails tests listed above in this guide.
-Unit Testing your Models
+Model Testing
------------------------
-In Rails, unit tests are what you write to test your models.
-
For this guide we will be using the application we built in the [Getting Started with Rails](getting_started.html) guide.
If you remember when you used the `rails generate scaffold` command from earlier. We created our first resource among other things it created a test stub in the `test/models` directory:
@@ -259,10 +250,10 @@ be rebuilt. This can be done by executing `bin/rake db:test:prepare`.
### Running Tests
-Running a test is as simple as invoking the file containing the test cases through `rake test` command.
+Running a test is as simple as invoking the file containing the test cases through `rails test` command.
```bash
-$ bin/rake test test/models/article_test.rb
+$ bin/rails test test/models/article_test.rb
.
Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
@@ -270,10 +261,12 @@ Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
```
+This will run all test methods from the test case.
+
You can also run a particular test method from the test case by running the test and providing the `test method name`.
```bash
-$ bin/rake test test/models/article_test.rb test_the_truth
+$ bin/rails test test/models/article_test.rb test_the_truth
.
Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
@@ -281,8 +274,6 @@ Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
```
-This will run all test methods from the test case.
-
The `.` (dot) above indicates a passing test. When a test fails you see an `F`; when a test throws an error you see an `E` in its place. The last line of the output is the summary.
#### Your first failing test
@@ -296,10 +287,10 @@ test "should not save article without title" do
end
```
-Let us run this newly added test.
+Let us run this newly added test (where `6` is the number of line where the test is defined).
```bash
-$ bin/rake test test/models/article_test.rb test_should_not_save_article_without_title
+$ bin/rails test test/models/article_test.rb:6
F
Finished tests in 0.044632s, 22.4054 tests/s, 22.4054 assertions/s.
@@ -339,7 +330,7 @@ end
Now the test should pass. Let us verify by running the test again:
```bash
-$ bin/rake test test/models/article_test.rb test_should_not_save_article_without_title
+$ bin/rails test test/models/article_test.rb:6
.
Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
@@ -347,7 +338,11 @@ Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
```
-Now, if you noticed, we first wrote a test which fails for a desired functionality, then we wrote some code which adds the functionality and finally we ensured that our test passes. This approach to software development is referred to as _Test-Driven Development_ (TDD).
+Now, if you noticed, we first wrote a test which fails for a desired
+functionality, then we wrote some code which adds the functionality and finally
+we ensured that our test passes. This approach to software development is
+referred to as
+[_Test-Driven Development_ (TDD)](http://c2.com/cgi/wiki?TestDrivenDevelopment).
#### What an error looks like
@@ -364,7 +359,7 @@ end
Now you can see even more output in the console from running the tests:
```bash
-$ bin/rake test test/models/article_test.rb test_should_report_error
+$ bin/rails test test/models/article_test.rb
E
Finished tests in 0.030974s, 32.2851 tests/s, 0.0000 assertions/s.
@@ -379,17 +374,20 @@ NameError: undefined local variable or method `some_undefined_variable' for #<Ar
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.
+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 random order. The
+[`config.active_support.test_order` option](configuring.html#configuring-active-support)
+can be used to configure test order.
When a test fails you are presented with the corresponding backtrace. By default
Rails filters that backtrace and will only print lines relevant to your
application. This eliminates the framework noise and helps to focus on your
code. However there are situations when you want to see the full
-backtrace. simply set the `BACKTRACE` environment variable to enable this
-behavior:
+backtrace. Simply set the `-b` (or `--backtrace`) argument to enable this behavior:
```bash
-$ BACKTRACE=1 bin/rake test test/models/article_test.rb
+$ bin/rails test -b test/models/article_test.rb
```
If we want this test to pass we can modify it to use `assert_raises` like so:
@@ -409,9 +407,49 @@ This test should now pass.
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.
-There are a bunch of different types of assertions you can use that come with [`Minitest`](https://github.com/seattlerb/minitest), the default testing library used by Rails.
-
-For a list of all available assertions please check the [Minitest API documentation](http://docs.seattlerb.org/minitest/), specifically [`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html)
+Here's an extract of the assertions you can use with
+[`Minitest`](https://github.com/seattlerb/minitest), the default testing library
+used by Rails. The `[msg]` parameter is an optional string message you can
+specify to make your test failure messages clearer. It's not required.
+
+| Assertion | Purpose |
+| ---------------------------------------------------------------- | ------- |
+| `assert( test, [msg] )` | Ensures that `test` is true.|
+| `assert_not( test, [msg] )` | Ensures that `test` is false.|
+| `assert_equal( expected, actual, [msg] )` | Ensures that `expected == actual` is true.|
+| `assert_not_equal( expected, actual, [msg] )` | Ensures that `expected != actual` is true.|
+| `assert_same( expected, actual, [msg] )` | Ensures that `expected.equal?(actual)` is true.|
+| `assert_not_same( expected, actual, [msg] )` | Ensures that `expected.equal?(actual)` is false.|
+| `assert_nil( obj, [msg] )` | Ensures that `obj.nil?` is true.|
+| `assert_not_nil( obj, [msg] )` | Ensures that `obj.nil?` is false.|
+| `assert_empty( obj, [msg] )` | Ensures that `obj` is `empty?`.|
+| `assert_not_empty( obj, [msg] )` | Ensures that `obj` is not `empty?`.|
+| `assert_match( regexp, string, [msg] )` | Ensures that a string matches the regular expression.|
+| `assert_no_match( regexp, string, [msg] )` | Ensures that a string doesn't match the regular expression.|
+| `assert_includes( collection, obj, [msg] )` | Ensures that `obj` is in `collection`.|
+| `assert_not_includes( collection, obj, [msg] )` | Ensures that `obj` is not in `collection`.|
+| `assert_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are within `delta` of each other.|
+| `assert_not_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are not within `delta` of each other.|
+| `assert_throws( symbol, [msg] ) { block }` | Ensures that the given block throws the symbol.|
+| `assert_raises( exception1, exception2, ... ) { block }` | Ensures that the given block raises one of the given exceptions.|
+| `assert_nothing_raised( exception1, exception2, ... ) { block }` | Ensures that the given block doesn't raise one of the given exceptions.|
+| `assert_instance_of( class, obj, [msg] )` | Ensures that `obj` is an instance of `class`.|
+| `assert_not_instance_of( class, obj, [msg] )` | Ensures that `obj` is not an instance of `class`.|
+| `assert_kind_of( class, obj, [msg] )` | Ensures that `obj` is an instance of `class` or is descending from it.|
+| `assert_not_kind_of( class, obj, [msg] )` | Ensures that `obj` is not an instance of `class` and is not descending from it.|
+| `assert_respond_to( obj, symbol, [msg] )` | Ensures that `obj` responds to `symbol`.|
+| `assert_not_respond_to( obj, symbol, [msg] )` | Ensures that `obj` does not respond to `symbol`.|
+| `assert_operator( obj1, operator, [obj2], [msg] )` | Ensures that `obj1.operator(obj2)` is true.|
+| `assert_not_operator( obj1, operator, [obj2], [msg] )` | Ensures that `obj1.operator(obj2)` is false.|
+| `assert_predicate ( obj, predicate, [msg] )` | Ensures that `obj.predicate` is true, e.g. `assert_predicate str, :empty?`|
+| `assert_not_predicate ( obj, predicate, [msg] )` | Ensures that `obj.predicate` is false, e.g. `assert_not_predicate str, :empty?`|
+| `assert_send( array, [msg] )` | Ensures that executing the method listed in `array[1]` on the object in `array[0]` with the parameters of `array[2 and up]` is true. This one is weird eh?|
+| `flunk( [msg] )` | Ensures failure. This is useful to explicitly mark a test that isn't finished yet.|
+
+The above are a subset of assertions that minitest supports. For an exhaustive &
+more up-to-date list, please check
+[Minitest API documentation](http://docs.seattlerb.org/minitest/), specifically
+[`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html)
Because of the modular nature of the testing framework, it is possible to create your own assertions. In fact, that's exactly what Rails does. It includes some specialized assertions to make your life easier.
@@ -424,12 +462,11 @@ Rails adds some custom assertions of its own to the `minitest` framework:
| Assertion | Purpose |
| --------------------------------------------------------------------------------- | ------- |
| `assert_difference(expressions, difference = 1, message = nil) {...}` | Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.|
-| `assert_no_difference(expressions, message = nil, &amp;block)` | Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.|
+| `assert_no_difference(expressions, message = nil, &block)` | Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.|
| `assert_recognizes(expected_options, path, extras={}, message=nil)` | Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.|
| `assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)` | Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.|
| `assert_response(type, message = nil)` | Asserts that the response comes with a specific status code. You can specify `:success` to indicate 200-299, `:redirect` to indicate 300-399, `:missing` to indicate 404, or `:error` to match the 500-599 range. You can also pass an explicit status number or its symbolic equivalent. For more information, see [full list of status codes](http://rubydoc.info/github/rack/rack/master/Rack/Utils#HTTP_STATUS_CODES-constant) and how their [mapping](http://rubydoc.info/github/rack/rack/master/Rack/Utils#SYMBOL_TO_STATUS_CODE-constant) works.|
| `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on. You can also pass named routes such as `assert_redirected_to root_path` and Active Record objects such as `assert_redirected_to @article`.|
-| `assert_template(expected = nil, message=nil)` | Asserts that the request was rendered with the appropriate template file.|
You'll see the usage of some of these assertions in the next chapter.
@@ -442,10 +479,11 @@ All the basic assertions such as `assert_equal` defined in `Minitest::Assertions
* `ActionMailer::TestCase`
* `ActionView::TestCase`
* `ActionDispatch::IntegrationTest`
+* `ActiveJob::TestCase`
Each of these classes include `Minitest::Assertions`, allowing us to use all of the basic assertions in our tests.
-NOTE: For more information on `Minitest`, refer to [Minitest](http://ruby-doc.org/stdlib-2.1.0/libdoc/minitest/rdoc/MiniTest.html)
+NOTE: For more information on `Minitest`, refer to [Minitest](http://docs.seattlerb.org/minitest)
Functional Tests for Your Controllers
-------------------------------------
@@ -467,34 +505,43 @@ Now that we have used Rails scaffold generator for our `Article` resource, it ha
Let me take you through one such test, `test_should_get_index` from the file `articles_controller_test.rb`.
```ruby
+# articles_controller_test.rb
class ArticlesControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
- assert_not_nil assigns(:articles)
+ assert_includes @response.body, 'Articles'
end
end
```
-In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful and also ensuring that it assigns a valid `articles` instance variable.
+In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful
+and also ensuring that the right response body has been generated.
The `get` method kicks off the web request and populates the results into the response. It accepts 4 arguments:
-* The action of the controller you are requesting. This can be in the form of a string or a symbol.
-* An optional hash of request parameters to pass into the action (eg. query string parameters or article variables).
-* An optional hash of session variables to pass along with the request.
-* An optional hash of flash values.
+* The action of the controller you are requesting.
+ This can be in the form of a string or a symbol.
+
+* `params`: option with a hash of request parameters to pass into the action
+ (e.g. query string parameters or article variables).
+
+* `session`: option with a hash of session variables to pass along with the request.
+
+* `flash`: option with a hash of flash values.
+
+All the keyword arguments are optional.
Example: Calling the `:show` action, passing an `id` of 12 as the `params` and setting a `user_id` of 5 in the session:
```ruby
-get(:show, {'id' => "12"}, {'user_id' => 5})
+get(:show, params: { id: 12 }, session: { user_id: 5 })
```
Another example: Calling the `:view` action, passing an `id` of 12 as the `params`, this time with no session, but with a flash message.
```ruby
-get(:view, {'id' => '12'}, nil, {'message' => 'booya!'})
+get(:view, params: { id: 12 }, flash: { message: 'booya!' })
```
NOTE: If you try running `test_should_create_article` test from `articles_controller_test.rb` it will fail on account of the newly added model level validation and rightly so.
@@ -504,10 +551,10 @@ Let us modify `test_should_create_article` test in `articles_controller_test.rb`
```ruby
test "should create article" do
assert_difference('Article.count') do
- post :create, article: {title: 'Some title'}
+ post :create, params: { article: { title: 'Some title' } }
end
- assert_redirected_to article_path(assigns(:article))
+ assert_redirected_to article_path(Article.last)
end
```
@@ -528,24 +575,34 @@ All of request types have equivalent methods that you can use. In a typical C.R.
NOTE: Functional tests do not verify whether the specified request type is accepted by the action, we're more concerned with the result. Request tests exist for this use case to make your tests more purposeful.
+### Testing XHR (AJAX) requests
+
+To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
+`patch`, `put`, and `delete` methods:
+
+```ruby
+test "ajax request" do
+ get :show, params: { id: articles(:first).id }, xhr: true
+
+ assert_equal 'hello world', @response.body
+ assert_equal "text/javascript", @response.content_type
+end
+```
+
### The Four Hashes of the Apocalypse
After a request has been made and processed, you will have 4 Hash objects ready for use:
-* `assigns` - Any objects that are stored as instance variables in actions for use in views.
* `cookies` - Any cookies that are set.
* `flash` - Any objects living in the flash.
* `session` - Any object living in session variables.
-As is the case with normal Hash objects, you can access the values by referencing the keys by string. You can also reference them by symbol name, except for `assigns`. For example:
+As is the case with normal Hash objects, you can access the values by referencing the keys by string. You can also reference them by symbol name. For example:
```ruby
flash["gordon"] flash[:gordon]
session["shmession"] session[:shmession]
cookies["are_good_for_u"] cookies[:are_good_for_u]
-
-# Because you can't use assigns[:something] for historical reasons:
-assigns["something"] assigns(:something)
```
### Instance Variables Available
@@ -573,46 +630,6 @@ get :index # simulate the request with custom header
post :create # simulate the request with custom env variable
```
-### Testing Templates and Layouts
-
-Eventually, you may want to test whether a specific layout is rendered in the view of a response.
-
-#### Asserting Templates
-
-If you want to make sure that the response rendered the correct template and layout, you can use the `assert_template`
-method:
-
-```ruby
-test "index should render correct template and layout" do
- get :index
- assert_template :index
- assert_template layout: "layouts/application"
-
- # You can also pass a regular expression.
- assert_template layout: /layouts\/application/
-end
-```
-
-NOTE: You cannot test for template and layout at the same time, with a single call to `assert_template`.
-
-WARNING: You must include the "layouts" directory name even if you save your layout file in this standard layout directory. Hence, `assert_template layout: "application"` will not work.
-
-#### Asserting Partials
-
-If your view renders any partial, when asserting for the layout, you can to assert for the partial at the same time.
-Otherwise, assertion will fail.
-
-Remember, we added the "_form" partial to our creating Articles view? Let's write an assertion for that in the `:new` action now:
-
-```ruby
-test "new should render correct layout" do
- get :new
- assert_template layout: "layouts/application", partial: "_form"
-end
-```
-
-This is the correct way to assert for when the view renders a partial with a given name. As identified by the `:partial` key passed to the `assert_template` call.
-
### Testing `flash` notices
If you remember from earlier one of the Four Hashes of the Apocalypse was `flash`.
@@ -625,10 +642,10 @@ Let's start by adding this assertion to our `test_should_create_article` test:
```ruby
test "should create article" do
assert_difference('Article.count') do
- post :create, article: {title: 'Some title'}
+ post :create, params: { article: { title: 'Some title' } }
end
- assert_redirected_to article_path(assigns(:article))
+ assert_redirected_to article_path(Article.last)
assert_equal 'Article was successfully created.', flash[:notice]
end
```
@@ -636,7 +653,7 @@ end
If we run our test now, we should see a failure:
```bash
-$ bin/rake test test/controllers/articles_controller_test.rb test_should_create_article
+$ bin/rails test test/controllers/articles_controller_test.rb test_should_create_article
Run options: -n test_should_create_article --seed 32266
# Running:
@@ -674,7 +691,7 @@ end
Now if we run our tests, we should see it pass:
```bash
-$ bin/rake test test/controllers/articles_controller_test.rb test_should_create_article
+$ bin/rails test test/controllers/articles_controller_test.rb test_should_create_article
Run options: -n test_should_create_article --seed 18981
# Running:
@@ -695,7 +712,7 @@ Let's write a test for the `:show` action:
```ruby
test "should show article" do
article = articles(:one)
- get :show, id: article.id
+ get :show, params: { id: article.id }
assert_response :success
end
```
@@ -708,7 +725,7 @@ How about deleting an existing Article?
test "should destroy article" do
article = articles(:one)
assert_difference('Article.count', -1) do
- delete :destroy, id: article.id
+ delete :destroy, params: { id: article.id }
end
assert_redirected_to articles_path
@@ -720,8 +737,8 @@ We can also add a test for updating an existing Article.
```ruby
test "should update article" do
article = articles(:one)
- patch :update, id: article.id, article: {title: "updated"}
- assert_redirected_to article_path(assigns(:article))
+ patch :update, params: { id: article.id, article: { title: "updated" } }
+ assert_redirected_to article_path(article)
end
```
@@ -740,35 +757,67 @@ class ArticlesControllerTest < ActionController::TestCase
# called after every single test
def teardown
- # as we are re-initializing @article before every test
- # setting it to nil here is not essential but I hope
- # you understand how you can use the teardown method
- @article = nil
+ # when controller is using cache it may be a good idea to reset it afterwards
+ Rails.cache.clear
end
test "should show article" do
# Reuse the @article instance variable from setup
- get :show, id: @article.id
+ get :show, params: { id: @article.id }
assert_response :success
end
test "should destroy article" do
assert_difference('Article.count', -1) do
- delete :destroy, id: @article.id
+ delete :destroy, params: { id: @article.id }
end
assert_redirected_to articles_path
end
test "should update article" do
- patch :update, id: @article.id, article: {title: "updated"}
- assert_redirected_to article_path(assigns(:article))
+ patch :update, params: { id: @article.id, article: { title: "updated" } }
+ assert_redirected_to article_path(@article)
end
end
```
Similar to other callbacks in Rails, the `setup` and `teardown` methods can also be used by passing a block, lambda, or method name as a symbol to call.
+### Test helpers
+
+To avoid code duplication, you can add your own test helpers.
+Sign in helper can be a good example:
+
+```ruby
+test/test_helper.rb
+
+module SignInHelper
+ def sign_in(user)
+ session[:user_id] = user.id
+ end
+end
+
+class ActionController::TestCase
+ include SignInHelper
+end
+```
+
+```ruby
+require 'test_helper'
+
+class ProfileControllerTest < ActionController::TestCase
+
+ test "should show profile" do
+ # helper is now reusable from any controller test case
+ sign_in users(:david)
+
+ get :show
+ assert_response :success
+ end
+end
+```
+
Testing Routes
--------------
@@ -789,7 +838,7 @@ end
I've added this file here `test/controllers/articles_routes_test.rb` and if we run the test we should see:
```bash
-$ bin/rake test test/controllers/articles_routes_test.rb
+$ bin/rails test test/controllers/articles_routes_test.rb
# Running:
@@ -805,7 +854,7 @@ For more information on routing assertions available in Rails, see the API docum
Testing Views
-------------
-Testing the response to your request by asserting the presence of key HTML elements and their content is a common way to test the views of your application. The `assert_select` method allows you to query HTML elements of the response by using a simple yet powerful syntax.
+Testing the response to your request by asserting the presence of key HTML elements and their content is a common way to test the views of your application. Like route tests, view tests reside in `test/controllers/` or are part of controller tests. The `assert_select` method allows you to query HTML elements of the response by using a simple yet powerful syntax.
There are two forms of `assert_select`:
@@ -866,7 +915,7 @@ assert_select_email do
end
```
-Testing helpers
+Testing Helpers
---------------
In order to test helpers, all you need to do is check that the output of the
@@ -978,13 +1027,12 @@ How about testing our ability to create a new article in our blog and see the re
test "can create an article" do
get "/articles/new"
assert_response :success
- assert_template "articles/new", partial: "articles/_form"
- post "/articles", article: {title: "can create", body: "article successfully."}
+ post "/articles",
+ params: { article: { title: "can create", body: "article successfully." } }
assert_response :redirect
follow_redirect!
assert_response :success
- assert_template "articles/show"
assert_select "p", "Title:\n can create"
end
```
@@ -996,7 +1044,8 @@ We start by calling the `:new` action on our Articles controller. This response
After this we make a post request to the `:create` action of our Articles controller:
```ruby
-post "/articles", article: {title: "can create", body: "article successfully."}
+post "/articles",
+ params: { article: { title: "can create", body: "article successfully." } }
assert_response :redirect
follow_redirect!
```
@@ -1018,7 +1067,7 @@ Testing mailer classes requires some specific tools to do a thorough job.
### 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.
+Your mailer classes - like every other part of your Rails application - should be tested to ensure that they are working as expected.
The goals of testing your mailer classes are to ensure that:
@@ -1050,9 +1099,10 @@ require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
test "invite" do
# Send the email, then test that it got queued
- email = UserMailer.create_invite('me@example.com',
- 'friend@example.com', Time.now).deliver_now
- assert_not ActionMailer::Base.deliveries.empty?
+ assert_emails 1 do
+ email = UserMailer.create_invite('me@example.com',
+ 'friend@example.com', Time.now).deliver_now
+ end
# Test the body of the sent email contains what we expect it to
assert_equal ['me@example.com'], email.from
@@ -1100,7 +1150,7 @@ require 'test_helper'
class UserControllerTest < ActionController::TestCase
test "invite friend" do
assert_difference 'ActionMailer::Base.deliveries.size', +1 do
- post :invite_friend, email: 'friend@example.com'
+ post :invite_friend, params: { email: 'friend@example.com' }
end
invite_email = ActionMailer::Base.deliveries.last
@@ -1154,7 +1204,7 @@ within a model:
```ruby
require 'test_helper'
-class ProductTest < ActiveSupport::TestCase
+class ProductTest < ActiveJob::TestCase
test 'billing job scheduling' do
assert_enqueued_with(job: BillingJob) do
product.charge(account)
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index c0c94475e0..17309d4b47 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
A Guide for Upgrading Ruby on Rails
===================================
@@ -20,7 +20,7 @@ The best way to be sure that your application still works after upgrading is to
Rails generally stays close to the latest released Ruby version when it's released:
-* Rails 5 requires Ruby 2.2 or newer.
+* Rails 5 requires Ruby 2.2.2 or newer.
* Rails 4 prefers Ruby 2.0 and requires 1.9.3 or newer.
* Rails 3.2.x is the last branch to support Ruby 1.8.7.
* Rails 3 and above require Ruby 1.8.7 or higher. Support for all of the previous Ruby versions has been dropped officially. You should upgrade as early as possible.
@@ -75,6 +75,23 @@ warning by adding the following configuration to your `config/application.rb`:
See [#17227](https://github.com/rails/rails/pull/17227) for more details.
+### ActiveJob jobs now inherent from ApplicationJob by default
+
+In Rails 4.2 an ActiveJob inherits from `ActiveJob::Base`. In Rails 5.0 this
+behavior has changed to now inherit from `ApplicationJob`.
+
+When upgrading from Rails 4.2 to Rails 5.0 you need to create an
+`application_job.rb` file in `app/jobs/` and add the following content:
+
+```
+class ApplicationJob < ActiveJob::Base
+end
+```
+
+Then make sure that all your job classes inherit from it.
+
+See [#19034](https://github.com/rails/rails/pull/19034) for more details.
+
Upgrading from Rails 4.1 to Rails 4.2
-------------------------------------
@@ -276,6 +293,22 @@ class Notifier < ActionMailer::Base
end
```
+### Foreign Key Support
+
+The migration DSL has been expanded to support foreign key definitions. If
+you've been using the Foreigner gem, you might want to consider removing it.
+Note that the foreign key support of Rails is a subset of Foreigner. This means
+that not every Foreigner definition can be fully replaced by its Rails
+migration DSL counterpart.
+
+The migration procedure is as follows:
+
+1. remove `gem "foreigner"` from the Gemfile.
+2. run `bundle install`.
+3. run `bin/rake db:schema:dump`.
+4. make sure that `db/schema.rb` contains every foreign key definition with
+the necessary options.
+
Upgrading from Rails 4.0 to Rails 4.1
-------------------------------------
@@ -427,7 +460,7 @@ If your application currently depend on MultiJSON directly, you have a few optio
WARNING: Do not simply replace `MultiJson.dump` and `MultiJson.load` with
`JSON.dump` and `JSON.load`. These JSON gem APIs are meant for serializing and
-deserializing arbitrary Ruby objects and are generally [unsafe](http://www.ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-load).
+deserializing arbitrary Ruby objects and are generally [unsafe](http://www.ruby-doc.org/stdlib-2.2.2/libdoc/json/rdoc/JSON.html#method-i-load).
#### JSON gem compatibility
@@ -534,7 +567,7 @@ module FixtureFileHelpers
Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
end
end
-ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers
+ActiveRecord::FixtureSet.context_class.include FixtureFileHelpers
```
### I18n enforcing available locales
@@ -850,6 +883,20 @@ this gem such as `whitelist_attributes` or `mass_assignment_sanitizer` options.
* To re-enable the old finders, you can use the [activerecord-deprecated_finders gem](https://github.com/rails/activerecord-deprecated_finders).
+* Rails 4.0 has changed to default join table for `has_and_belongs_to_many` relations to strip the common prefix off the second table name. Any existing `has_and_belongs_to_many` relationship between models with a common prefix must be specified with the `join_table` option. For example:
+
+```ruby
+CatalogCategory < ActiveRecord::Base
+ has_and_belongs_to_many :catalog_products, join_table: 'catalog_categories_catalog_products'
+end
+
+CatalogProduct < ActiveRecord::Base
+ has_and_belongs_to_many :catalog_categories, join_table: 'catalog_categories_catalog_products'
+end
+```
+
+* Note that the the prefix takes scopes into account as well, so relations between `Catalog::Category` and `Catalog::Product` or `Catalog::Category` and `CatalogProduct` need to be updated similarly.
+
### Active Resource
Rails 4.0 extracted Active Resource to its own gem. If you still need the feature you can add the [Active Resource gem](https://github.com/rails/activeresource) in your Gemfile.
@@ -879,7 +926,7 @@ Rails 4.0 extracted Active Resource to its own gem. If you still need the featur
Please note that you should wait to set `secret_key_base` until you have 100% of your userbase on Rails 4.x and are reasonably sure you will not need to rollback to Rails 3.x. This is because cookies signed based on the new `secret_key_base` in Rails 4.x are not backwards compatible with Rails 3.x. You are free to leave your existing `secret_token` in place, not set the new `secret_key_base`, and ignore the deprecation warnings until you are reasonably sure that your upgrade is otherwise complete.
-If you are relying on the ability for external applications or Javascript to be able to read your Rails app's signed session cookies (or signed cookies in general) you should not set `secret_key_base` until you have decoupled these concerns.
+If you are relying on the ability for external applications or JavaScript to be able to read your Rails app's signed session cookies (or signed cookies in general) you should not set `secret_key_base` until you have decoupled these concerns.
* Rails 4.0 encrypts the contents of cookie-based sessions if `secret_key_base` has been set. Rails 3.x signed, but did not encrypt, the contents of cookie-based session. Signed cookies are "secure" in that they are verified to have been generated by your app and are tamper-proof. However, the contents can be viewed by end users, and encrypting the contents eliminates this caveat/concern without a significant performance penalty.
@@ -893,6 +940,8 @@ Please read [Pull Request #9978](https://github.com/rails/rails/pull/9978) for d
* Rails 4.0 has removed the XML parameters parser. You will need to add the `actionpack-xml_parser` gem if you require this feature.
+* Rails 4.0 changes the default `layout` lookup set using symbols or procs that return nil. To get the "no layout" behavior, return false instead of nil.
+
* Rails 4.0 changes the default memcached client from `memcache-client` to `dalli`. To upgrade, simply add `gem 'dalli'` to your `Gemfile`.
* Rails 4.0 deprecates the `dom_id` and `dom_class` methods in controllers (they are fine in views). You will need to include the `ActionView::RecordIdentifier` module in controllers requiring this feature.
diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md
index 5131f809d7..f3d3a83afc 100644
--- a/guides/source/working_with_javascript_in_rails.md
+++ b/guides/source/working_with_javascript_in_rails.md
@@ -1,4 +1,4 @@
-**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON http://guides.rubyonrails.org.**
Working with JavaScript in Rails
================================
@@ -357,7 +357,7 @@ This gem uses Ajax to speed up page rendering in most applications.
Turbolinks attaches a click handler to all `<a>` on the page. If your browser
supports
-[PushState](https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history#The_pushState(\).C2.A0method),
+[PushState](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#The_pushState()_method),
Turbolinks will make an Ajax request for the page, parse the response, and
replace the entire `<body>` of the page with the `<body>` of the response. It
will then use PushState to change the URL to the correct one, preserving