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.md2
-rw-r--r--guides/source/3_0_release_notes.md2
-rw-r--r--guides/source/3_1_release_notes.md2
-rw-r--r--guides/source/3_2_release_notes.md2
-rw-r--r--guides/source/4_0_release_notes.md2
-rw-r--r--guides/source/4_1_release_notes.md2
-rw-r--r--guides/source/4_2_release_notes.md105
-rw-r--r--guides/source/_welcome.html.erb9
-rw-r--r--guides/source/action_controller_overview.md70
-rw-r--r--guides/source/action_mailer_basics.md22
-rw-r--r--guides/source/action_view_overview.md2
-rw-r--r--guides/source/active_job_basics.md8
-rw-r--r--guides/source/active_model_basics.md2
-rw-r--r--guides/source/active_record_basics.md4
-rw-r--r--guides/source/active_record_callbacks.md2
-rw-r--r--guides/source/active_record_migrations.md10
-rw-r--r--guides/source/active_record_postgresql.md5
-rw-r--r--guides/source/active_record_querying.md64
-rw-r--r--guides/source/active_record_validations.md4
-rw-r--r--guides/source/active_support_core_extensions.md22
-rw-r--r--guides/source/active_support_instrumentation.md2
-rw-r--r--guides/source/api_documentation_guidelines.md2
-rw-r--r--guides/source/asset_pipeline.md29
-rw-r--r--guides/source/association_basics.md49
-rw-r--r--guides/source/autoloading_and_reloading_constants.md1300
-rw-r--r--guides/source/caching_with_rails.md4
-rw-r--r--guides/source/command_line.md30
-rw-r--r--guides/source/configuring.md8
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md13
-rw-r--r--guides/source/debugging_rails_applications.md14
-rw-r--r--guides/source/development_dependencies_install.md2
-rw-r--r--guides/source/documents.yaml28
-rw-r--r--guides/source/engines.md2
-rw-r--r--guides/source/form_helpers.md2
-rw-r--r--guides/source/generators.md10
-rw-r--r--guides/source/getting_started.md87
-rw-r--r--guides/source/i18n.md4
-rw-r--r--guides/source/initialization.md2
-rw-r--r--guides/source/layouts_and_rendering.md46
-rw-r--r--guides/source/maintenance_policy.md2
-rw-r--r--guides/source/nested_model_forms.md2
-rw-r--r--guides/source/plugins.md4
-rw-r--r--guides/source/profiling.md16
-rw-r--r--guides/source/rails_application_templates.md2
-rw-r--r--guides/source/rails_on_rack.md4
-rw-r--r--guides/source/routing.md2
-rw-r--r--guides/source/ruby_on_rails_guides_guidelines.md2
-rw-r--r--guides/source/security.md14
-rw-r--r--guides/source/testing.md720
-rw-r--r--guides/source/upgrading_ruby_on_rails.md51
-rw-r--r--guides/source/working_with_javascript_in_rails.md2
52 files changed, 2198 insertions, 600 deletions
diff --git a/guides/source/2_2_release_notes.md b/guides/source/2_2_release_notes.md
index b11aaa15a8..019da08687 100644
--- a/guides/source/2_2_release_notes.md
+++ b/guides/source/2_2_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN 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 20566c9155..4ac1529e76 100644
--- a/guides/source/2_3_release_notes.md
+++ b/guides/source/2_3_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails 2.3 Release Notes
===============================
diff --git a/guides/source/3_0_release_notes.md b/guides/source/3_0_release_notes.md
index e985f1ab4b..3d7966e50b 100644
--- a/guides/source/3_0_release_notes.md
+++ b/guides/source/3_0_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN 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 b7ed285b96..8728750966 100644
--- a/guides/source/3_1_release_notes.md
+++ b/guides/source/3_1_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails 3.1 Release Notes
===============================
diff --git a/guides/source/3_2_release_notes.md b/guides/source/3_2_release_notes.md
index c5db0262e9..0b28aac9ce 100644
--- a/guides/source/3_2_release_notes.md
+++ b/guides/source/3_2_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN 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 84a65df2bc..5f52c33746 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails 4.0 Release Notes
===============================
diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md
index c7877a9cb5..dbc151c0ca 100644
--- a/guides/source/4_1_release_notes.md
+++ b/guides/source/4_1_release_notes.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails 4.1 Release Notes
===============================
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index c3803aa856..e8ddfcc9e2 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -1,10 +1,12 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails 4.2 Release Notes
===============================
Highlights in Rails 4.2:
* Active Job
-* Asynchronous Mails
+* Asynchronous mails
* Adequate Record
* Web Console
* Foreign key support
@@ -41,13 +43,22 @@ Jobs written with the Active Job API run on any of the supported queues thanks
to their respective adapters. Active Job comes pre-configured with an inline
runner that executes jobs right away.
-Jobs often need to take Active Record objects as arguments, but we can't pass
-fully-marshaled Ruby objects through many queueing systems. Active Job passes
+Jobs often need to take Active Record objects as arguments. Active Job passes
object references as URIs (uniform resource identifiers) instead of marshaling
the object itself. The new [Global ID](https://github.com/rails/globalid)
library builds URIs and looks up the objects they reference. Passing Active
-Record objects as job arguments "just works:" Active Job passes a reference to
-the object, then looks up the object from its reference.
+Record objects as job arguments just works by using Global ID internally.
+
+For example, if `trashable` is an Active Record object, then this job runs
+just fine with no serialization involved:
+
+```ruby
+class TrashableCleanupJob < ActiveJob::Base
+ def perform(trashable, depth)
+ trashable.cleanup(depth)
+ end
+end
+```
See the [Active Job Basics](active_job_basics.html) guide for more
information.
@@ -70,9 +81,9 @@ on similar calls, skipping most of the query-generation work on subsequent
calls. For more details, please refer to [Aaron Patterson's blog
post](http://tenderlovemaking.com/2014/02/19/adequaterecord-pro-like-activerecord.html).
-Active Record will automatically take advantage of this feature on the
+Active Record will automatically take advantage of this feature on
supported operations without any user involvement or code changes. Here are
-some examples of the supported operations:
+some examples of supported operations:
```ruby
Post.find(1) # First call generates and cache the prepared statement
@@ -86,10 +97,10 @@ post.comments(true)
```
It's important to highlight that, as the examples above suggest, the prepared
-statements do not cache the values passed in the method calls, they rather
+statements do not cache the values passed in the method calls; rather, they
have placeholders for them.
-The caching is not used in the following scenarios:
+Caching is not used in the following scenarios:
- The model has a default scope
- The model uses single table inheritance
@@ -109,22 +120,15 @@ The caching is not used in the following scenarios:
### Web Console
-New applications generated from Rails 4.2 now come with the Web Console gem by
-default.
-
-Web Console is a set of debugging tools for your Rails application. It adds an
-interactive console on every error page and a `console` view and controller
-helper.
-
-The interactive console on the error pages lets you execute code where the
-exception originated. It's quite handy being able to introspect the state that
-led to the error.
+New applications generated with Rails 4.2 now come with the [Web
+Console](https://github.com/rails/web-console) gem by default. Web Console adds
+an interactive Ruby console on every error page and provides a `console` view
+and controller helpers.
-The `console` view helper launches an interactive console within the context of
-the view where it is invoked.
-
-The `console` controller helper spawns an interactive console within the
-context of the controller action it was invoked in.
+The interactive console on error pages lets you execute code in the context of
+the place where the exception originated. The `console` helper, if called
+anywhere in a view or controller, launches an interactive console with the final
+context, once rendering has completed.
### Foreign Key Support
@@ -164,11 +168,11 @@ The following changes may require immediate action upon upgrade.
### `render` with a String Argument
Previously, calling `render "foo/bar"` in a controller action was equivalent to
-`render file: "foo/bar"`. In Rails 4.2, this has been changed to mean `render template: "foo/bar"`
-instead. If you need to render a file, please change your code to use the
-explicit form (`render file: "foo/bar"`) instead.
+`render file: "foo/bar"`. In Rails 4.2, this has been changed to mean
+`render template: "foo/bar"` instead. If you need to render a file, please
+change your code to use the explicit form (`render file: "foo/bar"`) instead.
-### `respond_with` / class-level `respond_to`
+### `respond_with` / Class-Level `respond_to`
`respond_with` and the corresponding class-level `respond_to` have been moved
to the [responders](https://github.com/plataformatec/responders) gem. Add
@@ -207,8 +211,9 @@ end
Due to a [change in Rack](https://github.com/rack/rack/commit/28b014484a8ac0bbb388e7eaeeef159598ec64fc),
`rails server` now listens on `localhost` instead of `0.0.0.0` by default. This
-should have minimal impact on the standard development workflow as both http://127.0.0.1:3000
-and http://localhost:3000 will continue to work as before on your own machine.
+should have minimal impact on the standard development workflow as both
+http://127.0.0.1:3000 and http://localhost:3000 will continue to work as before
+on your own machine.
However, with this change you will no longer be able to access the Rails
server from a different machine, for example if your development environment
@@ -226,8 +231,8 @@ built upon [Loofah](https://github.com/flavorjones/loofah) and
[Nokogiri](https://github.com/sparklemotion/nokogiri). The new sanitizer is
more secure and its sanitization is more powerful and flexible.
-Due to the new algorithm, sanitized output changes for certain pathological
-inputs.
+Due to the new algorithm, the sanitized output may be different for certain
+pathological inputs.
If you have a particular need for the exact output of the old sanitizer, you
can add the [rails-deprecated_sanitizer](https://github.com/kaspth/rails-deprecated_sanitizer)
@@ -250,8 +255,13 @@ application is using any of these spellings, you will need to update them:
non-alphanumeric characters.
```
- a[href=/] => a[href="/"]
- a[href$=/] => a[href$="/"]
+ # before
+ a[href=/]
+ a[href$=/]
+
+ # now
+ a[href="/"]
+ a[href$="/"]
```
* DOMs built from HTML source containing invalid HTML with improperly
@@ -501,6 +511,17 @@ Please refer to the [Changelog][action-pack] for detailed changes.
serving assets from your Rails server in production.
([Pull Request](https://github.com/rails/rails/pull/16466))
+* When calling the `process` helpers in an integration test the path needs to have
+ a leading slash. Previously you could omit it but that was a byproduct of the
+ implementation and not an intentional feature, e.g.:
+
+ ```ruby
+ test "list all posts" do
+ get "/posts"
+ assert_response :success
+ end
+ ```
+
Action View
-----------
@@ -621,6 +642,10 @@ Please refer to the [Changelog][active-record] for detailed changes.
`Relation` for performing queries and updates is the preferred API.
([Commit](https://github.com/rails/rails/commit/d5902c9e))
+* Deprecated `add_timestamps` and `t.timestamps` without passing the `:null`
+ option. The default of `null: true` will change in Rails 5 to `null: false`.
+ ([Pull Request](https://github.com/rails/rails/pull/16481))
+
* Deprecated `Reflection#source_macro` without replacement as it is no longer
needed in Active Record.
([Pull Request](https://github.com/rails/rails/pull/16373))
@@ -639,6 +664,9 @@ Please refer to the [Changelog][active-record] for detailed changes.
### Notable changes
+* `SchemaDumper` uses `force: :cascade` on `create_table`. This makes it
+ possible to reload a schema when foreign keys are in place.
+
* Added a `:required` option to singular associations, which defines a
presence validation on the association.
([Pull Request](https://github.com/rails/rails/pull/16056))
@@ -655,8 +683,8 @@ Please refer to the [Changelog][active-record] for detailed changes.
current environment.
([Commit](https://github.com/rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d))
-* Introduced `ActiveRecord::Base#validate!` that raises `ActiveRecord::RecordInvalid` if the
- record is invalid.
+* Introduced `ActiveRecord::Base#validate!` that raises
+ `ActiveRecord::RecordInvalid` if the record is invalid.
([Pull Request](https://github.com/rails/rails/pull/8639))
* Introduced `validate` as an alias for `valid?`.
@@ -696,8 +724,8 @@ Please refer to the [Changelog][active-record] for detailed changes.
`SELECT`s.
([Pull Request](https://github.com/rails/rails/pull/15866))
-* `ActiveRecord::Base#reflections` now returns a hash with string keys instead of symbol keys.
- ([Pull Request](https://github.com/rails/rails/pull/17718))
+* `ActiveRecord::Base#reflections` now returns a hash with string keys instead
+ of symbol keys. ([Pull Request](https://github.com/rails/rails/pull/17718))
* The `references` method in migrations now supports a `type` option for
specifying the type of the foreign key (e.g. `:uuid`).
@@ -805,6 +833,7 @@ Please refer to the [Changelog][active-support] for detailed changes.
`module Foo; extend ActiveSupport::Concern; end` boilerplate.
([Commit](https://github.com/rails/rails/commit/b16c36e688970df2f96f793a759365b248b582ad))
+* New [guide](constant_autoloading_and_reloading.html) about constant autoloading and reloading.
Credits
-------
diff --git a/guides/source/_welcome.html.erb b/guides/source/_welcome.html.erb
index 614d69ecdd..67f5f1cdd5 100644
--- a/guides/source/_welcome.html.erb
+++ b/guides/source/_welcome.html.erb
@@ -10,10 +10,15 @@
</p>
<% else %>
<p>
- These are the new guides for Rails 4.2 based on <a href="https://github.com/rails/rails/tree/<%= @version %>"><%= @version %></a>.
+ These are the new guides for Rails 5.0 based on <a href="https://github.com/rails/rails/tree/<%= @version %>"><%= @version %></a>.
These guides are designed to make you immediately productive with Rails, and to help you understand how all of the pieces fit together.
</p>
<% end %>
<p>
- The guides for earlier releases: <a href="http://guides.rubyonrails.org/v4.1.8/">Rails 4.1.8</a>, <a href="http://guides.rubyonrails.org/v4.0.12/">Rails 4.0.12</a>, <a href="http://guides.rubyonrails.org/v3.2.21/">Rails 3.2.21</a> and <a href="http://guides.rubyonrails.org/v2.3.11/">Rails 2.3.11</a>.
+The guides for earlier releases:
+<a href="http://guides.rubyonrails.org/v4.2.0/">Rails 4.2.0</a>,
+<a href="http://guides.rubyonrails.org/v4.1.8/">Rails 4.1.8</a>,
+<a href="http://guides.rubyonrails.org/v4.0.12/">Rails 4.0.12</a>,
+<a href="http://guides.rubyonrails.org/v3.2.21/">Rails 3.2.21</a> and
+<a href="http://guides.rubyonrails.org/v2.3.11/">Rails 2.3.11</a>.
</p>
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 1ca0d9ed55..36d1b6de83 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Action Controller Overview
==========================
@@ -112,8 +114,8 @@ NOTE: The actual URL in this example will be encoded as "/clients?ids%5b%5d=1&id
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.
-NOTE: Values such as `[]`, `[nil]` or `[nil, nil, ...]` in `params` are replaced
-with `nil` for security reasons by default. See [Security Guide](security.html#unsafe-query-generation)
+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:
@@ -992,6 +994,11 @@ you would like in a response object. The `ActionController::Live` module allows
you to create a persistent connection with a browser. Using this module, you will
be able to send arbitrary data to the browser at specific points in time.
+NOTE: The default Rails server (WEBrick) is a buffering web server and does not
+support streaming. In order to use this feature, you'll need to use a non buffering
+server like [Puma](http://puma.io), [Rainbows](http://rainbows.bogomips.org)
+or [Passenger](https://www.phusionpassenger.com).
+
#### Incorporating Live Streaming
Including `ActionController::Live` inside of your controller class will provide
@@ -1164,67 +1171,10 @@ class ClientsController < ApplicationController
end
```
-WARNING: You shouldn't do `rescue_from Exception` or `rescue_from StandardError` unless you have a particular reason as it will cause serious side-effects (e.g. you won't be able to see exception details and tracebacks during development). If you would like to dynamically generate error pages, see [Custom errors page](#custom-errors-page).
+WARNING: You shouldn't do `rescue_from Exception` or `rescue_from StandardError` unless you have a particular reason as it will cause serious side-effects (e.g. you won't be able to see exception details and tracebacks during development).
NOTE: Certain exceptions are only rescuable from the `ApplicationController` class, as they are raised before the controller gets initialized and the action gets executed. See Pratik Naik's [article](http://m.onkey.org/2008/7/20/rescue-from-dispatching) on the subject for more information.
-
-### Custom errors page
-
-You can customize the layout of your error handling using controllers and views.
-First define your app own routes to display the errors page.
-
-* `config/application.rb`
-
- ```ruby
- config.exceptions_app = self.routes
- ```
-
-* `config/routes.rb`
-
- ```ruby
- match '/404', via: :all, to: 'errors#not_found'
- match '/422', via: :all, to: 'errors#unprocessable_entity'
- match '/500', via: :all, to: 'errors#server_error'
- ```
-
-Create the controller and views.
-
-* `app/controllers/errors_controller.rb`
-
- ```ruby
- class ErrorsController < ActionController::Base
- layout 'error'
-
- def not_found
- render status: :not_found
- end
-
- def unprocessable_entity
- render status: :unprocessable_entity
- end
-
- def server_error
- render status: :server_error
- end
- end
- ```
-
-* `app/views`
-
- ```
- errors/
- not_found.html.erb
- unprocessable_entity.html.erb
- server_error.html.erb
- layouts/
- error.html.erb
- ```
-
-Do not forget to set the correct status code on the controller as shown before.
-
-WARNING: You should avoid using the database or any complex operations because the user is already on the error page. Generating another error while on an error page could cause issues like presenting an empty page for the users.
-
Force HTTPS protocol
--------------------
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index 2e8ab83241..c586675ee5 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Action Mailer Basics
====================
@@ -48,7 +50,7 @@ create test/mailers/previews/user_mailer_preview.rb
```ruby
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
- default "from@example.com"
+ default from: "from@example.com"
layout 'mailer'
end
@@ -470,16 +472,7 @@ By using the full URL, your links will now work in your emails.
#### generating URLs with `url_for`
-You need to pass the `only_path: false` option when using `url_for`. This will
-ensure that absolute URLs are generated because the `url_for` view helper will,
-by default, generate relative URLs when a `:host` option isn't explicitly
-provided.
-
-```erb
-<%= url_for(controller: 'welcome',
- action: 'greeting',
- only_path: false) %>
-```
+`url_for` generate full URL by default in templates.
If you did not configure the `:host` option globally make sure to pass it to
`url_for`.
@@ -491,9 +484,6 @@ If you did not configure the `:host` option globally make sure to pass it to
action: 'greeting') %>
```
-NOTE: When you explicitly pass the `:host` Rails will always generate absolute
-URLs, so there is no need to pass `only_path: false`.
-
#### generating URLs with named routes
Email clients have no web context and so paths have no base URL to form complete
@@ -743,7 +733,9 @@ Mailer framework. You can do this in an initializer file
`config/initializers/sandbox_email_interceptor.rb`
```ruby
-ActionMailer::Base.register_interceptor(SandboxEmailInterceptor) if Rails.env.staging?
+if Rails.env.staging?
+ ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
+end
```
NOTE: The example above uses a custom environment called "staging" for a
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index f4d5bb8272..a6bde4f517 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Action View Overview
====================
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index 748467866d..3046a62778 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Job Basics
=================
@@ -155,7 +157,7 @@ end
# environment
```
-The default queue name prefix delimiter is '_'. This can be changed by setting
+The default queue name prefix delimiter is '\_'. This can be changed by setting
`config.active_job.queue_name_delimiter` in `application.rb`:
```ruby
@@ -215,8 +217,8 @@ backends you need to specify the queues to listen to.
Callbacks
---------
-Active Job provides hooks during the lifecycle of a job. Callbacks allow you to
-trigger logic during the lifecycle of a job.
+Active Job provides hooks during the life cycle of a job. Callbacks allow you to
+trigger logic during the life cycle of a job.
### Available callbacks
diff --git a/guides/source/active_model_basics.md b/guides/source/active_model_basics.md
index a520b91a4d..8dee1cc5ec 100644
--- a/guides/source/active_model_basics.md
+++ b/guides/source/active_model_basics.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Model Basics
===================
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index bd074d0055..9d2ba328ea 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record Basics
====================
@@ -358,7 +360,7 @@ class CreatePublications < ActiveRecord::Migration
t.string :publisher_type
t.boolean :single_issue
- t.timestamps
+ t.timestamps null: false
end
add_index :publications, :publication_type_id
end
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
index 9c7e60cbb0..9d3a8c3af6 100644
--- a/guides/source/active_record_callbacks.md
+++ b/guides/source/active_record_callbacks.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record Callbacks
=======================
diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md
index c8a31fe7b8..8ae282bad2 100644
--- a/guides/source/active_record_migrations.md
+++ b/guides/source/active_record_migrations.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record Migrations
========================
@@ -39,7 +41,7 @@ class CreateProducts < ActiveRecord::Migration
t.string :name
t.text :description
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -285,7 +287,7 @@ class CreateProducts < ActiveRecord::Migration
t.string :name
t.text :description
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -452,6 +454,8 @@ number of digits after the decimal point.
are using a dynamic value (such as a date), the default will only be calculated
the first time (i.e. on the date the migration is applied).
* `index` Adds an index for the column.
+* `required` Adds `required: true` for `belongs_to` associations and
+`null: false` to the column in the migration.
Some adapters may support additional options; see the adapter specific API docs
for further information.
@@ -824,7 +828,7 @@ class CreateProducts < ActiveRecord::Migration
create_table :products do |t|
t.string :name
t.text :description
- t.timestamps
+ t.timestamps null: false
end
end
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index a2681a80e9..fa0f31cbbd 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record and PostgreSQL
============================
@@ -83,9 +85,12 @@ Book.where("array_length(ratings, 1) >= 3")
* [type definition](http://www.postgresql.org/docs/9.3/static/hstore.html)
+NOTE: you need to enable the `hstore` extension to use hstore.
+
```ruby
# db/migrate/20131009135255_create_profiles.rb
ActiveRecord::Schema.define do
+ enable_extension 'hstore' unless extension_enabled?('hstore')
create_table :profiles do |t|
t.hstore 'settings'
end
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index e1a465c64f..e0a9add2be 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record Query Interface
=============================
@@ -9,6 +11,7 @@ After reading this guide, you will know:
* How to specify the order, retrieved attributes, grouping, and other properties of the found records.
* How to use eager loading to reduce the number of database queries needed for data retrieval.
* How to use dynamic finders methods.
+* How to use method chaining to use multiple ActiveRecord methods together.
* How to check for the existence of particular records.
* How to perform various calculations on Active Record models.
* How to run EXPLAIN on relations.
@@ -1327,14 +1330,65 @@ You can specify an exclamation point (`!`) on the end of the dynamic finders to
If you want to find both by name and locked, you can chain these finders together by simply typing "`and`" between the fields. For example, `Client.find_by_first_name_and_locked("Ryan", true)`.
+Understanding The Method Chaining
+---------------------------------
+
+The Active Record pattern implements [Method Chaining](http://en.wikipedia.org/wiki/Method_chaining),
+which allow us to use multiple Active Record methods together in a simple and straightforward way.
+
+You can chain methods in a statement when the previous method called returns an
+`ActiveRecord::Relation`, like `all`, `where`, and `joins`. Methods that return
+a single object (see [Retrieving a Single Object Section](#retrieving-a-single-object))
+have to be at the end of the statement.
+
+There are some examples below. This guide won't cover all the possibilities, just a few as examples.
+When an Active Record method is called, the query is not immediately generated and sent to the database,
+this just happens when the data is actually needed. So each example below generates a single query.
+
+### Retrieving filtered data from multiple tables
+
+```ruby
+Person
+ .select('people.id, people.name, comments.text')
+ .joins(:comments)
+ .where('comments.created_at > ?', 1.week.ago)
+```
+
+The result should be something like this:
+
+```sql
+SELECT people.id, people.name, comments.text
+FROM people
+INNER JOIN comments
+ ON comments.person_id = people.id
+WHERE comments.created_at = '2015-01-01'
+```
+
+### Retrieving specific data from multiple tables
+
+```ruby
+Person
+ .select('people.id, people.name, companies.name')
+ .joins(:company)
+ .find_by('people.name' => 'John') # this should be the last
+```
+
+The above should generate:
+
+```sql
+SELECT people.id, people.name, companies.name
+FROM people
+INNER JOIN companies
+ ON companies.person_id = people.id
+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.
+
Find or Build a New Object
--------------------------
-NOTE: Some dynamic finders have been deprecated in Rails 4.0 and will be
-removed in Rails 4.1. The best practice is to use Active Record scopes
-instead. You can find the deprecation gem at
-https://github.com/rails/activerecord-deprecated_finders
-
It's common that you need to find a record or create it if it doesn't exist. You can do that with the `find_or_create_by` and `find_or_create_by!` methods.
### `find_or_create_by`
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
index 546c0608ee..8c832bafff 100644
--- a/guides/source/active_record_validations.md
+++ b/guides/source/active_record_validations.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record Validations
=========================
@@ -487,6 +489,8 @@ constraints to acceptable values:
* `:even` - Specifies the value must be an even number if set to true. The
default error message for this option is _"must be even"_.
+NOTE: By default, `numericality` doesn't allow `nil` values. You can use `allow_nil: true` option to permit it.
+
The default error message is _"is not a number"_.
### `presence`
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 616b813817..c857f30541 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Support Core Extensions
==============================
@@ -1447,7 +1449,7 @@ Returns the substring of the string starting at position `position`:
"hello".from(0) # => "hello"
"hello".from(2) # => "llo"
"hello".from(-2) # => "lo"
-"hello".from(10) # => "" if < 1.9, nil in 1.9
+"hello".from(10) # => nil
```
NOTE: Defined in `active_support/core_ext/string/access.rb`.
@@ -1950,24 +1952,6 @@ as well as adding or subtracting their results from a Time object. For example:
(4.months + 5.years).from_now
```
-While these methods provide precise calculation when used as in the examples above, care
-should be taken to note that this is not true if the result of `months', `years', etc is
-converted before use:
-
-```ruby
-# equivalent to 30.days.to_i.from_now
-1.month.to_i.from_now
-
-# equivalent to 365.25.days.to_f.from_now
-1.year.to_f.from_now
-```
-
-In such cases, Ruby's core [Date](http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html) and
-[Time](http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html) should be used for precision
-date and time arithmetic.
-
-NOTE: Defined in `active_support/core_ext/numeric/time.rb`.
-
### Formatting
Enables the formatting of numbers in a variety of ways.
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index 9dfacce560..0aa74e387d 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Support Instrumentation
==============================
diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md
index a2ebf55335..d481700709 100644
--- a/guides/source/api_documentation_guidelines.md
+++ b/guides/source/api_documentation_guidelines.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
API Documentation Guidelines
============================
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index ae0f19c02a..64d1c31083 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
The Asset Pipeline
==================
@@ -167,9 +169,8 @@ directory. Files in this directory are served by the Sprockets middleware.
Assets can still be placed in the `public` hierarchy. Any assets under `public`
will be served as static files by the application or web server when
-`config.serve_static_assets` is set to true. You should use
-`app/assets` for files that must undergo some pre-processing before they are
-served.
+`config.serve_static_files` is set to true. You should use `app/assets` for
+files that must undergo some pre-processing before they are served.
In production, Rails precompiles these files to `public/assets` by default. The
precompiled copies are then served as static assets by the web server. The files
@@ -181,12 +182,12 @@ When you generate a scaffold or a controller, Rails also generates a JavaScript
file (or CoffeeScript file if the `coffee-rails` gem is in the `Gemfile`) and a
Cascading Style Sheet file (or SCSS file if `sass-rails` is in the `Gemfile`)
for that controller. Additionally, when generating a scaffold, Rails generates
-the file scaffolds.css (or scaffolds.css.scss if `sass-rails` is in the
+the file scaffolds.css (or scaffolds.scss if `sass-rails` is in the
`Gemfile`.)
For example, if you generate a `ProjectsController`, Rails will also add a new
-file at `app/assets/javascripts/projects.js.coffee` and another at
-`app/assets/stylesheets/projects.css.scss`. By default these files will be ready
+file at `app/assets/javascripts/projects.coffee` and another at
+`app/assets/stylesheets/projects.scss`. By default these files will be ready
to use by your application immediately using the `require_tree` directive. See
[Manifest Files and Directives](#manifest-files-and-directives) for more details
on require_tree.
@@ -231,7 +232,9 @@ images, JavaScript files or stylesheets.
scope of the application or those libraries which are shared across applications.
* `vendor/assets` is for assets that are owned by outside entities, such as
-code for JavaScript plugins and CSS frameworks.
+code for JavaScript plugins and CSS frameworks. Keep in mind that third party
+code with references to other files also processed by the asset Pipeline (images,
+stylesheets, etc.), will need to be rewritten to use helpers like `asset_path`.
WARNING: If you are upgrading from Rails 3, please take into account that assets
under `lib/assets` or `vendor/assets` are available for inclusion via the
@@ -421,7 +424,7 @@ $('#logo').attr({ src: "<%= asset_path('logo.png') %>" });
This writes the path to the particular asset being referenced.
Similarly, you can use the `asset_path` helper in CoffeeScript files with `erb`
-extension (e.g., `application.js.coffee.erb`):
+extension (e.g., `application.coffee.erb`):
```js
$('#logo').attr src: "<%= asset_path('logo.png') %>"
@@ -522,8 +525,8 @@ The file extensions used on an asset determine what preprocessing is applied.
When a controller or a scaffold is generated with the default Rails gemset, a
CoffeeScript file and a SCSS file are generated in place of a regular JavaScript
and CSS file. The example used before was a controller called "projects", which
-generated an `app/assets/javascripts/projects.js.coffee` and an
-`app/assets/stylesheets/projects.css.scss` file.
+generated an `app/assets/javascripts/projects.coffee` and an
+`app/assets/stylesheets/projects.scss` file.
In development mode, or if the asset pipeline is disabled, when these files are
requested they are processed by the processors provided by the `coffee-script`
@@ -535,13 +538,13 @@ web server.
Additional layers of preprocessing can be requested by adding other extensions,
where each extension is processed in a right-to-left manner. These should be
used in the order the processing should be applied. For example, a stylesheet
-called `app/assets/stylesheets/projects.css.scss.erb` is first processed as ERB,
+called `app/assets/stylesheets/projects.scss.erb` is first processed as ERB,
then SCSS, and finally served as CSS. The same applies to a JavaScript file -
-`app/assets/javascripts/projects.js.coffee.erb` is processed as ERB, then
+`app/assets/javascripts/projects.coffee.erb` is processed as ERB, then
CoffeeScript, and served as JavaScript.
Keep in mind the order of these preprocessors is important. For example, if
-you called your JavaScript file `app/assets/javascripts/projects.js.erb.coffee`
+you called your JavaScript file `app/assets/javascripts/projects.erb.coffee`
then it would be processed with the CoffeeScript interpreter first, which
wouldn't understand ERB and therefore you would run into problems.
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index a12f5638e3..95c7e747ef 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Active Record Associations
==========================
@@ -101,13 +103,13 @@ class CreateOrders < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :orders do |t|
t.belongs_to :customer, index: true
t.datetime :order_date
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -132,13 +134,13 @@ class CreateSuppliers < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :accounts do |t|
t.belongs_to :supplier, index: true
t.string :account_number
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -165,13 +167,13 @@ class CreateCustomers < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :orders do |t|
t.belongs_to :customer, index:true
t.datetime :order_date
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -207,19 +209,19 @@ class CreateAppointments < ActiveRecord::Migration
def change
create_table :physicians do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :patients do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :appointments do |t|
t.belongs_to :physician, index: true
t.belongs_to :patient, index: true
t.datetime :appointment_date
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -291,19 +293,19 @@ class CreateAccountHistories < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :accounts do |t|
t.belongs_to :supplier, index: true
t.string :account_number
- t.timestamps
+ t.timestamps null: false
end
create_table :account_histories do |t|
t.belongs_to :account, index: true
t.integer :credit_rating
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -332,12 +334,12 @@ class CreateAssembliesAndParts < ActiveRecord::Migration
def change
create_table :assemblies do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :parts do |t|
t.string :part_number
- t.timestamps
+ t.timestamps null: false
end
create_table :assemblies_parts, id: false do |t|
@@ -371,13 +373,13 @@ class CreateSuppliers < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
- t.timestamps
+ t.timestamps null: false
end
create_table :accounts do |t|
t.integer :supplier_id
t.string :account_number
- t.timestamps
+ t.timestamps null: false
end
add_index :accounts, :supplier_id
@@ -455,7 +457,7 @@ class CreatePictures < ActiveRecord::Migration
t.string :name
t.integer :imageable_id
t.string :imageable_type
- t.timestamps
+ t.timestamps null: false
end
add_index :pictures, :imageable_id
@@ -471,7 +473,7 @@ class CreatePictures < ActiveRecord::Migration
create_table :pictures do |t|
t.string :name
t.references :imageable, polymorphic: true, index: true
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -501,7 +503,7 @@ class CreateEmployees < ActiveRecord::Migration
def change
create_table :employees do |t|
t.references :manager, index: true
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -879,10 +881,12 @@ class Order < ActiveRecord::Base
belongs_to :customer, counter_cache: :count_of_orders
end
class Customer < ActiveRecord::Base
- has_many :orders
+ has_many :orders, counter_cache: :count_of_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.
+
Counter cache columns are added to the containing model's list of read-only attributes through `attr_readonly`.
##### `:dependent`
@@ -1495,6 +1499,7 @@ The `has_many` association supports these options:
* `:as`
* `:autosave`
* `:class_name`
+* `:counter_cache`
* `:dependent`
* `:foreign_key`
* `:inverse_of`
@@ -1522,6 +1527,10 @@ class Customer < ActiveRecord::Base
end
```
+##### `:counter_cache`
+
+This option can be used to configure a custom named `:counter_cache`. You only need this option when you customized the name of your `:counter_cache` on the [belongs_to association](#options-for-belongs-to).
+
##### `:dependent`
Controls what happens to the associated objects when their owner is destroyed:
diff --git a/guides/source/autoloading_and_reloading_constants.md b/guides/source/autoloading_and_reloading_constants.md
new file mode 100644
index 0000000000..489ea681e2
--- /dev/null
+++ b/guides/source/autoloading_and_reloading_constants.md
@@ -0,0 +1,1300 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
+Autoloading and Reloading Constants
+===================================
+
+This guide documents how constant autoloading and reloading works.
+
+After reading this guide, you will know:
+
+* Key aspects of Ruby constants
+* What is `autoload_paths`
+* How constant autoloading works
+* What is `require_dependency`
+* How constant reloading works
+* Solutions to common autoloading gotchas
+
+--------------------------------------------------------------------------------
+
+
+Introduction
+------------
+
+Ruby on Rails allows applications to be written as if their code was preloaded.
+
+In a normal Ruby program classes need to load their dependencies:
+
+```ruby
+require 'application_controller'
+require 'post'
+
+class PostsController < ApplicationController
+ def index
+ @posts = Post.all
+ end
+end
+```
+
+Our Rubyist instinct quickly sees some redundancy in there: If classes were
+defined in files matching their name, couldn't their loading be automated
+somehow? We could save scanning the file for dependencies, which is brittle.
+
+Moreover, `Kernel#require` loads files once, but development is much more smooth
+if code gets refreshed when it changes without restarting the server. It would
+be nice to be able to use `Kernel#load` in development, and `Kernel#require` in
+production.
+
+Indeed, those features are provided by Ruby on Rails, where we just write
+
+```ruby
+class PostsController < ApplicationController
+ def index
+ @posts = Post.all
+ end
+end
+```
+
+This guide documents how that works.
+
+
+Constants Refresher
+-------------------
+
+While constants are trivial in most programming languages, they are a rich
+topic in Ruby.
+
+It is beyond the scope of this guide to document Ruby constants, but we are
+nevertheless going to highlight a few key topics. Truly grasping the following
+sections is instrumental to understanding constant autoloading and reloading.
+
+### Nesting
+
+Class and module definitions can be nested to create namespaces:
+
+```ruby
+module XML
+ class SAXParser
+ # (1)
+ end
+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
+(1) is
+
+```ruby
+[XML::SAXParser, XML]
+```
+
+It is important to understand that the nesting is composed of class and module
+*objects*, it has nothing to do with the constants used to access them, and is
+also unrelated to their names.
+
+For instance, while this definition is similar to the previous one:
+
+```ruby
+class XML::SAXParser
+ # (2)
+end
+```
+
+the nesting in (2) is different:
+
+```ruby
+[XML::SAXParser]
+```
+
+`XML` does not belong to it.
+
+We can see in this example that the name of a class or module that belongs to a
+certain nesting does not necessarily correlate with the namespaces at the spot.
+
+Even more, they are totally independent, take for instance
+
+```ruby
+module X::Y
+ module A::B
+ # (3)
+ end
+end
+```
+
+The nesting in (3) consists of two module objects:
+
+```ruby
+[A::B, X::Y]
+```
+
+So, it not only doesn't end in `A`, which does not even belong to the nesting,
+but it also contains `X::Y`, which is independent from `A::B`.
+
+The nesting is an internal stack maintained by the interpreter, and it gets
+modified according to these rules:
+
+* The class object following a `class` keyword gets pushed when its body is
+executed, and popped after it.
+
+* The module object following a `module` keyword gets pushed when its body is
+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,
+the singleton class of 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
+a newly created anonymous module is pushed by Ruby.
+
+It is interesting to observe that blocks do not modify the stack. In particular
+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):
+
+```ruby
+class C
+end
+```
+
+Ruby creates a constant `C` in `Object` and stores in that constant a class
+object. The name of the class instance is "C", a string, named after the
+constant.
+
+That is,
+
+```ruby
+class Project < ActiveRecord::Base
+end
+```
+
+performs a constant assignment equivalent to
+
+```ruby
+Project = Class.new(ActiveRecord::Base)
+```
+
+including setting the name of the class as a side-effect:
+
+```ruby
+Project.name # => "Project"
+```
+
+Constant assignment has a special rule to make that happen: if the object
+being assigned is an anonymous class or module, Ruby sets the object's name to
+the name of the constant.
+
+INFO. From then on, what happens to the constant and the instance does not
+matter. For example, the constant could be deleted, the class object could be
+assigned to a different constant, be stored in no constant anymore, etc. Once
+the name is set, it doesn't change.
+
+Similarly, module creation using the `module` keyword as in
+
+```ruby
+module Admin
+end
+```
+
+performs a constant assignment equivalent to
+
+```ruby
+Admin = Module.new
+```
+
+including setting the name as a side-effect:
+
+```ruby
+Admin.name # => "Admin"
+```
+
+WARNING. The execution context of a block passed to `Class.new` or `Module.new`
+is not entirely equivalent to the one of the body of the definitions using the
+`class` and `module` keywords. But both idioms result in the same constant
+assignment.
+
+Thus, when one informally says "the `String` class", that really means: the
+class object stored in the constant called "String" in the class object stored
+in the `Object` constant. `String` is otherwise an ordinary Ruby constant and
+everything related to constants such as resolution algorithms applies to it.
+
+Likewise, in the controller
+
+```ruby
+class PostsController < ApplicationController
+ def index
+ @posts = Post.all
+ end
+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`.
+
+That is why we talk about *constant* autoloading, Rails has the ability to
+load constants on the fly.
+
+### Constants are Stored in Modules
+
+Constants belong to modules in a very literal sense. Classes and modules have
+a constant table; think of it as a hash table.
+
+Let's analyze an example to really understand what that means. While common
+abuses of language like "the `String` class" are convenient, the exposition is
+going to be precise here for didactic purposes.
+
+Let's consider the following module definition:
+
+```ruby
+module Colors
+ RED = '0xff0000'
+end
+```
+
+First, when the `module` keyword is processed, the interpreter creates a new
+entry in the constant table of the class object stored in the `Object` constant.
+Said entry associates the name "Colors" to a newly created module object.
+Furthermore, the interpreter sets the name of the new module object to be the
+string "Colors".
+
+Later, when the body of the module definition is interpreted, a new entry is
+created in the constant table of the module object stored in the `Colors`
+constant. That entry maps the name "RED" to the string "0xff0000".
+
+In particular, `Colors::RED` is totally unrelated to any other `RED` constant
+that may live in any other class or module object. If there were any, they
+would have separate entries in their respective constant tables.
+
+Pay special attention in the previous paragraphs to the distinction between
+class and module objects, constant names, and value objects associated to them
+in constant tables.
+
+### Resolution Algorithms
+
+#### Resolution Algorithm for Relative Constants
+
+At any given place in the code, let's define *cref* to be the first element of
+the nesting if it is not empty, or `Object` otherwise.
+
+Without getting too much into the details, the resolution algorithm for relative
+constant references goes like this:
+
+1. If the nesting is not empty the constant is looked up in its elements and in
+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
+implementation of `const_missing` raises `NameError`, but it can be overridden.
+
+Rails autoloading **does not emulate this algorithm**, but its starting point is
+the name of the constant to be autoloaded, and the cref. See more in [Relative
+References](#autoloading-algorithms-relative-references).
+
+#### Resolution Algorithm for Qualified Constants
+
+Qualified constants look like this:
+
+```ruby
+Billing::Invoice
+```
+
+`Billing::Invoice` is composed of two constants: `Billing` is relative and is
+resolved using the algorithm of the previous section.
+
+INFO. Leading colons would make the first segment absolute rather than
+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
+object, that is, `Billing` in the example above. The algorithm for qualified
+constants goes like this:
+
+1. The constant is looked up in the parent and its ancestors.
+
+2. If the lookup fails, `const_missing` is invoked in the parent. The default
+implementation of `const_missing` raises `NameError`, but it can be overridden.
+
+As you see, this algorithm is simpler than the one for relative constants. In
+particular, the nesting plays no role here, and modules are not special-cased,
+if neither they nor their ancestors have the constants, `Object` is **not**
+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).
+
+
+Vocabulary
+----------
+
+### Parent Namespaces
+
+Given a string with a constant path we define its *parent namespace* to be the
+string that results from removing its rightmost segment.
+
+For example, the parent namespace of the string "A::B::C" is the string "A::B",
+the parent namespace of "A::B" is "A", and the parent namespace of "A" is "".
+
+The interpretation of a parent namespace when thinking about classes and modules
+is tricky though. Let's consider a module M named "A::B":
+
+* The parent namespace, "A", may not reflect nesting at a given spot.
+
+* The constant `A` may no longer exist, some code could have removed it from
+`Object`.
+
+* If `A` exists, the class or module that was originally in `A` may not be there
+anymore. For example, if after a constant removal there was another constant
+assignment there would generally be a different object in there.
+
+* In such case, it could even happen that the reassigned `A` held a new class or
+module called also "A"!
+
+* In the previous scenarios M would no longer be reachable through `A::B` but
+the module object itself could still be alive somewhere and its name would
+still be "A::B".
+
+The idea of a parent namespace is at the core of the autoloading algorithms
+and helps explain and understand their motivation intuitively, but as you see
+that metaphor leaks easily. Given an edge case to reason about, take always into
+account that by "parent namespace" the guide means exactly that specific string
+derivation.
+
+### Loading Mechanism
+
+Rails autoloads files with `Kernel#load` when `config.cache_classes` is false,
+the default in development mode, and with `Kernel#require` otherwise, the
+default in production mode.
+
+`Kernel#load` allows Rails to execute files more than once if [constant
+reloading](#constant-reloading) is enabled.
+
+This guide uses the word "load" freely to mean a given file is interpreted, but
+the actual mechanism can be `Kernel#load` or `Kernel#require` depending on that
+flag.
+
+
+Autoloading Availability
+------------------------
+
+Rails is always able to autoload provided its environment is in place. For
+example the `runner` command autoloads:
+
+```
+$ bin/rails runner 'p User.column_names'
+["id", "email", "created_at", "updated_at"]
+```
+
+The console autoloads, the test suite autoloads, and of course the application
+autoloads.
+
+By default, Rails eager loads the application files when it boots in production
+mode, so most of the autoloading going on in development does not happen. But
+autoloading may still be triggered during eager loading.
+
+For example, given
+
+```ruby
+class BeachHouse < House
+end
+```
+
+if `House` is still unknown when `app/models/beach_house.rb` is being eager
+loaded, Rails autoloads it.
+
+
+autoload_paths
+--------------
+
+As you probably know, when `require` gets a relative file name:
+
+```ruby
+require 'erb'
+```
+
+Ruby looks for the file in the directories listed in `$LOAD_PATH`. That is, Ruby
+iterates over all its directories and for each one of them checks whether they
+have a file called "erb.rb", or "erb.so", or "erb.o", or "erb.dll". If it finds
+any of them, the interpreter loads it and ends the search. Otherwise, it tries
+again in the next directory of the list. If the list gets exhausted, `LoadError`
+is raised.
+
+We are going to cover how constant autoloading works in more detail later, but
+the idea is that when a constant like `Post` is hit and missing, if there's a
+`post.rb` file for example in `app/models` Rails is going to find it, evaluate
+it, and have `Post` defined as a side-effect.
+
+Alright, Rails has a collection of directories similar to `$LOAD_PATH` in which
+to look up `post.rb`. That collection is called `autoload_paths` and by
+default it contains:
+
+* All subdirectories of `app` in the application and engines. For example,
+ `app/controllers`. They do not need to be the default ones, any custom
+ directories like `app/workers` belong automatically to `autoload_paths`.
+
+* Any existing second level directories called `app/*/concerns` in the
+ application and engines.
+
+* The directory `test/mailers/previews`.
+
+Also, this collection is configurable via `config.autoload_paths`. For example,
+`lib` was in the list years ago, but no longer is. An application can opt-in
+by adding this to `config/application.rb`:
+
+```ruby
+config.autoload_paths += "#{Rails.root}/lib"
+```
+
+The value of `autoload_paths` can be inspected. In a just generated application
+it is (edited):
+
+```
+$ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths'
+.../app/assets
+.../app/controllers
+.../app/helpers
+.../app/mailers
+.../app/models
+.../app/controllers/concerns
+.../app/models/concerns
+.../test/mailers/previews
+```
+
+INFO. `autoload_paths` is computed and cached during the initialization process.
+The application needs to be restarted to reflect any changes in the directory
+structure.
+
+
+Autoloading Algorithms
+----------------------
+
+### Relative References
+
+A relative constant reference may appear in several places, for example, in
+
+```ruby
+class PostsController < ApplicationController
+ def index
+ @posts = Post.all
+ end
+end
+```
+
+all three constant references are relative.
+
+#### Constants after the `class` and `module` Keywords
+
+Ruby performs a lookup for the constant that follows a `class` or `module`
+keyword because it needs to know if the class or module is going to be created
+or reopened.
+
+If the constant is not defined at that point it is not considered to be a
+missing constant, autoloading is **not** triggered.
+
+So, in the previous example, if `PostsController` is not defined when the file
+is interpreted Rails autoloading is not going to be triggered, Ruby will just
+define the controller.
+
+#### Top-Level Constants
+
+On the contrary, if `ApplicationController` is unknown, the constant is
+considered missing and an autoload is going to be attempted by Rails.
+
+In order to load `ApplicationController`, Rails iterates over `autoload_paths`.
+First checks if `app/assets/application_controller.rb` exists. If it does not,
+which is normally the case, it continues and finds
+`app/controllers/application_controller.rb`.
+
+If the file defines the constant `ApplicationController` all is fine, otherwise
+`LoadError` is raised:
+
+```
+unable to autoload constant ApplicationController, expected
+<full path to application_controller.rb> to define it (LoadError)
+```
+
+INFO. Rails does not require the value of autoloaded constants to be a class or
+module object. For example, if the file `app/models/max_clients.rb` defines
+`MAX_CLIENTS = 100` autoloading `MAX_CLIENTS` works just fine.
+
+#### Namespaces
+
+Autoloading `ApplicationController` looks directly under the directories of
+`autoload_paths` because the nesting in that spot is empty. The situation of
+`Post` is different, the nesting in that line is `[PostsController]` and support
+for namespaces comes into play.
+
+The basic idea is that given
+
+```ruby
+module Admin
+ class BaseController < ApplicationController
+ @@all_roles = Role.all
+ end
+end
+```
+
+to autoload `Role` we are going to check if it is defined in the current or
+parent namespaces, one at a time. So, conceptually we want to try to autoload
+any of
+
+```
+Admin::BaseController::Role
+Admin::Role
+Role
+```
+
+in that order. That's the idea. To do so, Rails looks in `autoload_paths`
+respectively for file names like these:
+
+```
+admin/base_controller/role.rb
+admin/role.rb
+role.rb
+```
+
+modulus some additional directory lookups we are going to cover soon.
+
+INFO. `'Constant::Name'.underscore` gives the relative path without extension of
+the file name where `Constant::Name` is expected to be defined.
+
+Let's see how Rails autoloads the `Post` constant in the `PostsController`
+above assuming the application has a `Post` model defined in
+`app/models/post.rb`.
+
+First it checks for `posts_controller/post.rb` in `autoload_paths`:
+
+```
+app/assets/posts_controller/post.rb
+app/controllers/posts_controller/post.rb
+app/helpers/posts_controller/post.rb
+...
+test/mailers/previews/posts_controller/post.rb
+```
+
+Since the lookup is exhausted without success, a similar search for a directory
+is performed, we are going to see why in the [next section](#automatic-modules):
+
+```
+app/assets/posts_controller/post
+app/controllers/posts_controller/post
+app/helpers/posts_controller/post
+...
+test/mailers/previews/posts_controller/post
+```
+
+If all those attempts fail, then Rails starts the lookup again in the parent
+namespace. In this case only the top-level remains:
+
+```
+app/assets/post.rb
+app/controllers/post.rb
+app/helpers/post.rb
+app/mailers/post.rb
+app/models/post.rb
+```
+
+A matching file is found in `app/models/post.rb`. The lookup stops there and the
+file is loaded. If the file actually defines `Post` all is fine, otherwise
+`LoadError` is raised.
+
+### Qualified References
+
+When a qualified constant is missing Rails does not look for it in the parent
+namespaces. But there is a caveat: When a constant is missing, Rails is
+unable to tell if the trigger was a relative reference or a qualified one.
+
+For example, consider
+
+```ruby
+module Admin
+ User
+end
+```
+
+and
+
+```ruby
+Admin::User
+```
+
+If `User` is missing, in either case all Rails knows is that a constant called
+"User" was missing in a module called "Admin".
+
+If there is a top-level `User` Ruby would resolve it in the former example, but
+wouldn't in the latter. In general, Rails does not emulate the Ruby constant
+resolution algorithms, but in this case it tries using the following heuristic:
+
+> If none of the parent namespaces of the class or module has the missing
+> constant then Rails assumes the reference is relative. Otherwise qualified.
+
+For example, if this code triggers autoloading
+
+```ruby
+Admin::User
+```
+
+and the `User` constant is already present in `Object`, it is not possible that
+the situation is
+
+```ruby
+module Admin
+ User
+end
+```
+
+because otherwise Ruby would have resolved `User` and no autoloading would have
+been triggered in the first place. Thus, Rails assumes a qualified reference and
+considers the file `admin/user.rb` and directory `admin/user` to be the only
+valid options.
+
+In practice, this works quite well as long as the nesting matches all parent
+namespaces respectively and the constants that make the rule apply are known at
+that time.
+
+However, autoloading happens on demand. If by chance the top-level `User` was
+not yet loaded, then Rails assumes a relative reference by contract.
+
+Naming conflicts of this kind are rare in practice, but if one occurs,
+`require_dependency` provides a solution by ensuring that the constant needed
+to trigger the heuristic is defined in the conflicting place.
+
+### Automatic Modules
+
+When a module acts as a namespace, Rails does not require the application to
+defines a file for it, a directory matching the namespace is enough.
+
+Suppose an application has a back office whose controllers are stored in
+`app/controllers/admin`. If the `Admin` module is not yet loaded when
+`Admin::UsersController` is hit, Rails needs first to autoload the constant
+`Admin`.
+
+If `autoload_paths` has a file called `admin.rb` Rails is going to load that
+one, but if there's no such file and a directory called `admin` is found, Rails
+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
+[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*.)
+
+The procedure to autoload constant `C` in an arbitrary situation is as follows:
+
+```
+if the class or module in which C is missing is Object
+ let ns = ''
+else
+ let M = the class or module in which C is missing
+
+ if M is anonymous
+ let ns = ''
+ else
+ let ns = M.name
+ end
+end
+
+loop do
+ # Look for a regular file.
+ for dir in autoload_paths
+ if the file "#{dir}/#{ns.underscore}/c.rb" exists
+ load/require "#{dir}/#{ns.underscore}/c.rb"
+
+ if C is now defined
+ return
+ else
+ raise LoadError
+ end
+ end
+ end
+
+ # Look for an automatic module.
+ for dir in autoload_paths
+ if the directory "#{dir}/#{ns.underscore}/c" exists
+ if ns is an empty string
+ let C = Module.new in Object and return
+ else
+ let C = Module.new in ns.constantize and return
+ end
+ end
+ end
+
+ if ns is empty
+ # We reached the top-level without finding the constant.
+ raise NameError
+ else
+ if C exists in any of the parent namespaces
+ # Qualified constants heuristic.
+ raise NameError
+ else
+ # Try again in the parent namespace.
+ let ns = the parent namespace of ns and retry
+ end
+ end
+end
+```
+
+
+require_dependency
+------------------
+
+Constant autoloading is triggered on demand and therefore code that uses a
+certain constant may have it already defined or may trigger an autoload. That
+depends on the execution path and it may vary between runs.
+
+There are times, however, in which you want to make sure a certain constant is
+known when the execution reaches some code. `require_dependency` provides a way
+to load a file using the current [loading mechanism](#loading-mechanism), and
+keeping track of constants defined in that file as if they were autoloaded to
+have them reloaded as needed.
+
+`require_dependency` is rarely needed, but see a couple of use-cases in
+[Autoloading and STI](#autoloading-and-sti) and [When Constants aren't
+Triggered](#when-constants-aren-t-missed).
+
+WARNING. Unlike autoloading, `require_dependency` does not expect the file to
+define any particular constant. Exploiting this behavior would be a bad practice
+though, file and constant paths should match.
+
+
+Constant Reloading
+------------------
+
+When `config.cache_classes` is false Rails is able to reload autoloaded
+constants.
+
+For example, in you're in a console session and edit some file behind the
+scenes, the code can be reloaded with the `reload!` command:
+
+```
+> reload!
+```
+
+When the application runs, code is reloaded when something relevant to this
+logic changes. In order to do that, Rails monitors a number of things:
+
+* `config/routes.rb`.
+
+* Locales.
+
+* Ruby files under `autoload_paths`.
+
+* `db/schema.rb` and `db/structure.sql`.
+
+If anything in there changes, there is a middleware that detects it and reloads
+the code.
+
+Autoloading keeps track of autoloaded constants. Reloading is implemented by
+removing them all from their respective classes and modules using
+`Module#remove_const`. That way, when the code goes on, those constants are
+going to be unknown again, and files reloaded on demand.
+
+INFO. This is an all-or-nothing operation, Rails does not attempt to reload only
+what changed since dependencies between classes makes that really tricky.
+Instead, everything is wiped.
+
+
+Module#autoload isn't Involved
+------------------------------
+
+`Module#autoload` provides a lazy way to load constants that is fully integrated
+with the Ruby constant lookup algorithms, dynamic constant API, etc. It is quite
+transparent.
+
+Rails internals make extensive use of it to defer as much work as possible from
+the boot process. But constant autoloading in Rails is **not** implemented with
+`Module#autoload`.
+
+One possible implementation based on `Module#autoload` would be to walk the
+application tree and issue `autoload` calls that map existing file names to
+their conventional constant name.
+
+There are a number of reasons that prevent Rails from using that implementation.
+
+For example, `Module#autoload` is only capable of loading files using `require`,
+so reloading would not be possible. Not only that, it uses an internal `require`
+which is not `Kernel#require`.
+
+Then, it provides no way to remove declarations in case a file is deleted. If a
+constant gets removed with `Module#remove_const` its `autoload` is not triggered
+again. Also, it doesn't support qualified names, so files with namespaces should
+be interpreted during the walk tree to install their own `autoload` calls, but
+those files could have constant references not yet configured.
+
+An implementation based on `Module#autoload` would be awesome but, as you see,
+at least as of today it is not possible. Constant autoloading in Rails is
+implemented with `Module#const_missing`, and that's why it has its own contract,
+documented in this guide.
+
+
+Common Gotchas
+--------------
+
+### Nesting and Qualified Constants
+
+Let's consider
+
+```ruby
+module Admin
+ class UsersController < ApplicationController
+ def index
+ @users = User.all
+ end
+ end
+end
+```
+
+and
+
+```ruby
+class Admin::UsersController < ApplicationController
+ def index
+ @users = User.all
+ end
+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).)
+
+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,
+`Admin::User` will get autoloaded in either case.
+
+Albeit qualified constants with `class` and `module` keywords may technically
+work with autoloading in some cases, it is preferable to use relative constants
+instead:
+
+```ruby
+module Admin
+ class UsersController < ApplicationController
+ def index
+ @users = User.all
+ end
+ end
+end
+```
+
+### Autoloading and STI
+
+Single Table Inheritance (STI) is a feature of Active Record that enables
+storing a hierarchy of models in one single table. The API of such models is
+aware of the hierarchy and encapsulates some common needs. For example, given
+these classes:
+
+```ruby
+# app/models/polygon.rb
+class Polygon < ActiveRecord::Base
+end
+
+# app/models/triangle.rb
+class Triangle < Polygon
+end
+
+# app/models/rectangle.rb
+class Rectangle < Polygon
+end
+```
+
+`Triangle.create` creates a row that represents a triangle, and
+`Rectangle.create` creates a row that represents a rectangle. If `id` is the
+ID of an existing record, `Polygon.find(id)` returns an object of the correct
+type.
+
+Methods that operate on collections are also aware of the hierarchy. For
+example, `Polygon.all` returns all the records of the table, because all
+rectangles and triangles are polygons. Active Record takes care of returning
+instances of their corresponding class in the result set.
+
+Types are autoloaded as needed. For example, if `Polygon.first` is a rectangle
+and `Rectangle` has not yet been loaded, Active Record autoloads it and the
+record is correctly instantiated.
+
+All good, but if instead of performing queries based on the root class we need
+to work on some subclass, things get interesting.
+
+While working with `Polygon` you do not need to be aware of all its descendants,
+because anything in the table is by definition a polygon, but when working with
+subclasses Active Record needs to be able to enumerate the types it is looking
+for. Let’s see an example.
+
+`Rectangle.all` only loads rectangles by adding a type constraint to the query:
+
+```sql
+SELECT "polygons".* FROM "polygons"
+WHERE "polygons"."type" IN ("Rectangle")
+```
+
+Let’s introduce now a subclass of `Rectangle`:
+
+```ruby
+# app/models/square.rb
+class Square < Rectangle
+end
+```
+
+`Rectangle.all` should now return rectangles **and** squares:
+
+```sql
+SELECT "polygons".* FROM "polygons"
+WHERE "polygons"."type" IN ("Rectangle", "Square")
+```
+
+But there’s a caveat here: How does Active Record know that the class `Square`
+exists at all?
+
+Even if the file `app/models/square.rb` exists and defines the `Square` class,
+if no code yet used that class, `Rectangle.all` issues the query
+
+```sql
+SELECT "polygons".* FROM "polygons"
+WHERE "polygons"."type" IN ("Rectangle")
+```
+
+That is not a bug, the query includes all *known* descendants of `Rectangle`.
+
+A way to ensure this works correctly regardless of the order of execution is to
+load the leaves of the tree by hand at the bottom of the file that defines the
+root class:
+
+```ruby
+# app/models/polygon.rb
+class Polygon < ActiveRecord::Base
+end
+require_dependency ‘square’
+```
+
+Only the leaves that are **at least grandchildren** need to be loaded this
+way. Direct subclasses do not need to be preloaded. If the hierarchy is
+deeper, intermediate classes will be autoloaded recursively from the bottom
+because their constant will appear in the class definitions as superclass.
+
+### Autoloading and `require`
+
+Files defining constants to be autoloaded should never be `require`d:
+
+```ruby
+require 'user' # DO NOT DO THIS
+
+class UsersController < ApplicationController
+ ...
+end
+```
+
+There are two possible gotchas here in development mode:
+
+1. If `User` is autoloaded before reaching the `require`, `app/models/user.rb`
+runs again because `load` does not update `$LOADED_FEATURES`.
+
+2. If the `require` runs first Rails does not mark `User` as an autoloaded
+constant and changes to `app/models/user.rb` aren't reloaded.
+
+Just follow the flow and use constant autoloading always, never mix
+autoloading and `require`. As a last resort, if some file absolutely needs to
+load a certain file use `require_dependency` to play nice with constant
+autoloading. This option is rarely needed in practice, though.
+
+Of course, using `require` in autoloaded files to load ordinary 3rd party
+libraries is fine, and Rails is able to distinguish their constants, they are
+not marked as autoloaded.
+
+### Autoloading and Initializers
+
+Consider this assignment in `config/initializers/set_auth_service.rb`:
+
+```ruby
+AUTH_SERVICE = if Rails.env.production?
+ RealAuthService
+else
+ MockedAuthService
+end
+```
+
+The purpose of this setup would be that the application uses the class that
+corresponds to the environment via `AUTH_SERVICE`. In development mode
+`MockedAuthService` gets autoloaded when the initializer runs. Let’s suppose
+we do some requests, change its implementation, and hit the application again.
+To our surprise the changes are not reflected. Why?
+
+As [we saw earlier](#constant-reloading), Rails removes autoloaded constants,
+but `AUTH_SERVICE` stores the original class object. Stale, non-reachable
+using the original constant, but perfectly functional.
+
+The following code summarizes the situation:
+
+```ruby
+class C
+ def quack
+ 'quack!'
+ end
+end
+
+X = C
+Object.instance_eval { remove_const(:C) }
+X.new.quack # => quack!
+X.name # => C
+C # => uninitialized constant C (NameError)
+```
+
+Because of that, it is not a good idea to autoload constants on application
+initialization.
+
+In the case above we could implement a dynamic access point:
+
+```ruby
+# app/models/auth_service.rb
+class AuthService
+ if Rails.env.production?
+ def self.instance
+ RealAuthService
+ end
+ else
+ def self.instance
+ MockedAuthService
+ end
+ end
+end
+```
+
+and have the application use `AuthService.instance` instead. `AuthService`
+would be loaded on demand and be autoload-friendly.
+
+### `require_dependency` and Initializers
+
+As we saw before, `require_dependency` loads files in an autoloading-friendly
+way. Normally, though, such a call does not make sense in an initializer.
+
+One could think about doing some [`require_dependency`](#require-dependency)
+calls in an initializer to make sure certain constants are loaded upfront, for
+example as an attempt to address the [gotcha with STIs](#autoloading-and-sti).
+
+Problem is, in development mode [autoloaded constants are wiped](#constant-reloading)
+if there is any relevant change in the file system. If that happens then
+we are in the very same situation the initializer wanted to avoid!
+
+Calls to `require_dependency` have to be strategically written in autoloaded
+spots.
+
+### When Constants aren't Missed
+
+#### Relative References
+
+Let's consider a flight simulator. The application has a default flight model
+
+```ruby
+# app/models/flight_model.rb
+class FlightModel
+end
+```
+
+that can be overridden by each airplane, for instance
+
+```ruby
+# app/models/bell_x1/flight_model.rb
+module BellX1
+ class FlightModel < FlightModel
+ end
+end
+
+# app/models/bell_x1/aircraft.rb
+module BellX1
+ class Aircraft
+ def initialize
+ @flight_model = FlightModel.new
+ end
+ end
+end
+```
+
+The initializer wants to create a `BellX1::FlightModel` and nesting has
+`BellX1`, that looks good. But if the default flight model is loaded and the
+one for the Bell-X1 is not, the interpreter is able to resolve the top-level
+`FlightModel` and autoloading is thus not triggered for `BellX1::FlightModel`.
+
+That code depends on the execution path.
+
+These kind of ambiguities can often be resolved using qualified constants:
+
+```ruby
+module BellX1
+ class Plane
+ def flight_model
+ @flight_model ||= BellX1::FlightModel.new
+ end
+ end
+end
+```
+
+Also, `require_dependency` is a solution:
+
+```ruby
+require_dependency 'bell_x1/flight_model'
+
+module BellX1
+ class Plane
+ def flight_model
+ @flight_model ||= FlightModel.new
+ end
+ end
+end
+```
+
+#### Qualified References
+
+Given
+
+```ruby
+# app/models/hotel.rb
+class Hotel
+end
+
+# app/models/image.rb
+class Image
+end
+
+# app/models/hotel/image.rb
+class Hotel
+ class Image < Image
+ end
+end
+```
+
+the expression `Hotel::Image` is ambiguous because it depends on the execution
+path.
+
+As [we saw before](#resolution-algorithm-for-qualified-constants), Ruby looks
+up the constant in `Hotel` and its ancestors. If `app/models/image.rb` has
+been loaded but `app/models/hotel/image.rb` hasn't, Ruby does not find `Image`
+in `Hotel`, but it does in `Object`:
+
+```
+$ bin/rails r 'Image; p Hotel::Image' 2>/dev/null
+Image # NOT Hotel::Image!
+```
+
+The code evaluating `Hotel::Image` needs to make sure
+`app/models/hotel/image.rb` has been loaded, possibly with
+`require_dependency`.
+
+In these cases the interpreter issues a warning though:
+
+```
+warning: toplevel constant Image referenced by Hotel::Image
+```
+
+This surprising constant resolution can be observed with any qualifying class:
+
+```
+2.1.5 :001 > String::Array
+(irb):1: warning: toplevel constant Array referenced by String::Array
+ => Array
+```
+
+WARNING. To find this gotcha the qualifying namespace has to be a class,
+`Object` is not an ancestor of modules.
+
+### Autoloading within Singleton Classes
+
+Let's suppose we have these class definitions:
+
+```ruby
+# app/models/hotel/services.rb
+module Hotel
+ class Services
+ end
+end
+
+# app/models/hotel/geo_location.rb
+module Hotel
+ class GeoLocation
+ class << self
+ Services
+ end
+ end
+end
+```
+
+If `Hotel::Services` is known by the time `app/models/hotel/geo_location.rb`
+is being loaded, `Services` is resolved by Ruby because `Hotel` belongs to the
+nesting when the singleton class of `Hotel::GeoLocation` is opened.
+
+But if `Hotel::Services` is not known, Rails is not able to autoload it, the
+application raises `NameError`.
+
+The reason is that autoloading is triggered for the singleton class, which is
+anonymous, and as [we saw before](#generic-procedure), Rails only checks the
+top-level namespace in that edge case.
+
+An easy solution to this caveat is to qualify the constant:
+
+```ruby
+module Hotel
+ class GeoLocation
+ class << self
+ Hotel::Services
+ end
+ end
+end
+```
+
+### Autoloading in `BasicObject`
+
+Direct descendants of `BasicObject` do not have `Object` among their ancestors
+and cannot resolve top-level constants:
+
+```ruby
+class C < BasicObject
+ String # NameError: uninitialized constant C::String
+end
+```
+
+When autoloading is involved that plot has a twist. Let's consider:
+
+```ruby
+class C < BasicObject
+ def user
+ User # WRONG
+ end
+end
+```
+
+Since Rails checks the top-level namespace `User` gets autoloaded just fine the
+first time the `user` method is invoked. You only get the exception if the
+`User` constant is known at that point, in particular in a *second* call to
+`user`:
+
+```ruby
+c = C.new
+c.user # surprisingly fine, User
+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).)
+
+As with pure Ruby, within the body of a direct descendant of `BasicObject` use
+always absolute constant paths:
+
+```ruby
+class C < BasicObject
+ ::String # RIGHT
+
+ def user
+ ::User # RIGHT
+ end
+end
+```
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index cbcd053950..61b991df61 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Caching with Rails: An overview
===============================
@@ -105,7 +107,7 @@ This method generates a cache key that depends on all products and can be used i
<% end %>
```
-If you want to cache a fragment under certain condition you can use `cache_if` or `cache_unless`
+If you want to cache a fragment under certain conditions, you can use `cache_if` or `cache_unless`
```erb
<% cache_if (condition, cache_key_for_products) do %>
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index e72bc81766..d14cdb93f2 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
The Rails Command Line
======================
@@ -24,7 +26,7 @@ There are a few commands that are absolutely critical to your everyday usage of
* `rails dbconsole`
* `rails new app_name`
-All commands can run with ```-h or --help``` to list more information.
+All commands can run with `-h` or `--help` to list more information.
Let's create a simple Rails application to step through each of these commands in context.
@@ -61,7 +63,7 @@ With no further work, `rails server` will run our new shiny Rails app:
$ cd commandsapp
$ bin/rails server
=> Booting WEBrick
-=> Rails 4.2.0 application starting in development on http://localhost:3000
+=> Rails 5.0.0 application starting in development on http://localhost:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2013-08-07 02:00:01] INFO WEBrick 1.3.1
@@ -151,9 +153,9 @@ $ bin/rails generate controller Greetings hello
create app/helpers/greetings_helper.rb
invoke assets
invoke coffee
- create app/assets/javascripts/greetings.js.coffee
+ create app/assets/javascripts/greetings.coffee
invoke scss
- create app/assets/stylesheets/greetings.css.scss
+ create app/assets/stylesheets/greetings.scss
```
What all did this generate? It made sure a bunch of directories were in our application, and created a controller file, a view file, a functional test file, a helper for the view, a JavaScript file and a stylesheet file.
@@ -239,11 +241,11 @@ $ bin/rails generate scaffold HighScore game:string score:integer
create app/views/high_scores/show.json.jbuilder
invoke assets
invoke coffee
- create app/assets/javascripts/high_scores.js.coffee
+ create app/assets/javascripts/high_scores.coffee
invoke scss
- create app/assets/stylesheets/high_scores.css.scss
+ create app/assets/stylesheets/high_scores.scss
invoke scss
- identical app/assets/stylesheets/scaffolds.css.scss
+ identical app/assets/stylesheets/scaffolds.scss
```
The generator checks that there exist the directories for models, controllers, helpers, layouts, functional and unit tests, stylesheets, creates the views, controller, model and database migration for HighScore (creating the `high_scores` table and fields), takes care of the route for the **resource**, and new tests for everything.
@@ -284,7 +286,7 @@ If you wish to test out some code without changing any data, you can do that by
```bash
$ bin/rails console --sandbox
-Loading development environment in sandbox (Rails 4.2.0)
+Loading development environment in sandbox (Rails 5.0.0)
Any modifications you make will be rolled back on exit
irb(main):001:0>
```
@@ -368,7 +370,7 @@ Rake is Ruby Make, a standalone Ruby utility that replaces the Unix utility 'mak
You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing `rake --tasks`. Each task has a description, and should help you find the thing you need.
-To get the full backtrace for running rake task you can pass the option ```--trace``` to command line, for example ```rake db:create --trace```.
+To get the full backtrace for running rake task you can pass the option `--trace` to command line, for example `rake db:create --trace`.
```bash
$ bin/rake --tasks
@@ -384,7 +386,7 @@ rake middleware # Prints out your Rack middleware stack
rake tmp:clear # Clear session, cache, and socket files from tmp/ (narrow w/ tmp:sessions:clear, tmp:cache:clear, tmp:sockets:clear)
rake tmp:create # Creates tmp directories for sessions, cache, sockets, and pids
```
-INFO: You can also use ```rake -T``` to get the list of tasks.
+INFO: You can also use `rake -T` to get the list of tasks.
### `about`
@@ -393,10 +395,10 @@ INFO: You can also use ```rake -T``` to get the list of tasks.
```bash
$ bin/rake about
About your application's environment
-Rails version 4.2.0
-Ruby version 1.9.3 (x86_64-linux)
-RubyGems version 1.3.6
-Rack version 1.3
+Rails version 5.0.0
+Ruby version 2.2.0 (x86_64-linux)
+RubyGems version 2.4.5
+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
Application root /home/foobar/commandsapp
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 7688962c01..0a375d7cb8 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Configuring Rails Applications
==============================
@@ -120,7 +122,7 @@ numbers. New applications filter out passwords by adding the following `config.f
* `secrets.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`.
-* `config.serve_static_assets` configures Rails itself to serve static assets. Defaults to true, but in the production environment is turned off as the server software (e.g. NGINX or Apache) used to run the application should serve static assets instead. Unlike the default setting set this to true when running (absolutely not recommended!) or testing your app in production mode using WEBrick. Otherwise you won't be able use page caching and requests for files that exist regularly under the public directory will anyway hit your Rails app.
+* `config.serve_static_files` configures Rails to serve static files. This option defaults to true, but in the production environment it is set to false because the server software (e.g. NGINX or Apache) used to run the application should serve static files instead. If you are running or testing your app in production mode using WEBrick (it is not recommended to use WEBrick in production) set the option to true. Otherwise, you won't be able to use page caching and request for files that exist under the public directory.
* `config.session_store` is usually set up in `config/initializers/session_store.rb` and specifies what class to use to store the session. Possible values are `:cookie_store` which is the default, `:mem_cache_store`, and `:disabled`. The last one tells Rails not to deal with sessions. Custom session stores can also be specified:
@@ -197,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_assets` is `false`.
+* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.serve_static_files` is `false`.
* `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.
@@ -318,6 +320,8 @@ The schema dumper adds one additional configuration option:
* `config.action_controller.default_charset` specifies the default character set for all renders. The default is "utf-8".
+* `config.action_controller.include_all_helpers` configures whether all view helpers are available everywhere or are scoped to the corresponding controller. If set to `false`, `UsersHelper` methods are only available for views rendered as part of `UsersController`. If `true`, `UsersHelper` methods are available everywhere. The default is `true`.
+
* `config.action_controller.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 Controller. Set to `nil` to disable logging.
* `config.action_controller.request_forgery_protection_token` sets the token parameter name for RequestForgery. Calling `protect_from_forgery` sets it to `:authenticity_token` by default.
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 4eb360cc7a..db3f19f8ac 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Contributing to Ruby on Rails
=============================
@@ -24,7 +26,7 @@ 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 do not find any issue addressing it you may proceed 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 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.)
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.
@@ -205,7 +207,7 @@ Rails follows a simple set of coding style conventions:
* Use Ruby >= 1.9 syntax for hashes. Prefer `{ a: :b }` over `{ :a => :b }`.
* Prefer `&&`/`||` over `and`/`or`.
* Prefer class << self over self.method for class methods.
-* Use `MyClass.my_method(my_arg)` not `my_method( my_arg )` or `my_method my_arg`.
+* Use `my_method(my_arg)` not `my_method( my_arg )` or `my_method my_arg`.
* Use `a = b` and not `a=b`.
* Use assert_not methods instead of refute.
* Prefer `method { do_stuff }` instead of `method{do_stuff}` for single-line blocks.
@@ -287,7 +289,12 @@ $ ruby -w -Itest test/mail_layout_test.rb -n test_explicit_class_layout
The `-n` option allows you to run a single method instead of the whole
file.
-##### Testing Active Record
+#### Testing Active Record
+
+First, create the databases you'll need. For MySQL and PostgreSQL,
+running the SQL statements `create database activerecord_unittest` and
+`create database activerecord_unittest2` is sufficient. This is not
+necessary for SQLite3.
This is how you run the Active Record test suite only for SQLite3:
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 1a647f8375..cef9ac083b 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Debugging Rails Applications
============================
@@ -309,7 +311,7 @@ For example:
```bash
=> Booting WEBrick
-=> Rails 4.2.0 application starting in development on http://0.0.0.0:3000
+=> Rails 5.0.0 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option)
=> Ctrl-C to shutdown server
@@ -422,11 +424,11 @@ then `backtrace` will supply the answer.
--> #0 ArticlesController.index
at /PathTo/project/test_app/app/controllers/articles_controller.rb:8
#1 ActionController::ImplicitRender.send_action(method#String, *args#Array)
- at /PathToGems/actionpack-4.2.0/lib/action_controller/metal/implicit_render.rb:4
+ at /PathToGems/actionpack-5.0.0/lib/action_controller/metal/implicit_render.rb:4
#2 AbstractController::Base.process_action(action#NilClass, *args#Array)
- at /PathToGems/actionpack-4.2.0/lib/abstract_controller/base.rb:189
+ at /PathToGems/actionpack-5.0.0/lib/abstract_controller/base.rb:189
#3 ActionController::Rendering.process_action(action#NilClass, *args#NilClass)
- at /PathToGems/actionpack-4.2.0/lib/action_controller/metal/rendering.rb:10
+ at /PathToGems/actionpack-5.0.0/lib/action_controller/metal/rendering.rb:10
...
```
@@ -438,7 +440,7 @@ context.
```
(byebug) frame 2
-[184, 193] in /PathToGems/actionpack-4.2.0/lib/abstract_controller/base.rb
+[184, 193] in /PathToGems/actionpack-5.0.0/lib/abstract_controller/base.rb
184: # is the intended way to override action dispatching.
185: #
186: # Notice that the first argument is the method to be dispatched
@@ -655,7 +657,7 @@ instruction to be executed. In this case, the activesupport's `week` method.
```
(byebug) step
-[50, 59] in /PathToGems/activesupport-4.2.0/lib/active_support/core_ext/numeric/time.rb
+[50, 59] in /PathToGems/activesupport-5.0.0/lib/active_support/core_ext/numeric/time.rb
50: ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
51: end
52: alias :day :days
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 3d9ec578ae..9eacc3a2fe 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Development Dependencies Install
================================
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 1b838201cc..134e9ddad2 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -86,8 +86,7 @@
-
name: Testing Rails Applications
url: testing.html
- work_in_progress: true
- description: This is a rather comprehensive guide to doing both unit and functional tests in Rails. It covers everything from 'What is a test?' to the testing APIs. Enjoy.
+ description: This is a rather comprehensive guide to the various testing facilities in Rails. It covers everything from 'What is a test?' to the testing APIs. Enjoy.
-
name: Securing Rails Applications
url: security.html
@@ -113,15 +112,25 @@
url: working_with_javascript_in_rails.html
description: This guide covers the built-in Ajax/JavaScript functionality of Rails.
-
- name: Getting Started with Engines
- url: engines.html
- description: This guide explains how to write a mountable engine.
- work_in_progress: true
- -
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
+ -
+ name: Constant Autoloading and Reloading
+ url: constant_autoloading_and_reloading.html
+ description: This guide documents how constant autoloading and reloading work.
+ -
+ name: Active Support Instrumentation
+ work_in_progress: true
+ url: active_support_instrumentation.html
+ description: This guide explains how to use the instrumentation API inside of Active Support to measure events inside of Rails and other Ruby code.
+ -
+ name: Profiling Rails Applications
+ work_in_progress: true
+ url: profiling.html
+ description: This guide explains how to profile your Rails applications to improve performance.
+
-
name: Extending Rails
documents:
@@ -138,6 +147,11 @@
name: Creating and Customizing Rails Generators
url: generators.html
description: This guide covers the process of adding a brand new generator to your extension or providing an alternative to an element of a built-in Rails generator (such as providing alternative test stubs for the scaffold generator).
+ -
+ name: Getting Started with Engines
+ url: engines.html
+ description: This guide explains how to write a mountable engine.
+ work_in_progress: true
-
name: Contributing to Ruby on Rails
documents:
diff --git a/guides/source/engines.md b/guides/source/engines.md
index a1f2da18ed..731178787f 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Getting Started with Engines
============================
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index f3f7415b3c..a8dcd3ee4f 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Form Helpers
============
diff --git a/guides/source/generators.md b/guides/source/generators.md
index f5d2c67cb4..05bf07b4c8 100644
--- a/guides/source/generators.md
+++ b/guides/source/generators.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Creating and Customizing Rails Generators & Templates
=====================================================
@@ -197,11 +199,11 @@ $ bin/rails generate scaffold User name:string
create app/views/users/show.json.jbuilder
invoke assets
invoke coffee
- create app/assets/javascripts/users.js.coffee
+ create app/assets/javascripts/users.coffee
invoke scss
- create app/assets/stylesheets/users.css.scss
+ create app/assets/stylesheets/users.scss
invoke scss
- create app/assets/stylesheets/scaffolds.css.scss
+ create app/assets/stylesheets/scaffolds.scss
```
Looking at this output, it's easy to understand how generators work in Rails 3.0 and above. The scaffold generator doesn't actually generate anything, it just invokes others to do the work. This allows us to add/replace/remove any of those invocations. For instance, the scaffold generator invokes the scaffold_controller generator, which invokes erb, test_unit and helper generators. Since each generator has a single responsibility, they are easy to reuse, avoiding code duplication.
@@ -407,7 +409,7 @@ $ bin/rails generate scaffold Comment body:text
create app/views/comments/show.json.jbuilder
invoke assets
invoke coffee
- create app/assets/javascripts/comments.js.coffee
+ create app/assets/javascripts/comments.coffee
invoke scss
```
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index dc63ae62b1..e803f95911 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Getting Started with Rails
==========================
@@ -90,18 +92,18 @@ current version of Ruby installed:
TIP: A number of tools exist to help you quickly install Ruby and Ruby
on Rails on your system. Windows users can use [Rails Installer](http://railsinstaller.org),
while Mac OS X users can use [Tokaido](https://github.com/tokaido/tokaidoapp).
+For more installation methods for most Operating Systems take a look at
+[ruby-lang.org](https://www.ruby-lang.org/en/documentation/installation/).
```bash
$ ruby -v
ruby 2.0.0p353
```
-If you don't have Ruby installed have a look at
-[ruby-lang.org](https://www.ruby-lang.org/en/installation/) for possible ways to
-install Ruby on your platform.
-
-Many popular UNIX-like OSes ship with an acceptable version of SQLite3. Windows
-users and others can find installation instructions at the [SQLite3 website](https://www.sqlite.org).
+Many popular UNIX-like OSes ship with an acceptable version of SQLite3.
+On Windows, if you installed Rails through Rails Installer, you
+already have SQLite installed. Others can find installation instructions
+at the [SQLite3 website](https://www.sqlite.org).
Verify that it is correctly installed and in your PATH:
```bash
@@ -123,7 +125,7 @@ run the following:
$ rails --version
```
-If it says something like "Rails 4.2.0", you are ready to continue.
+If it says something like "Rails 5.0.0", you are ready to continue.
### Creating the Blog Application
@@ -259,9 +261,9 @@ invoke helper
create app/helpers/welcome_helper.rb
invoke assets
invoke coffee
-create app/assets/javascripts/welcome.js.coffee
+create app/assets/javascripts/welcome.coffee
invoke scss
-create app/assets/stylesheets/welcome.css.scss
+create app/assets/stylesheets/welcome.scss
```
Most important of these are of course the controller, located at
@@ -300,8 +302,9 @@ Rails.application.routes.draw do
# ...
```
-This is your application's _routing file_ which holds entries in a special DSL
-(domain-specific language) that tells Rails how to connect incoming requests to
+This is your application's _routing file_ which holds entries in a special
+[DSL (domain-specific language)](http://en.wikipedia.org/wiki/Domain-specific_language)
+that tells Rails how to connect incoming requests to
controllers and actions. This file contains many sample routes on commented
lines, and one of them actually shows you how to connect the root of your site
to a specific controller and action. Find the line beginning with `root` and
@@ -422,12 +425,12 @@ If you refresh <http://localhost:3000/articles/new> now, you'll get a new error:
This error indicates that Rails cannot find the `new` action inside the
`ArticlesController` that you just generated. This is because when controllers
are generated in Rails they are empty by default, unless you tell it
-your wanted actions during the generation process.
+your desired actions during the generation process.
To manually define an action inside a controller, all you need to do is to
define a new method inside the controller. Open
`app/controllers/articles_controller.rb` and inside the `ArticlesController`
-class, define a `new` method so that the controller now looks like this:
+class, define the `new` method so that your controller now looks like this:
```ruby
class ArticlesController < ApplicationController
@@ -444,23 +447,23 @@ With the `new` method defined in `ArticlesController`, if you refresh
You're getting this error now because Rails expects plain actions like this one
to have views associated with them to display their information. With no view
-available, Rails errors out.
+available, Rails will raise an exception.
In the above image, the bottom line has been truncated. Let's see what the full
-thing looks like:
+error message looks like:
>Missing template articles/new, application/new with {locale:[:en], formats:[:html], handlers:[:erb, :builder, :coffee]}. Searched in: * "/path/to/blog/app/views"
That's quite a lot of text! Let's quickly go through and understand what each
-part of it does.
+part of it means.
-The first part identifies what template is missing. In this case, it's the
+The first part identifies which template is missing. In this case, it's the
`articles/new` template. Rails will first look for this template. If not found,
then it will attempt to load a template called `application/new`. It looks for
one here because the `ArticlesController` inherits from `ApplicationController`.
The next part of the message contains a hash. The `:locale` key in this hash
-simply indicates what spoken language template should be retrieved. By default,
+simply indicates which spoken language template should be retrieved. By default,
this is the English - or "en" - template. The next key, `:formats` specifies the
format of template to be served in response. The default format is `:html`, and
so Rails is looking for an HTML template. The final key, `:handlers`, is telling
@@ -473,14 +476,16 @@ Templates within a basic Rails application like this are kept in a single
location, but in more complex applications it could be many different paths.
The simplest template that would work in this case would be one located at
-`app/views/articles/new.html.erb`. The extension of this file name is key: the
-first extension is the _format_ of the template, and the second extension is the
-_handler_ that will be used. Rails is attempting to find a template called
-`articles/new` within `app/views` for the application. The format for this
-template can only be `html` and the handler must be one of `erb`, `builder` or
-`coffee`. Because you want to create a new HTML form, you will be using the `ERB`
-language. Therefore the file should be called `articles/new.html.erb` and needs
-to be located inside the `app/views` directory of the application.
+`app/views/articles/new.html.erb`. The extension of this file name is important:
+the first extension is the _format_ of the template, and the second extension
+is the _handler_ that will be used. Rails is attempting to find a template
+called `articles/new` within `app/views` for the application. The format for
+this template can only be `html` and the handler must be one of `erb`,
+`builder` or `coffee`. Because you want to create a new HTML form, you will be
+using the `ERB` language which is designed to embed Ruby in HTML.
+
+Therefore the file should be called `articles/new.html.erb` and needs to be
+located inside the `app/views` directory of the application.
Go ahead now and create a new file at `app/views/articles/new.html.erb` and
write this content in it:
@@ -665,8 +670,8 @@ rake commands to run migrations, and it's possible to undo a migration after
it's been applied to your database. Migration filenames include a timestamp to
ensure that they're processed in the order that they were created.
-If you look in the `db/migrate/20140120191729_create_articles.rb` file (remember,
-yours will have a slightly different name), here's what you'll find:
+If you look in the `db/migrate/YYYYMMDDHHMMSS_create_articles.rb` file
+(remember, yours will have a slightly different name), here's what you'll find:
```ruby
class CreateArticles < ActiveRecord::Migration
@@ -675,7 +680,7 @@ class CreateArticles < ActiveRecord::Migration
t.string :title
t.text :text
- t.timestamps
+ t.timestamps null: false
end
end
end
@@ -736,7 +741,7 @@ database columns. In the first line we do just that (remember that
`@article.save` is responsible for saving the model in the database. Finally,
we redirect the user to the `show` action, which we'll define later.
-TIP: You might be wondering why the `A` in `Article.new` is capitalized above, whereas most other references to articles in this guide have used lowercase. In this context, we are referring to the class named `Article` that is defined in `\models\article.rb`. Class names in Ruby must begin with a capital letter.
+TIP: You might be wondering why the `A` in `Article.new` is capitalized above, whereas most other references to articles in this guide have used lowercase. In this context, we are referring to the class named `Article` that is defined in `app/models/article.rb`. Class names in Ruby must begin with a capital letter.
TIP: As we'll see later, `@article.save` returns a boolean indicating whether
the article was saved or not.
@@ -1537,8 +1542,9 @@ class CreateComments < ActiveRecord::Migration
# this line adds an integer column called `article_id`.
t.references :article, index: true
- t.timestamps
+ t.timestamps null: false
end
+ add_foreign_key :comments, :articles
end
end
```
@@ -1558,6 +1564,8 @@ run against the current database, so in this case you will just see:
== CreateComments: migrating =================================================
-- create_table(:comments)
-> 0.0115s
+-- add_foreign_key(:comments, :articles)
+ -> 0.0000s
== CreateComments: migrated (0.0119s) ========================================
```
@@ -1635,8 +1643,8 @@ This creates five files and one empty directory:
| app/views/comments/ | Views of the controller are stored here |
| test/controllers/comments_controller_test.rb | The test for the controller |
| app/helpers/comments_helper.rb | A view helper file |
-| app/assets/javascripts/comment.js.coffee | CoffeeScript for the controller |
-| app/assets/stylesheets/comment.css.scss | Cascading style sheet for the controller |
+| app/assets/javascripts/comment.coffee | CoffeeScript for the controller |
+| app/assets/stylesheets/comment.scss | Cascading style sheet for the controller |
Like with any blog, our readers will create their comments directly after
reading the article, and once they have added their comment, will be sent back
@@ -2029,9 +2037,14 @@ What's Next?
------------
Now that you've seen your first Rails application, you should feel free to
-update it and experiment on your own. But you don't have to do everything
-without help. As you need assistance getting up and running with Rails, feel
-free to consult these support resources:
+update it and experiment on your own.
+
+We recommend next that you read [A Guide to Testing Rails Applications](testing.html),
+for a deep dive into Rails testing facilities and approaches.
+
+Remember you don't have to do everything without help. As you need assistance
+getting up and running with Rails, feel free to consult these support
+resources:
* The [Ruby on Rails Guides](index.html)
* The [Ruby on Rails Tutorial](http://railstutorial.org/book)
@@ -2049,7 +2062,7 @@ command-line utility:
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 RedCloth and Nokogiri gems. Add it to your `Gemfile` and run
+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 f6cbc1823a..bd6babff41 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Rails Internationalization (I18n) API
=====================================
@@ -626,7 +628,7 @@ entry[count == 1 ? 0 : 1]
I.e. the translation denoted as `:one` is regarded as singular, the other is used as plural (including the count being zero).
-If the lookup for the key does not return a Hash suitable for pluralization, an `18n::InvalidPluralizationData` exception is raised.
+If the lookup for the key does not return a Hash suitable for pluralization, an `I18n::InvalidPluralizationData` exception is raised.
### Setting and Passing a Locale
diff --git a/guides/source/initialization.md b/guides/source/initialization.md
index 53bf3039fa..0acf094f71 100644
--- a/guides/source/initialization.md
+++ b/guides/source/initialization.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
The Rails Initialization Process
================================
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index ae16ad86cd..c3cde49630 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Layouts and Rendering in Rails
==============================
@@ -425,6 +427,9 @@ 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
+(100-199, 204, 205 or 304), it will be dropped from the response.
+
#### 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.
@@ -904,7 +909,10 @@ You can also specify multiple videos to play by passing an array of videos to th
This will produce:
```erb
-<video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
+<video>
+ <source src="/videos/trailer.ogg">
+ <source src="/videos/movie.ogg">
+</video>
```
#### Linking to Audio Files with the `audio_tag`
@@ -1022,6 +1030,42 @@ One way to use partials is to treat them as the equivalent of subroutines: as a
Here, the `_ad_banner.html.erb` and `_footer.html.erb` partials could contain content that is shared among many pages in your application. You don't need to see the details of these sections when you're concentrating on a particular page.
+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:
+
+* `users/index.html.erb`
+
+ ```html+erb
+ <%= render "shared/search_filters", search: @q do |f| %>
+ <p>
+ Name contains: <%= f.text_field :name_contains %>
+ </p>
+ <%= end %>
+ ```
+
+* `roles/index.html.erb`
+
+ ```html+erb
+ <%= render "shared/search_filters", search: @q do |f| %>
+ <p>
+ Title contains: <%= f.text_field :title_contains %>
+ </p>
+ <%= end %>
+ ```
+
+* `shared/_search_filters.html.erb`
+
+ ```html+erb
+ <%= form_for(@q) do |f| %>
+ <h1>Search form:</h1>
+ <fieldset>
+ <%= yield f %>
+ </fieldset>
+ <p>
+ <%= f.submit "Search" %>
+ </p>
+ <% end %>
+ ```
+
TIP: For content that is shared among all pages in your application, you can use partials directly from layouts.
#### Partial Layouts
diff --git a/guides/source/maintenance_policy.md b/guides/source/maintenance_policy.md
index 050a64ddf3..45cdc549f7 100644
--- a/guides/source/maintenance_policy.md
+++ b/guides/source/maintenance_policy.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN 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 f0ee34cfb1..44236ad239 100644
--- a/guides/source/nested_model_forms.md
+++ b/guides/source/nested_model_forms.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Rails Nested Model Forms
========================
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index 7b7eb80081..bd884441ac 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
The Basics of Creating Rails Plugins
====================================
@@ -433,7 +435,7 @@ Once your README is solid, go through and add rdoc comments to all of the method
Once your comments are good to go, navigate to your plugin directory and run:
```bash
-$ bin/rake rdoc
+$ bundle exec rake rdoc
```
### References
diff --git a/guides/source/profiling.md b/guides/source/profiling.md
new file mode 100644
index 0000000000..695b09647f
--- /dev/null
+++ b/guides/source/profiling.md
@@ -0,0 +1,16 @@
+*DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
+A Guide to Profiling Rails Applications
+=======================================
+
+This guide covers built-in mechanisms in Rails for profiling your application.
+
+After reading this guide, you will know:
+
+* Rails profiling terminology.
+* How to write benchmark tests for your application.
+* Other benchmarking approaches and plugins.
+
+--------------------------------------------------------------------------------
+
+
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index 6512b14e60..0db777b9bb 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Rails Application Templates
===========================
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index 0dec0e139b..bfe4ced87b 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Rails on Rack
=============
@@ -233,7 +235,7 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
**`ActionDispatch::Static`**
-* Used to serve static assets. Disabled if `config.serve_static_assets` is `false`.
+* Used to serve static files. Disabled if `config.serve_static_files` is `false`.
**`Rack::Lock`**
diff --git a/guides/source/routing.md b/guides/source/routing.md
index b1a287f53a..893cedeefc 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Rails Routing from the Outside In
=================================
diff --git a/guides/source/ruby_on_rails_guides_guidelines.md b/guides/source/ruby_on_rails_guides_guidelines.md
index c0438f6341..0ecf8a80df 100644
--- a/guides/source/ruby_on_rails_guides_guidelines.md
+++ b/guides/source/ruby_on_rails_guides_guidelines.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails Guides Guidelines
===============================
diff --git a/guides/source/security.md b/guides/source/security.md
index b1c5b22338..4a80edbdad 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Ruby on Rails Security Guide
============================
@@ -237,7 +239,7 @@ Or the attacker places the code into the onmouseover event handler of an image:
<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />
```
-There are many other possibilities, like using a `<script>` tag to make a cross-site request to a URL with a JSONP or JavaScript response. The response is executable code that the attacker can find a way to run, possibly extracting sensitive data. To protect against this data leakage, we disallow cross-site `<script>` tags. Only Ajax requests may have JavaScript responses since XmlHttpRequest is subject to the browser Same-Origin policy - meaning only your site can initiate the request.
+There are many other possibilities, like using a `<script>` tag to make a cross-site request to a URL with a JSONP or JavaScript response. The response is executable code that the attacker can find a way to run, possibly extracting sensitive data. To protect against this data leakage, we disallow cross-site `<script>` tags. Only Ajax requests may have JavaScript responses since `XMLHttpRequest` is subject to the browser Same-Origin policy - meaning only your site can initiate the request.
To protect against all other forged requests, we introduce a _required security token_ that our site knows but other sites don't know. We include the security token in requests and verify it on the server. This is a one-liner in your application controller, and is the default for newly created rails applications:
@@ -247,6 +249,8 @@ protect_from_forgery with: :exception
This will automatically include a security token in all forms and Ajax requests generated by Rails. If the security token doesn't match what was expected, an exception will be thrown.
+NOTE: By default, Rails includes jQuery and an [unobtrusive scripting adapter for jQuery](https://github.com/rails/jquery-ujs), which adds a header called `X-CSRF-Token` on every non-GET Ajax call made by jQuery with the security token. Without this header, non-GET Ajax requests won't be accepted by Rails. When using another library to make Ajax calls, it is necessary to add the security token as a default header for Ajax calls in your library. To get the token, have a look at `<meta name='csrf-token' content='THE-TOKEN'>` tag printed by `<%= csrf_meta_tags %>` in your application view.
+
It is common to use persistent cookies to store user information, with `cookies.permanent` for example. In this case, the cookies will not be cleared and the out of the box CSRF protection will not be effective. If you are using a different cookie store than the session for this information, you must handle what to do with it yourself:
```ruby
@@ -942,7 +946,7 @@ unless params[:token].nil?
end
```
-When `params[:token]` is one of: `[]`, `[nil]`, `[nil, nil, ...]` or
+When `params[:token]` is one of: `[nil]`, `[nil, nil, ...]` or
`['foo', nil]` it will bypass the test for `nil`, but `IS NULL` or
`IN ('foo', NULL)` where clauses still will be added to the SQL query.
@@ -953,9 +957,9 @@ request:
| JSON | Parameters |
|-----------------------------------|--------------------------|
| `{ "person": null }` | `{ :person => nil }` |
-| `{ "person": [] }` | `{ :person => nil }` |
-| `{ "person": [null] }` | `{ :person => nil }` |
-| `{ "person": [null, null, ...] }` | `{ :person => nil }` |
+| `{ "person": [] }` | `{ :person => [] }` |
+| `{ "person": [null] }` | `{ :person => [] }` |
+| `{ "person": [null, null, ...] }` | `{ :person => [] }` |
| `{ "person": ["foo", null] }` | `{ :person => ["foo"] }` |
It is possible to return to old behaviour and disable `deep_munge` configuring
diff --git a/guides/source/testing.md b/guides/source/testing.md
index b4c70dfa1d..21b0b37efa 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
A Guide to Testing Rails Applications
=====================================
@@ -29,11 +31,13 @@ Testing support was woven into the Rails fabric from the beginning. It wasn't an
By default, every Rails application has three environments: development, test, and production. The database for each one of them is configured in `config/database.yml`.
-A dedicated test database allows you to set up and interact with test data in isolation. Tests can mangle test data with confidence, that won't touch the data in the development or production databases.
+A dedicated test database allows you to set up and interact with test data in isolation. This way your tests can mangle test data with confidence, without worrying about the data in the development or production databases.
+
+Also, each environment's configuration can be modified similarly. In this case, we can modify our test environment by changing the options found in `config/environments/test.rb`.
### Rails Sets up for Testing from the Word Go
-Rails creates a `test` folder for you as soon as you create a Rails project using `rails new` _application_name_. If you list the contents of this folder then you shall see:
+Rails creates a `test` directory for you as soon as you create a Rails project using `rails new` _application_name_. If you list the contents of this directory then you shall see:
```bash
$ ls -F test
@@ -41,9 +45,9 @@ controllers/ helpers/ mailers/ test_helper.rb
fixtures/ integration/ models/
```
-The `models` directory is meant to hold tests for your models, the `controllers` directory is meant to hold tests for your controllers and the `integration` directory is meant to hold tests that involve any number of controllers interacting.
+The `models` directory is meant to hold tests for your models, the `controllers` directory is meant to hold tests for your controllers and the `integration` directory is meant to hold tests that involve any number of controllers interacting. There is also a directory for testing your mailers and one for testing view helpers.
-Fixtures are a way of organizing test data; they reside in the `fixtures` folder.
+Fixtures are a way of organizing test data; they reside in the `fixtures` directory.
The `test_helper.rb` file holds the default configuration for your tests.
@@ -51,7 +55,7 @@ The `test_helper.rb` file holds the default configuration for your tests.
For good tests, you'll need to give some thought to setting up test data.
In Rails, you can handle this by defining and customizing fixtures.
-You can find comprehensive documentation in the [fixture api documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
+You can find comprehensive documentation in the [Fixtures API documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
#### What Are Fixtures?
@@ -61,7 +65,7 @@ You'll find fixtures under your `test/fixtures` directory. When you run `rails g
#### YAML
-YAML-formatted fixtures are a very human-friendly way to describe your sample data. These types of fixtures have the **.yml** file extension (as in `users.yml`).
+YAML-formatted fixtures are a human-friendly way to describe your sample data. These types of fixtures have the **.yml** file extension (as in `users.yml`).
Here's a sample YAML fixture file:
@@ -78,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. Keys which resemble YAML keywords such as 'yes' and 'no' are quoted so that the YAML Parser correctly interprets them.
+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.
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
@@ -96,11 +100,9 @@ one:
category: about
```
-Note: For associations to reference one another by name, you cannot specify the `id:`
- attribute on the fixtures. Rails will auto assign a primary key to be consistent between
- runs. If you manually specify an `id:` attribute, this behavior will not work. For more
- information on this association behavior please read the
- [fixture api documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
+Notice the `category` key of the `one` article found in `fixtures/articles.yml` has a value of `about`. This tells Rails to load the category `about` found in `fixtures/categories.yml`.
+
+NOTE: For associations to reference one another by name, you cannot specify the `id:` attribute on the associated fixtures. Rails will auto assign a primary key to be consistent between runs. For more information on this association behavior please read the [Fixtures API documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
#### ERB'in It Up
@@ -116,15 +118,17 @@ user_<%= n %>:
#### Fixtures in Action
-Rails by default automatically loads all fixtures from the `test/fixtures` folder for your models and controllers test. Loading involves three steps:
+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 variable in case you want to access it directly
+* 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))
#### Fixtures are Active Record objects
-Fixtures are instances of Active Record. As mentioned in point #3 above, you can access the object directly because it is automatically setup as a local variable of the test case. For example:
+Fixtures are instances of Active Record. As mentioned in point #3 above, you can access the object directly because it is automatically available as a method whose scope is local of the test case. For example:
```ruby
# this will return the User object for the fixture named david
@@ -137,16 +141,35 @@ users(:david).id
email(david.girlfriend.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 |
+
+We will cover each of types Rails tests listed above in this guide.
+
Unit Testing your Models
------------------------
-In Rails, models tests are what you write to test your models.
-
-For this guide we will be using Rails _scaffolding_. It will create the model, a migration, controller and views for the new resource in a single operation. It will also create a full test suite following Rails best practices. We will be using examples from this generated code and will be supplementing it with additional examples where necessary.
+In Rails, unit tests are what you write to test your models.
-NOTE: For more information on Rails _scaffolding_, refer to [Getting Started with Rails](getting_started.html)
+For this guide we will be using the application we built in the [Getting Started with Rails](getting_started.html) guide.
-When you use `rails generate scaffold`, for a resource among other things it creates a test stub in the `test/models` folder:
+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:
```bash
$ bin/rails generate scaffold article title:string body:text
@@ -175,18 +198,18 @@ A line by line examination of this file will help get you oriented to Rails test
require 'test_helper'
```
-As you know by now, `test_helper.rb` specifies the default configuration to run our tests. This is included with all the tests, so any methods added to this file are available to all your tests.
+By requiring this file, `test_helper.rb` the default configuration to run our tests is loaded. We will include this with all the tests we write, so any methods added to this file are available to all your tests.
```ruby
class ArticleTest < ActiveSupport::TestCase
```
-The `ArticleTest` class defines a _test case_ because it inherits from `ActiveSupport::TestCase`. `ArticleTest` thus has all the methods available from `ActiveSupport::TestCase`. You'll see those methods a little later in this guide.
+The `ArticleTest` class defines a _test case_ because it inherits from `ActiveSupport::TestCase`. `ArticleTest` thus has all the methods available from `ActiveSupport::TestCase`. Later in this guide, you'll see some of the methods it gives you.
Any method defined within a class inherited from `Minitest::Test`
-(which is the superclass of `ActiveSupport::TestCase`) that begins with `test_` (case sensitive) is simply called a test. So, `test_password` and `test_valid_password` are legal test names and are run automatically when the test case is run.
+(which is the superclass of `ActiveSupport::TestCase`) that begins with `test_` (case sensitive) is simply called a test. So, methods defined as `test_password` and `test_valid_password` are legal test names and are run automatically when the test case is run.
-Rails adds a `test` method that takes a test name and a block. It generates a normal `Minitest::Unit` test with method names prefixed with `test_`. So,
+Rails also adds a `test` method that takes a test name and a block. It generates a normal `Minitest::Unit` test with method names prefixed with `test_`. So you don't have to worry about naming the methods, and you can write something like:
```ruby
test "the truth" do
@@ -194,7 +217,7 @@ test "the truth" do
end
```
-acts as if you had written
+Which is approximately the same as writing this:
```ruby
def test_the_truth
@@ -202,26 +225,37 @@ def test_the_truth
end
```
-only the `test` macro allows a more readable test name. You can still use regular method definitions though.
+However only the `test` macro allows a more readable test name. You can still use regular method definitions though.
-NOTE: The method name is generated by replacing spaces with underscores. The result does not need to be a valid Ruby identifier though, the name may contain punctuation characters etc. That's because in Ruby technically any string may be a method name. Odd ones need `define_method` and `send` calls, but formally there's no restriction.
+NOTE: The method name is generated by replacing spaces with underscores. The result does not need to be a valid Ruby identifier though, the name may contain punctuation characters etc. That's because in Ruby technically any string may be a method name. This may require use of `define_method` and `send` calls to function properly, but formally there's little restriction on the name.
+
+Next, let's look at our first assertion:
```ruby
assert true
```
-This line of code is called an _assertion_. An assertion is a line of code that evaluates an object (or expression) for expected results. For example, an assertion can check:
+An assertion is a line of code that evaluates an object (or expression) for expected results. For example, an assertion can check:
* does this value = that value?
* is this object nil?
* does this line of code throw an exception?
* is the user's password greater than 5 characters?
-Every test contains one or more assertions. Only when all the assertions are successful will the test pass.
+Every test must contain at least one assertion, with no restriction as to how many assertions are allowed. Only when all the assertions are successful will the test pass.
### Maintaining the test database schema
-In order to run your tests, your test database will need to have the current structure. The test helper checks whether your test database has any pending migrations. If so, it will try to load your `db/schema.rb` or `db/structure.sql` into the test database. If migrations are still pending, an error will be raised.
+In order to run your tests, your test database will need to have the current
+structure. The test helper checks whether your test database has any pending
+migrations. If so, it will try to load your `db/schema.rb` or `db/structure.sql`
+into the test database. If migrations are still pending, an error will be
+raised. Usually this indicates that your schema is not fully migrated. Running
+the migrations against the development database (`bin/rake db:migrate`) will
+bring the schema up to date.
+
+NOTE: If existing migrations required modifications, the test database needs to
+be rebuilt. This can be done by executing `bin/rake db:test:prepare`.
### Running Tests
@@ -247,10 +281,12 @@ 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. Note that `test_helper.rb` is in the `test` directory, hence this directory needs to be added to the load path using the `-I` switch.
+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
+
To see how a test failure is reported, you can add a failing test to the `article_test.rb` test case.
```ruby
@@ -313,7 +349,7 @@ Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
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).
-TIP: Many Rails developers practice _Test-Driven Development_ (TDD). This is an excellent way to build up a test suite that exercises every part of your application. TDD is beyond the scope of this guide, but one place to start is with [15 TDD steps to create a Rails application](http://andrzejonsoftware.blogspot.com/2007/05/15-tdd-steps-to-create-rails.html).
+#### What an error looks like
To see how an error gets reported, here's a test containing an error:
@@ -356,52 +392,26 @@ behavior:
$ BACKTRACE=1 bin/rake test test/models/article_test.rb
```
-### What to Include in Your Unit Tests
+If we want this test to pass we can modify it to use `assert_raises` like so:
-Ideally, you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.
+```ruby
+test "should report error" do
+ # some_undefined_variable is not defined elsewhere in the test case
+ assert_raises(NameError) do
+ some_undefined_variable
+ end
+end
+```
+
+This test should now pass.
### Available Assertions
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.
-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 or descends from `class`.|
-| `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 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)
+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)
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.
@@ -423,10 +433,24 @@ Rails adds some custom assertions of its own to the `minitest` framework:
You'll see the usage of some of these assertions in the next chapter.
+### A Brief Note About Minitest
+
+All the basic assertions such as `assert_equal` defined in `Minitest::Assertions` are also available in the classes we use in our own test cases. In fact, Rails provides the following classes for you to inherit from:
+
+* `ActiveSupport::TestCase`
+* `ActionController::TestCase`
+* `ActionMailer::TestCase`
+* `ActionView::TestCase`
+* `ActionDispatch::IntegrationTest`
+
+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)
+
Functional Tests for Your Controllers
-------------------------------------
-In Rails, testing the various actions of a single controller is called writing functional tests for that controller. Controllers handle the incoming web requests to your application and eventually respond with a rendered view.
+In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you're testing how your actions handle the requests and the expected result, or response in some cases an HTML view.
### What to Include in your Functional Tests
@@ -500,13 +524,13 @@ If you're familiar with the HTTP protocol, you'll know that `get` is a type of r
* `head`
* `delete`
-All of request types are methods that you can use, however, you'll probably end up using the first two more often than the others.
+All of request types have equivalent methods that you can use. In a typical C.R.U.D. application you'll be using `get`, `post`, `put` and `delete` more often.
-NOTE: Functional tests do not verify whether the specified request type should be accepted by the action. Request types in this context exist to make your tests more descriptive.
+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.
### The Four Hashes of the Apocalypse
-After a request has been made using one of the 6 methods (`get`, `post`, etc.) and processed, you will have 4 Hash objects ready for use:
+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.
@@ -529,8 +553,8 @@ assigns["something"] assigns(:something)
You also have access to three instance variables in your functional tests:
* `@controller` - The controller processing the request
-* `@request` - The request
-* `@response` - The response
+* `@request` - The request object
+* `@response` - The response object
### Setting Headers and CGI variables
@@ -551,6 +575,10 @@ 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:
@@ -559,24 +587,22 @@ 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 that you cannot test for template and layout at the same time, with one call to `assert_template` method.
-Also, for the `layout` test, you can give a regular expression instead of a string, but using the string, makes
-things clearer. On the other hand, you have to include the "layouts" directory name even if you save your layout
-file in this standard layout directory. Hence,
+NOTE: You cannot test for template and layout at the same time, with a single call to `assert_template`.
-```ruby
-assert_template layout: "application"
-```
+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.
-will not work.
+#### Asserting Partials
-If your view renders any partial, when asserting for the layout, you have to assert for the partial at the same time.
+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.
-Hence:
+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
@@ -585,27 +611,201 @@ test "new should render correct layout" do
end
```
-is the correct way to assert for the layout when the view renders a partial with name `_form`. Omitting the `:partial` key in your `assert_template` call will complain.
+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`.
-### A Fuller Functional Test Example
+We want to add a `flash` message to our blog application whenever someone
+successfully creates a new Article.
-Here's another example that uses `flash`, `assert_redirected_to`, and `assert_difference`:
+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: 'Hi', body: 'This is my first article.'}
+ post :create, article: {title: 'Some title'}
end
+
assert_redirected_to article_path(assigns(:article))
assert_equal 'Article was successfully created.', flash[:notice]
end
```
-### Testing Views
+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
+Run options: -n test_should_create_article --seed 32266
+
+# Running:
+
+F
+
+Finished in 0.114870s, 8.7055 runs/s, 34.8220 assertions/s.
+
+ 1) Failure:
+ArticlesControllerTest#test_should_create_article [/Users/zzak/code/bench/sharedapp/test/controllers/articles_controller_test.rb:16]:
+--- expected
++++ actual
+@@ -1 +1 @@
+-"Article was successfully created."
++nil
+
+1 runs, 4 assertions, 1 failures, 0 errors, 0 skips
+```
+
+Let's implement the flash message now in our controller. Our `:create` action should now look like this:
+
+```ruby
+def create
+ @article = Article.new(article_params)
+
+ if @article.save
+ flash[:notice] = 'Article was successfully created.'
+ redirect_to @article
+ else
+ render 'new'
+ end
+end
+```
+
+Now if we run our tests, we should see it pass:
-Testing the response to your request by asserting the presence of key HTML elements and their content is a useful way to test the views of your application. The `assert_select` assertion allows you to do this by using a simple yet powerful syntax.
+```bash
+$ bin/rake test test/controllers/articles_controller_test.rb test_should_create_article
+Run options: -n test_should_create_article --seed 18981
+
+# Running:
+
+.
+
+Finished in 0.081972s, 12.1993 runs/s, 48.7972 assertions/s.
-NOTE: You may find references to `assert_tag` in other documentation. This has been removed in 4.2. Use `assert_select` instead.
+1 runs, 4 assertions, 0 failures, 0 errors, 0 skips
+```
+
+### Putting it together
+
+At this point our Articles controller tests the `:index` as well as `:new` and `:create` actions. What about dealing with existing data?
+
+Let's write a test for the `:show` action:
+
+```ruby
+test "should show article" do
+ article = articles(:one)
+ get :show, id: article.id
+ assert_response :success
+end
+```
+
+Remember from our discussion earlier on fixtures the `articles()` method will give us access to our Articles fixtures.
+
+How about deleting an existing Article?
+
+```ruby
+test "should destroy article" do
+ article = articles(:one)
+ assert_difference('Article.count', -1) do
+ delete :destroy, id: article.id
+ end
+
+ assert_redirected_to articles_path
+end
+```
+
+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))
+end
+```
+
+Notice we're starting to see some duplication in these three tests, they both access the same Article fixture data. We can D.R.Y. this up by using the `setup` and `teardown` methods provided by `ActiveSupport::Callbacks`.
+
+Our test should now look something like this, disregard the other tests we're leaving them out for brevity.
+
+```ruby
+require 'test_helper'
+
+class ArticlesControllerTest < ActionController::TestCase
+ # called before every single test
+ def setup
+ @article = articles(:one)
+ end
+
+ # 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
+ end
+
+ test "should show article" do
+ # Reuse the @article instance variable from setup
+ get :show, id: @article.id
+ assert_response :success
+ end
+
+ test "should destroy article" do
+ assert_difference('Article.count', -1) do
+ delete :destroy, 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))
+ 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.
+
+Testing Routes
+--------------
+
+Like everything else in your Rails application, it is recommended that you test your routes. Below are example tests for the routes of default `show` and `create` action of `Articles` controller above and it should look like:
+
+```ruby
+class ArticleRoutesTest < ActionController::TestCase
+ test "should route to article" do
+ assert_routing '/articles/1', { controller: "articles", action: "show", id: "1" }
+ end
+
+ test "should route to create article" do
+ assert_routing({ method: 'post', path: '/articles' }, { controller: "articles", action: "create" })
+ end
+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
+
+# Running:
+
+..
+
+Finished in 0.069381s, 28.8263 runs/s, 86.4790 assertions/s.
+
+2 runs, 6 assertions, 0 failures, 0 errors, 0 skips
+```
+
+For more information on routing assertions available in Rails, see the API documentation for [`ActionDispatch::Assertions::RoutingAssertions`](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html).
+
+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.
There are two forms of `assert_select`:
@@ -619,7 +819,10 @@ For example, you could verify the contents on the title element in your response
assert_select 'title', "Welcome to Rails Testing Guide"
```
-You can also use nested `assert_select` blocks. In this case the inner `assert_select` runs the assertion on the complete collection of elements selected by the outer `assert_select` block:
+You can also use nested `assert_select` blocks for deeper investigation.
+
+In the following example, the inner `assert_select` for `li.menu_item` runs
+within the collection of elements selected by the outer block:
```ruby
assert_select 'ul.navigation' do
@@ -627,7 +830,9 @@ assert_select 'ul.navigation' do
end
```
-Alternatively the collection of elements selected by the outer `assert_select` may be iterated through so that `assert_select` may be called separately for each element. Suppose for example that the response contains two ordered lists, each with four list elements then the following tests will both pass.
+A collection of selected elements may be iterated through so that `assert_select` may be called separately for each element.
+
+For example if the response contains two ordered lists, each with four nested list elements then the following tests will both pass.
```ruby
assert_select "ol" do |elements|
@@ -641,7 +846,7 @@ assert_select "ol" do
end
```
-The `assert_select` assertion is quite powerful. For more advanced usage, refer to its [documentation](https://github.com/rails/rails-dom-testing/blob/master/lib/rails/dom/testing/assertions/selector_assertions.rb).
+This assertion is quite powerful. For more advanced usage, refer to its [documentation](http://www.rubydoc.info/github/rails/rails-dom-testing).
#### Additional View-Based Assertions
@@ -661,12 +866,45 @@ assert_select_email do
end
```
+Testing helpers
+---------------
+
+In order to test helpers, all you need to do is check that the output of the
+helper method matches what you'd expect. Tests related to the helpers are
+located under the `test/helpers` directory.
+
+A helper test looks like so:
+
+```ruby
+require 'test_helper'
+
+class UserHelperTest < ActionView::TestCase
+end
+```
+
+A helper is just a simple module where you can define methods which are
+available into your views. To test the output of the helper's methods, you just
+have to use a mixin like this:
+
+```ruby
+class UserHelperTest < ActionView::TestCase
+ include UserHelper
+
+ test "should return the user name" do
+ # ...
+ end
+end
+```
+
+Moreover, since the test class extends from `ActionView::TestCase`, you have
+access to Rails' helper methods such as `link_to` or `pluralize`.
+
Integration Testing
-------------------
-Integration tests are used to test the interaction among any number of controllers. They are generally used to test important work flows within your application.
+Integration tests are used to test how various parts of your application interact. They are generally used to test important work flows within your application.
-Unlike Unit and Functional tests, integration tests have to be explicitly created under the 'test/integration' folder within your application. Rails provides a generator to create an integration test skeleton for you.
+For creating Rails integration tests, we use the 'test/integration' directory for your application. Rails provides a generator to create an integration test skeleton for you.
```bash
$ bin/rails generate integration_test user_flows
@@ -686,233 +924,92 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
end
```
-Integration tests inherit from `ActionDispatch::IntegrationTest`. This makes available some additional helpers to use in your integration tests. Also you need to explicitly include the fixtures to be made available to the test.
+Inheriting from `ActionDispatch::IntegrationTest` comes with some advantages. This makes available some additional helpers to use in your integration tests.
### Helpers Available for Integration Tests
-In addition to the standard testing helpers, there are some additional helpers available to integration tests:
+In addition to the standard testing helpers, inheriting `ActionDispatch::IntegrationTest` comes with some additional helpers available when writing integration tests. Let's briefly introduce you to the three categories of helpers you get to choose from.
-| Helper | Purpose |
-| ------------------------------------------------------------------ | ------- |
-| `https?` | Returns `true` if the session is mimicking a secure HTTPS request.|
-| `https!` | Allows you to mimic a secure HTTPS request.|
-| `host!` | Allows you to set the host name to use in the next request.|
-| `redirect?` | Returns `true` if the last request was a redirect.|
-| `follow_redirect!` | Follows a single redirect response.|
-| `request_via_redirect(http_method, path, [parameters], [headers])` | Allows you to make an HTTP request and follow any subsequent redirects.|
-| `post_via_redirect(path, [parameters], [headers])` | Allows you to make an HTTP POST request and follow any subsequent redirects.|
-| `get_via_redirect(path, [parameters], [headers])` | Allows you to make an HTTP GET request and follow any subsequent redirects.|
-| `patch_via_redirect(path, [parameters], [headers])` | Allows you to make an HTTP PATCH request and follow any subsequent redirects.|
-| `put_via_redirect(path, [parameters], [headers])` | Allows you to make an HTTP PUT request and follow any subsequent redirects.|
-| `delete_via_redirect(path, [parameters], [headers])` | Allows you to make an HTTP DELETE request and follow any subsequent redirects.|
-| `open_session` | Opens a new session instance.|
+For dealing with the integration test runner, see [`ActionDispatch::Integration::Runner`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Runner.html).
-### Integration Testing Examples
+When performing requests, you will have [`ActionDispatch::Integration::RequestHelpers`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html) available for your use.
-A simple integration test that exercises multiple controllers:
+If you'd like to modify the session, or state of your integration test you should look for [`ActionDispatch::Integration::Session`](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Session.html) to help.
-```ruby
-require 'test_helper'
+### Implementing an integration test
-class UserFlowsTest < ActionDispatch::IntegrationTest
- test "login and browse site" do
- # login via https
- https!
- get "/login"
- assert_response :success
+Let's add an integration test to our blog application. We'll start with a basic workflow of creating a new blog article, to verify that everything is working properly.
- post_via_redirect "/login", username: users(:david).username, password: users(:david).password
- assert_equal '/welcome', path
- assert_equal 'Welcome david!', flash[:notice]
+We'll start by generating our integration test skeleton:
- https!(false)
- get "/articles/all"
- assert_response :success
- assert assigns(:articles)
- end
-end
+```bash
+$ bin/rails generate integration_test blog_flow
```
-As you can see the integration test involves multiple controllers and exercises the entire stack from database to dispatcher. In addition you can have multiple session instances open simultaneously in a test and extend those instances with assertion methods to create a very powerful testing DSL (domain-specific language) just for your application.
+It should have created a test file placeholder for us, with the output of the previous command you should see:
-Here's an example of multiple sessions and custom DSL in an integration test
+```bash
+ invoke test_unit
+ create test/integration/blog_flow_test.rb
+```
+
+Now let's open that file and write our first assertion:
```ruby
require 'test_helper'
-class UserFlowsTest < ActionDispatch::IntegrationTest
- test "login and browse site" do
- # User david logs in
- david = login(:david)
- # User guest logs in
- guest = login(:guest)
-
- # Both are now available in different sessions
- assert_equal 'Welcome david!', david.flash[:notice]
- assert_equal 'Welcome guest!', guest.flash[:notice]
-
- # User david can browse site
- david.browses_site
- # User guest can browse site as well
- guest.browses_site
-
- # Continue with other assertions
+class BlogFlowTest < ActionDispatch::IntegrationTest
+ test "can see the welcome page" do
+ get "/"
+ assert_select "h1", "Welcome#index"
end
-
- private
-
- module CustomDsl
- def browses_site
- get "/products/all"
- assert_response :success
- assert assigns(:products)
- end
- end
-
- def login(user)
- open_session do |sess|
- sess.extend(CustomDsl)
- u = users(user)
- sess.https!
- sess.post "/login", username: u.username, password: u.password
- assert_equal '/welcome', sess.path
- sess.https!(false)
- end
- end
end
```
-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.
+If you remember from earlier in the "Testing Views" section we covered `assert_select` to query the resulting HTML of a request.
-| Tasks | Description |
-| ----------------------- | ----------- |
-| `rake test` | Runs all tests in the `test` folder. You can also simply run `rake` as Rails will run all the 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` folder and resets the db |
-
-
-A Brief Note About Minitest
------------------------------
-
-Ruby ships with a vast Standard Library for all common use-cases including testing. Since version 1.9, Ruby provides `Minitest`, a framework for testing. All the basic assertions such as `assert_equal` discussed above are actually defined in `Minitest::Assertions`. The classes `ActiveSupport::TestCase`, `ActionController::TestCase`, `ActionMailer::TestCase`, `ActionView::TestCase` and `ActionDispatch::IntegrationTest` - which we have been inheriting in our test classes - include `Minitest::Assertions`, allowing us to use all of the basic assertions in our tests.
+When visit our root path, we should see `welcome/index.html.erb` rendered for the view. So this assertion should pass.
-NOTE: For more information on `Minitest`, refer to [Minitest](http://ruby-doc.org/stdlib-2.1.0/libdoc/minitest/rdoc/MiniTest.html)
-
-Setup and Teardown
-------------------
+#### Creating articles integration
-If you would like to run a block of code before the start of each test and another block of code after the end of each test you have two special callbacks for your rescue. Let's take note of this by looking at an example for our functional test in `Articles` controller:
+How about testing our ability to create a new article in our blog and see the resulting article.
```ruby
-require 'test_helper'
-
-class ArticlesControllerTest < ActionController::TestCase
-
- # called before every single test
- def setup
- @article = articles(:one)
- end
-
- # 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
- end
-
- test "should show article" do
- get :show, id: @article.id
- assert_response :success
- end
-
- test "should destroy article" do
- assert_difference('Article.count', -1) do
- delete :destroy, id: @article.id
- end
-
- assert_redirected_to articles_path
- end
-
+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."}
+ assert_response :redirect
+ follow_redirect!
+ assert_response :success
+ assert_template "articles/show"
+ assert_select "p", "Title:\n can create"
end
```
-Above, the `setup` method is called before each test and so `@article` is available for each of the tests. Rails implements `setup` and `teardown` as `ActiveSupport::Callbacks`. Which essentially means you need not only use `setup` and `teardown` as methods in your tests. You could specify them by using:
+Let's break this test down so we can understand it.
-* a block
-* a method (like in the earlier example)
-* a method name as a symbol
-* a lambda
+We start by calling the `:new` action on our Articles controller. This response should be successful, and we can verify the correct template is rendered including the form partial.
-Let's see the earlier example by specifying `setup` callback by specifying a method name as a symbol:
+After this we make a post request to the `:create` action of our Articles controller:
```ruby
-require 'test_helper'
-
-class ArticlesControllerTest < ActionController::TestCase
-
- # called before every single test
- setup :initialize_article
-
- # called after every single test
- def teardown
- @article = nil
- end
-
- test "should show article" do
- get :show, id: @article.id
- assert_response :success
- end
-
- test "should update article" do
- patch :update, id: @article.id, article: {}
- assert_redirected_to article_path(assigns(:article))
- end
-
- test "should destroy article" do
- assert_difference('Article.count', -1) do
- delete :destroy, id: @article.id
- end
-
- assert_redirected_to articles_path
- end
-
- private
-
- def initialize_article
- @article = articles(:one)
- end
-end
+post "/articles", article: {title: "can create", body: "article successfully."}
+assert_response :redirect
+follow_redirect!
```
-Testing Routes
---------------
+The two lines following the request are to handle the redirect we setup when creating a new article.
-Like everything else in your Rails application, it is recommended that you test your routes. Below are example tests for the routes of default `show` and `create` action of `Articles` controller above and it should look like:
+NOTE: Don't forget to call `follow_redirect!` if you plan to make subsequent requests after a redirect is made.
-```ruby
-class ArticleRoutesTest < ActionController::TestCase
- test "should route to article" do
- assert_routing '/articles/1', { controller: "articles", action: "show", id: "1" }
- end
+Finally we can assert that our response was successful, template was rendered, and our new article is readable on the page.
- test "should route to create article" do
- assert_routing({ method: 'post', path: '/articles' }, { controller: "articles", action: "create" })
- end
-end
-```
+#### Taking it further
+
+We were able to successfully test a very small workflow for visiting our blog and creating a new article. If we wanted to take this further we could add tests for commenting, removing articles, or editting comments. Integration tests are a great place to experiment with all kinds of use-cases for our applications.
Testing Your Mailers
--------------------
@@ -1014,39 +1111,6 @@ class UserControllerTest < ActionController::TestCase
end
```
-Testing helpers
----------------
-
-In order to test helpers, all you need to do is check that the output of the
-helper method matches what you'd expect. Tests related to the helpers are
-located under the `test/helpers` directory.
-
-A helper test looks like so:
-
-```ruby
-require 'test_helper'
-
-class UserHelperTest < ActionView::TestCase
-end
-```
-
-A helper is just a simple module where you can define methods which are
-available into your views. To test the output of the helper's methods, you just
-have to use a mixin like this:
-
-```ruby
-class UserHelperTest < ActionView::TestCase
- include UserHelper
-
- test "should return the user name" do
- # ...
- end
-end
-```
-
-Moreover, since the test class extends from `ActionView::TestCase`, you have
-access to Rails' helper methods such as `link_to` or `pluralize`.
-
Testing Jobs
------------
@@ -1080,17 +1144,7 @@ no jobs have already been executed in the scope of each test.
### Custom Assertions And Testing Jobs Inside Other Components
-Active Job ships with a bunch of custom assertions that can be used to lessen
-the verbosity of tests:
-
-| Assertion | Purpose |
-| -------------------------------------- | ------- |
-| `assert_enqueued_jobs(number)` | Asserts that the number of enqueued jobs matches the given number. |
-| `assert_performed_jobs(number)` | Asserts that the number of performed jobs matches the given number. |
-| `assert_no_enqueued_jobs { ... }` | Asserts that no jobs have been enqueued. |
-| `assert_no_performed_jobs { ... }` | Asserts that no jobs have been performed. |
-| `assert_enqueued_with([args]) { ... }` | Asserts that the job passed in the block has been enqueued with the given arguments. |
-| `assert_performed_with([args]) { ... }`| Asserts that the job passed in the block has been performed with the given arguments. |
+Active Job ships with a bunch of custom assertions that can be used to lessen the verbosity of tests. For a full list of available assertions, see the API documentation for [`ActiveJob::TestHelper`](http://api.rubyonrails.org/classes/ActiveJob/TestHelper.html).
It's a good practice to ensure that your jobs correctly get enqueued or performed
wherever you invoke them (e.g. inside your controllers). This is precisely where
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 4ce61c282d..0b9f59bb46 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
A Guide for Upgrading Ruby on Rails
===================================
@@ -18,9 +20,10 @@ 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 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.
-* Rails 3.2.x is the last branch to support Ruby 1.8.7.
+* Rails 5 requires Ruby 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.
TIP: Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails. Ruby Enterprise Edition has these fixed since the release of 1.8.7-2010.02. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults, so if you want to use 1.9.x, jump straight to 1.9.3 for smooth sailing.
@@ -47,6 +50,9 @@ Overwrite /myapp/config/application.rb? (enter "h" for help) [Ynaqdh]
Don't forget to review the difference, to see if there were any unexpected changes.
+Upgrading from Rails 4.2 to Rails 5.0
+-------------------------------------
+
Upgrading from Rails 4.1 to Rails 4.2
-------------------------------------
@@ -207,12 +213,47 @@ gem 'rails-deprecated_sanitizer'
```
### Rails DOM Testing
+
The [`TagAssertions` module](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/TagAssertions.html) (containing methods such as `assert_tag`), [has been deprecated](https://github.com/rails/rails/blob/6061472b8c310158a2a2e8e9a6b81a1aef6b60fe/actionpack/lib/action_dispatch/testing/assertions/dom.rb) in favor of the `assert_select` methods from the `SelectorAssertions` module, which has been extracted into the [rails-dom-testing gem](https://github.com/rails/rails-dom-testing).
### Masked Authenticity Tokens
+
In order to mitigate SSL attacks, `form_authenticity_token` is now masked so that it varies with each request. Thus, tokens are validated by unmasking and then decrypting. As a result, any strategies for verifying requests from non-rails forms that relied on a static session CSRF token have to take this into account.
+### Action Mailer
+
+Previously, calling a mailer method on a mailer class will result in the
+corresponding instance method being executed directly. With the introduction of
+Active Job and `#deliver_later`, this is no longer true. In Rails 4.2, the
+invocation of the instance methods are deferred until either `deliver_now` or
+`deliver_later` is called. For example:
+
+```ruby
+class Notifier < ActionMailer::Base
+ def notify(user, ...)
+ puts "Called"
+ mail(to: user.email, ...)
+ end
+end
+
+mail = Notifier.notify(user, ...) # Notifier#notify is not yet called at this point
+mail = mail.deliver_now # Prints "Called"
+```
+
+This should not result in any noticeable differences for most applications.
+However, if you need some non-mailer methods to be executed synchronously, and
+you were previously relying on the synchronous proxying behavior, you should
+define them as class methods on the mailer class directly:
+
+```ruby
+class Notifier < ActionMailer::Base
+ def self.broadcast_notifications(users, ...)
+ users.each { |user| Notifier.notify(user, ...) }
+ end
+end
+```
+
Upgrading from Rails 4.0 to Rails 4.1
-------------------------------------
@@ -731,7 +772,7 @@ file (in `config/application.rb`):
```ruby
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
-Bundler.require(:default, Rails.env)
+Bundler.require(*Rails.groups)
```
### vendor/plugins
@@ -950,7 +991,7 @@ The following changes are meant for upgrading your application to the latest
Make the following changes to your `Gemfile`.
```ruby
-gem 'rails', '3.2.18'
+gem 'rails', '3.2.21'
group :assets do
gem 'sass-rails', '~> 3.2.6'
@@ -1075,7 +1116,7 @@ You can help test performance with these additions to your test environment:
```ruby
# Configure static asset server for tests with Cache-Control for performance
-config.serve_static_assets = true
+config.serve_static_files = true
config.static_cache_control = 'public, max-age=3600'
```
diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md
index 7c3fd9f69d..5131f809d7 100644
--- a/guides/source/working_with_javascript_in_rails.md
+++ b/guides/source/working_with_javascript_in_rails.md
@@ -1,3 +1,5 @@
+**DO NOT READ THIS FILE IN GITHUB, GUIDES ARE PUBLISHED IN http://guides.rubyonrails.org.**
+
Working with JavaScript in Rails
================================