aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/4_2_release_notes.md218
-rw-r--r--guides/source/action_controller_overview.md6
-rw-r--r--guides/source/active_job_basics.md102
-rw-r--r--guides/source/active_record_postgresql.md3
-rw-r--r--guides/source/active_record_querying.md6
-rw-r--r--guides/source/active_support_core_extensions.md48
-rw-r--r--guides/source/asset_pipeline.md218
-rw-r--r--guides/source/association_basics.md16
-rw-r--r--guides/source/caching_with_rails.md2
-rw-r--r--guides/source/configuring.md6
-rw-r--r--guides/source/development_dependencies_install.md84
-rw-r--r--guides/source/form_helpers.md34
-rw-r--r--guides/source/getting_started.md2
-rw-r--r--guides/source/i18n.md16
-rw-r--r--guides/source/initialization.md2
-rw-r--r--guides/source/layouts_and_rendering.md3
-rw-r--r--guides/source/maintenance_policy.md6
-rw-r--r--guides/source/routing.md2
-rw-r--r--guides/source/upgrading_ruby_on_rails.md45
19 files changed, 659 insertions, 160 deletions
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index 39655447e3..cb461feff8 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -36,11 +36,11 @@ Major Features
### Active Job, Action Mailer #deliver_later
Active Job is a new framework in Rails 4.2. It is an adapter layer on top of
-queuing systems like Resque, Delayed Job, Sidekiq, and more. You can write your
-jobs to Active Job, and it'll run on all these queues with no changes. (It comes
-pre-configured with an inline runner.)
+queuing systems like [Resque](https://github.com/resque/resque), [Delayed Job](https://github.com/collectiveidea/delayed_job), [Sidekiq](https://github.com/mperham/sidekiq), and more. You can write your
+jobs with the Active Job API, and it'll run on all these queues with no changes
+(it comes pre-configured with an inline runner).
-Building on top of Active Job, Action Mailer now comes with a #deliver_later
+Building on top of Active Job, Action Mailer now comes with a `#deliver_later`
method, which adds your email to be sent as a job to a queue, so it doesn't
bog down the controller or model.
@@ -60,13 +60,23 @@ TODO: add some technical details
### Web Console
-New applications generated from Rails 4.2 now comes with the Web Console gem by
+New applications generated from Rails 4.2 now come with the Web Console gem by
default.
-Web Console is an IRB console available in the browser. In development mode, you
-can go to /console and do your work right there. It will also be made available
-on all exception pages and allows you to jump between the different points in
-the backtrace.
+Web Console is a set of debugging tools for your Rails application. It will add
+an interactive console on every error page, a `console` view helper and a VT100
+compatible terminal.
+
+The interactive console on the error pages lets you execute code where the
+exception originated. It's quite handy to introspect the state that led to the
+error.
+
+The `console` view helper launches an interactive console within the context of
+the view where it is invoked.
+
+Finally, you can launch a VT100 terminal that runs `rails console`. If you need
+to create or modify existing test data, you can do that straight from the
+browser.
### Foreign key support
@@ -95,6 +105,136 @@ and
for a full description.
+Incompatibilities
+-----------------
+
+Previously deprecated functionality has been removed. Please refer to the
+individual components for new deprecations in this release.
+
+The following changes may require immediate action upon upgrade.
+
+### `respond_with` / class-level `respond_to`
+
+`respond_with` and the corresponding class-level `respond_to` have been moved to
+the `responders` gem. To use the following, add `gem 'responders', '~> 2.0'` to
+your Gemfile:
+
+```ruby
+# app/controllers/users_controller.rb
+
+class UsersController < ApplicationController
+ respond_to :html, :json
+
+ def show
+ @user = User.find(params[:id])
+ respond_with @user
+ end
+end
+```
+
+Instance-level `respond_to` is unaffected:
+
+```ruby
+# app/controllers/users_controller.rb
+
+class UsersController < ApplicationController
+ def show
+ @user = User.find(params[:id])
+ respond_to do |format|
+ format.html
+ format.json { render json: @user }
+ end
+ end
+end
+```
+
+### Production logging
+
+The default log level in the `production` environment is now `:debug`. This
+makes it consistent with the other environments, and ensures plenty of
+information is available to diagnose problems.
+
+It can be returned to the previous level, `:info`, in the environment
+configuration:
+
+```ruby
+# config/environments/production.rb
+
+# Decrease the log volume.
+config.log_level = :info
+```
+
+### HTML Sanitizer
+
+The HTML sanitizer has been replaced with a new, more robust, implementation
+built upon Loofah and Nokogiri. The new sanitizer is more secure and its
+sanitization is more powerful and flexible.
+
+With a new sanitization algorithm, the sanitized output will change for certain
+pathological inputs.
+
+If you have particular need for the exact output of the old sanitizer, you can
+add `rails-deprecated_sanitizer` to your Gemfile, and it will automatically
+replace the new implementation. Because it is opt-in, the legacy gem will not
+give deprecation warnings.
+
+`rails-deprecated_sanitizer` will be supported for Rails 4.2 only; it will not
+be maintained for Rails 5.0.
+
+See [the blog post](http://blog.plataformatec.com.br/2014/07/the-new-html-sanitizer-in-rails-4-2/)
+for more detail on the changes in the new sanitizer.
+
+### `assert_select`
+
+`assert_select` is now based on Nokogiri, making it (TODO: betterer).
+
+As a result, some previously-valid selectors are now unsupported. If your
+application is using any of these spellings, you will need to update them:
+
+* Values in attribute selectors may need to be quoted if they contain
+ non-alphanumeric characters.
+
+ ```
+ a[href=/] => a[href="/"]
+ a[href$=/] => a[href$="/"]
+ ```
+
+* DOMs built from HTML source containing invalid HTML with improperly
+ nested elements may differ.
+
+ For example:
+
+ ``` ruby
+ # content: <div><i><p></i></div>
+
+ # before:
+ assert_select('div > i') # => true
+ assert_select('div > p') # => false
+ assert_select('i > p') # => true
+
+ # now:
+ assert_select('div > i') # => true
+ assert_select('div > p') # => true
+ assert_select('i > p') # => false
+ ```
+
+* If the data selected contains entities, the value selected for comparison
+ used to be raw (e.g. `AT&amp;T`), and now is evaluated
+ (e.g. `AT&T`).
+
+ ``` ruby
+ # content: <p>AT&amp;T</p>
+
+ # before:
+ assert_select('p', 'AT&amp;T') # => true
+ assert_select('p', 'AT&T') # => false
+
+ # now:
+ assert_select('p', 'AT&T') # => true
+ assert_select('p', 'AT&amp;T') # => false
+ ```
+
+
Railties
--------
@@ -113,7 +253,7 @@ Please refer to the [Changelog][railties] for detailed changes.
### Notable changes
* Introduced `web-console` in the default application Gemfile.
- ([Pull Request](https://github.com/rails/rails/pull/16532))
+ ([Pull Request](https://github.com/rails/rails/pull/11667))
* Added a `required` option to the model generator for associations.
([Pull Request](https://github.com/rails/rails/pull/16062))
@@ -174,7 +314,8 @@ Please refer to the [Changelog][railties] for detailed changes.
* Introduced an API to register new extensions for `rake notes`.
([Pull Request](https://github.com/rails/rails/pull/14379))
-* Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`.
+* Introduced `Rails.gem_version` as a convenience method to return
+ `Gem::Version.new(Rails.version)`.
([Pull Request](https://github.com/rails/rails/pull/14101))
@@ -245,9 +386,9 @@ Please refer to the [Changelog][action-pack] for detailed changes.
skip_filter => skip_action_callback
```
- If your application is depending on these methods, you should use the
+ If your application currently depends on these methods, you should use the
replacement `*_action` methods instead. These methods will be deprecated in
- the future and eventually removed from Rails.
+ the future and will eventually be removed from Rails.
(Commit [1](https://github.com/rails/rails/commit/6c5f43bab8206747a8591435b2aa0ff7051ad3de),
[2](https://github.com/rails/rails/commit/489a8f2a44dc9cea09154ee1ee2557d1f037c7d4))
@@ -255,8 +396,8 @@ Please refer to the [Changelog][action-pack] for detailed changes.
* Added HTTP method `MKCALENDAR` from RFC-4791
([Pull Request](https://github.com/rails/rails/pull/15121))
-* `*_fragment.action_controller` notifications now include the controller and action name
- in the payload.
+* `*_fragment.action_controller` notifications now include the controller
+ and action name in the payload.
([Pull Request](https://github.com/rails/rails/pull/14137))
* Segments that are passed into URL helpers are now automatically escaped.
@@ -268,6 +409,26 @@ Please refer to the [Changelog][action-pack] for detailed changes.
* Added an option to disable logging of CSRF failures.
([Pull Request](https://github.com/rails/rails/pull/14280))
+* When the Rails server is set to serve static assets, gzip assets will now be
+ served if the client supports it and a pre-generated gzip file (.gz) is on disk.
+ By default the asset pipeline generates `.gz` files for all compressible assets.
+ Serving gzip files minimizes data transfer and speeds up asset requests. Always
+ [use a CDN](http://guides.rubyonrails.org/asset_pipeline.html#cdns) if you are
+ serving assets from your Rails server in production.
+ ([Pull Request](https://github.com/rails/rails/pull/16466))
+
+* The way `assert_select` works has changed; specifically a different library
+ is used to interpret css selectors, build the transient DOM that the
+ selectors are applied against, and to extract the data from that DOM. These
+ changes should only affect edge cases. Examples:
+ * Values in attribute selectors may need to be quoted if they contain
+ non-alphanumeric characters.
+ * DOMs built from HTML source containing invalid HTML with improperly
+ nested elements may differ.
+ * If the data selected contains entities, the value selected for comparison
+ used to be raw (e.g. `AT&amp;T`), and now is evaluated
+ (e.g. `AT&T`).
+
Action View
-------------
@@ -317,7 +478,7 @@ Please refer to the [Changelog][action-mailer] for detailed changes.
### Notable changes
* Introduced `deliver_later` which enqueues a job on the application's queue
- to deliver the mailer asynchronously.
+ to deliver emails asynchronously.
([Pull Request](https://github.com/rails/rails/pull/16485))
* Added the `show_previews` configuration option for enabling mailer previews
@@ -328,9 +489,7 @@ Please refer to the [Changelog][action-mailer] for detailed changes.
Active Record
-------------
-Please refer to the
-[Changelog](https://github.com/rails/rails/blob/4-2-stable/activerecord/CHANGELOG.md)
-for detailed changes.
+Please refer to the [Changelog][active-record] for detailed changes.
### Removals
@@ -346,7 +505,7 @@ for detailed changes.
* Removed unused `:timestamp` type. Transparently alias it to `:datetime`
in all cases. Fixes inconsistencies when column types are sent outside of
- `ActiveRecord`, such as for XML Serialization.
+ `ActiveRecord`, such as for XML serialization.
([Pull Request](https://github.com/rails/rails/pull/15184))
### Deprecations
@@ -441,7 +600,7 @@ for detailed changes.
* `sqlite3:///some/path` now resolves to the absolute system path
`/some/path`. For relative paths, use `sqlite3:some/path` instead.
(Previously, `sqlite3:///some/path` resolved to the relative path
- `some/path`. This behaviour was deprecated on Rails 4.1.)
+ `some/path`. This behaviour was deprecated on Rails 4.1).
([Pull Request](https://github.com/rails/rails/pull/14569))
* Introduced `#validate` as an alias for `#valid?`.
@@ -473,17 +632,19 @@ Please refer to the [Changelog][active-model] for detailed changes.
### Deprecations
-* Deprecated reset_#{attribute} in favor of restore_#{attribute}.
+* Deprecated `reset_#{attribute}` in favor of `restore_#{attribute}`.
([Pull Request](https://github.com/rails/rails/pull/16180))
-* Deprecated ActiveModel::Dirty#reset_changes in favor of #clear_changes_information.
+* Deprecated `ActiveModel::Dirty#reset_changes` in favor of
+ `#clear_changes_information`.
([Pull Request](https://github.com/rails/rails/pull/16180))
### Notable changes
* Introduced the `restore_attributes` method in `ActiveModel::Dirty` to restore
the changed (dirty) attributes to their previous values.
- (Pull Request [1](https://github.com/rails/rails/pull/14861), [2](https://github.com/rails/rails/pull/16180))
+ (Pull Request [1](https://github.com/rails/rails/pull/14861),
+ [2](https://github.com/rails/rails/pull/16180))
* `has_secure_password` no longer disallow blank passwords (i.e. passwords
that contains only spaces) by default.
@@ -527,13 +688,14 @@ Please refer to the [Changelog][active-support] for detailed changes.
### Notable changes
+* Introduced new configuration option `active_support.test_order` for
+ specifying the order test cases are executed. This option currently defaults
+ to `:sorted` but will be changed to `:random` in Rails 5.0.
+ ([Commit](TODO: fill me in))
+
* The `travel_to` test helper now truncates the `usec` component to 0.
([Commit](https://github.com/rails/rails/commit/9f6e82ee4783e491c20f5244a613fdeb4024beb5))
-* `ActiveSupport::TestCase` now randomizes the order that test cases are ran
- by default.
- ([Commit](https://github.com/rails/rails/commit/6ffb29d24e05abbd9ffe3ea974140d6c70221807))
-
* Introduced `Object#itself` as an identity function.
(Commit [1](https://github.com/rails/rails/commit/702ad710b57bef45b081ebf42e6fa70820fdd810),
[2](https://github.com/rails/rails/commit/64d91122222c11ad3918cc8e2e3ebc4b0a03448a))
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 4c04a06dbb..ca1e79d3ce 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -1183,9 +1183,9 @@ First define your app own routes to display the errors page.
* `config/routes.rb`
```ruby
- get '/404', to: 'errors#not_found'
- get '/422', to: 'errors#unprocessable_entity'
- get '/500', to: 'errors#server_error'
+ 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.
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index 58e828d1b5..7b3081993d 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -67,7 +67,7 @@ Here's what a job looks like:
class GuestsCleanupJob < ActiveJob::Base
queue_as :default
- def perform
+ def perform(*args)
# Do something later
end
end
@@ -78,15 +78,15 @@ end
Enqueue a job like so:
```ruby
-MyJob.enqueue record # Enqueue a job to be performed as soon the queueing system is free.
+MyJob.perform_later record # Enqueue a job to be performed as soon the queueing system is free.
```
```ruby
-MyJob.enqueue_at Date.tomorrow.noon, record # Enqueue a job to be performed tomorrow at noon.
+MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record) # Enqueue a job to be performed tomorrow at noon.
```
```ruby
-MyJob.enqueue_in 1.week, record # Enqueue a job to be performed 1 week from now.
+MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1 week from now.
```
That's it!
@@ -105,26 +105,31 @@ Active Job has adapters for the following queueing backends:
* [Delayed Job](https://github.com/collectiveidea/delayed_job)
* [Qu](https://github.com/bkeepers/qu)
* [Que](https://github.com/chanks/que)
-* [QueueClassic](https://github.com/ryandotsmith/queue_classic)
-* [Resque 1.x](https://github.com/resque/resque)
+* [QueueClassic 2.x](https://github.com/ryandotsmith/queue_classic/tree/v2.2.3)
+* [Resque 1.x](https://github.com/resque/resque/tree/1-x-stable)
* [Sidekiq](https://github.com/mperham/sidekiq)
* [Sneakers](https://github.com/jondot/sneakers)
* [Sucker Punch](https://github.com/brandonhilkert/sucker_punch)
#### Backends Features
-| | Async | Queues | Delayed | Priorities | Timeout | Retries |
-|-----------------------|-------|---------|---------|-------------|---------|---------|
-| **Backburner** | Yes | Yes | Yes | Yes | Job | Global |
-| **Delayed Job** | Yes | Yes | Yes | Job | Global | Global |
-| **Que** | Yes | Yes | Yes | Job | No | Job |
-| **Queue Classic** | Yes | Yes | Gem | No | No | No |
-| **Resque** | Yes | Yes | Gem | Queue | Global | ? |
-| **Sidekiq** | Yes | Yes | Yes | Queue | No | Job |
-| **Sneakers** | Yes | Yes | No | Queue | Queue | No |
-| **Sucker Punch** | Yes | Yes | Yes | No | No | No |
-| **Active Job** | Yes | Yes | WIP | No | No | No |
-| **Active Job Inline** | No | Yes | N/A | N/A | N/A | N/A |
+| | Async | Queues | Delayed | Priorities | Timeout | Retries |
+|-----------------------|-------|--------|-----------|------------|---------|---------|
+| **Backburner** | Yes | Yes | Yes | Yes | Job | Global |
+| **Delayed Job** | Yes | Yes | Yes | Job | Global | Global |
+| **Que** | Yes | Yes | Yes | Job | No | Job |
+| **Queue Classic** | Yes | Yes | No* | No | No | No |
+| **Resque** | Yes | Yes | Yes (Gem) | Queue | Global | Yes |
+| **Sidekiq** | Yes | Yes | Yes | Queue | No | Job |
+| **Sneakers** | Yes | Yes | No | Queue | Queue | No |
+| **Sucker Punch** | Yes | Yes | No | No | No | No |
+| **Active Job Inline** | No | Yes | N/A | N/A | N/A | N/A |
+| **Active Job** | Yes | Yes | Yes | No | No | No |
+
+NOTE:
+* Queue Classic does not support Job scheduling. However you can implement this
+yourself or you can use the queue_classic-later gem. See the documentation for
+ActiveJob::QueueAdapters::QueueClassicAdapter.
### Change Backends
@@ -150,8 +155,61 @@ class GuestsCleanupJob < ActiveJob::Base
end
```
-NOTE: Make sure your queueing backend "listens" on your queue name. For some backends
-you need to specify the queues to listen to.
+You can prefix the queue name for all your jobs using
+`config.active_job.queue_name_prefix` in `application.rb`:
+
+```ruby
+# config/application.rb
+module YourApp
+ class Application < Rails::Application
+ config.active_job.queue_name_prefix = Rails.env
+ end
+end
+
+# app/jobs/guests_cleanup.rb
+class GuestsCleanupJob < ActiveJob::Base
+ queue_as :low_priority
+ #....
+end
+
+# Now your job will run on queue production_low_priority on your
+# production environment and on beta_low_priority on your beta
+# environment
+```
+
+If you want more control on what queue a job will be run you can pass a :queue
+option to #set:
+
+```ruby
+MyJob.set(queue: :another_queue).perform_later(record)
+```
+
+To control the queue from the job level you can pass a block to queue_as. The
+block will be executed in the job context (so you can access self.arguments)
+and you must return the queue name:
+
+```ruby
+class ProcessVideoJob < ActiveJob::Base
+ queue_as do
+ video = self.arguments.first
+ if video.owner.premium?
+ :premium_videojobs
+ else
+ :videojobs
+ end
+ end
+
+ def perform(video)
+ # do process video
+ end
+end
+
+ProcessVideoJob.perform_later(Video.last)
+```
+
+
+NOTE: Make sure your queueing backend "listens" on your queue name. For some
+backends you need to specify the queues to listen to.
Callbacks
@@ -176,7 +234,7 @@ class GuestsCleanupJob < ActiveJob::Base
queue_as :default
before_enqueue do |job|
- # do somthing with the job instance
+ # do something with the job instance
end
around_perform do |job, block|
@@ -248,7 +306,7 @@ job:
class GuestsCleanupJob < ActiveJob::Base
queue_as :default
- rescue_from(ActiveRecord:NotFound) do |exception|
+ rescue_from(ActiveRecord::RecordNotFound) do |exception|
# do something with the exception
end
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index a5649e3903..6c94218ef6 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -132,7 +132,8 @@ event = Event.first
event.payload # => {"kind"=>"user_renamed", "change"=>["jack", "john"]}
## Query based on JSON document
-Event.where("payload->'kind' = ?", "user_renamed")
+# The -> operator returns the original JSON type (which might be an object), whereas ->> returns text
+Event.where("payload->>'kind' = ?", "user_renamed")
```
### Range Types
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index cb243c95f5..e1a465c64f 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -340,16 +340,14 @@ The `find_in_batches` method is similar to `find_each`, since both retrieve batc
```ruby
# Give add_invoices an array of 1000 invoices at a time
-Invoice.find_in_batches(include: :invoice_lines) do |invoices|
+Invoice.find_in_batches do |invoices|
export.add_invoices(invoices)
end
```
-NOTE: The `:include` option allows you to name associations that should be loaded alongside with the models.
-
##### Options for `find_in_batches`
-The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`, as well as most of the options allowed by the regular `find` method, except for `:order` and `:limit`, which are reserved for internal use by `find_in_batches`.
+The `find_in_batches` method accepts the same `:batch_size` and `:start` options as `find_each`.
Conditions
----------
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 5ed392d43d..2e1a3ee5dc 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -162,7 +162,7 @@ Active Support provides `duplicable?` to programmatically query an object about
false.duplicable? # => false
```
-By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, and module objects.
+By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, module, and method objects.
WARNING: Any class can disallow duplication by removing `dup` and `clone` or raising exceptions from them. Thus only `rescue` can tell whether a given arbitrary object is duplicable. `duplicable?` depends on the hard-coded list above, but it is much faster than `rescue`. Use it only if you know the hard-coded list is enough in your use case.
@@ -1310,6 +1310,38 @@ In above examples "dear" gets cut first, but then `:separator` prevents it.
NOTE: Defined in `active_support/core_ext/string/filters.rb`.
+### `truncate_words`
+
+The method `truncate_words` returns a copy of its receiver truncated after a given number of words:
+
+```ruby
+"Oh dear! Oh dear! I shall be late!".truncate_words(4)
+# => "Oh dear! Oh dear!..."
+```
+
+Ellipsis can be customized with the `:omission` option:
+
+```ruby
+"Oh dear! Oh dear! I shall be late!".truncate_words(4, omission: '&hellip;')
+# => "Oh dear! Oh dear!&hellip;"
+```
+
+Pass a `:separator` to truncate the string at a natural break:
+
+```ruby
+"Oh dear! Oh dear! I shall be late!".truncate_words(3, separator: '!')
+# => "Oh dear! Oh dear! I shall be late..."
+```
+
+The option `:separator` can be a regexp:
+
+```ruby
+"Oh dear! Oh dear! I shall be late!".truncate_words(4, separator: /\s/)
+# => "Oh dear! Oh dear!..."
+```
+
+NOTE: Defined in `active_support/core_ext/string/filters.rb`.
+
### `inquiry`
The `inquiry` method converts a string into a `StringInquirer` object making equality checks prettier.
@@ -2862,6 +2894,20 @@ Active Record does not accept unknown options when building associations, for ex
NOTE: Defined in `active_support/core_ext/hash/keys.rb`.
+### Working with Values
+
+#### `transform_values` && `transform_values!`
+
+The method `transform_values` accepts a block and returns a hash that has applied the block operations to each of the values in the receiver.
+
+```ruby
+{ nil => nil, 1 => 1, :x => :a }.transform_values { |value| value.to_s.upcase }
+# => {nil=>"", 1=>"1", :x=>"A"}
+```
+There's also the bang variant `transform_values!` that applies the block operations to values in the very receiver.
+
+NOTE: Defined in `active_support/core_text/hash/transform_values.rb`.
+
### Slicing
Ruby has built-in support for taking slices out of strings and arrays. Active Support extends slicing to hashes:
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index e31cefa5bb..c19c8e0bec 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -166,7 +166,8 @@ pipeline, the preferred location for these assets is now the `app/assets`
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. You should use
+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.
@@ -207,9 +208,7 @@ precompiling works.
NOTE: You must have an ExecJS supported runtime in order to use CoffeeScript.
If you are using Mac OS X or Windows, you have a JavaScript runtime installed in
-your operating system. Check
-[ExecJS](https://github.com/sstephenson/execjs#readme) documentation to know all
-supported JavaScript runtimes.
+your operating system. Check [ExecJS](https://github.com/sstephenson/execjs#readme) documentation to know all supported JavaScript runtimes.
You can also disable generation of controller specific asset files by adding the
following to your `config/application.rb` configuration:
@@ -736,10 +735,10 @@ Rails.application.config.assets.precompile << Proc.new do |path|
full_path = Rails.application.assets.resolve(path).to_path
app_assets_path = Rails.root.join('app', 'assets').to_path
if full_path.starts_with? app_assets_path
- puts "including asset: " + full_path
+ logger.info "including asset: " + full_path
true
else
- puts "excluding asset: " + full_path
+ logger.info "excluding asset: " + full_path
false
end
else
@@ -916,24 +915,207 @@ end
### CDNs
-If your assets are being served by a CDN, ensure they don't stick around in your
-cache forever. This can cause problems. If you use
-`config.action_controller.perform_caching = true`, Rack::Cache will use
-`Rails.cache` to store assets. This can cause your cache to fill up quickly.
+CDN stands for [Content Delivery
+Network](http://en.wikipedia.org/wiki/Content_delivery_network), they are
+primarily designed to cache assets all over the world so that when a browser
+requests the asset, a cached copy will be geographically close to that browser.
+If you are serving assets directly from your Rails server in production, the
+best practice is to use a CDN in front of your application.
+
+A common pattern for using a CDN is to set your production application as the
+"origin" server. This means when a browser requests an asset from the CDN and
+there is a cache miss, it will grab the file from your server on the fly and
+then cache it. For example if you are running a Rails application on
+`example.com` and have a CDN configured at `mycdnsubdomain.fictional-cdn.com`,
+then when a request is made to `mycdnsubdomain.fictional-
+cdn.com/assets/smile.png`, the CDN will query your server once at
+`example.com/assets/smile.png` and cache the request. The next request to the
+CDN that comes in to the same URL will hit the cached copy. When the CDN can
+serve an asset directly the request never touches your Rails server. Since the
+assets from a CDN are geographically closer to the browser, the request is
+faster, and since your server doesn't need to spend time serving assets, it can
+focus on serving application code as fast as possible.
+
+#### Set up a CDN to Serve Static Assets
+
+To set up your CDN you have to have your application running in production on
+the internet at a publically available URL, for example `example.com`. Next
+you'll need to sign up for a CDN service from a cloud hosting provider. When you
+do this you need to configure the "origin" of the CDN to point back at your
+website `example.com`, check your provider for documentation on configuring the
+origin server.
+
+The CDN you provisioned should give you a custom subdomain for your application
+such as `mycdnsubdomain.fictional-cdn.com` (note fictional-cdn.com is not a
+valid CDN provider at the time of this writing). Now that you have configured
+your CDN server, you need to tell browsers to use your CDN to grab assets
+instead of your Rails server directly. You can do this by configuring Rails to
+set your CDN as the asset host instead of using a relative path. To set your
+asset host in Rails, you need to set `config.action_controller.asset_host` in
+`config/production.rb`:
-Every cache is different, so evaluate how your CDN handles caching and make sure
-that it plays nicely with the pipeline. You may find quirks related to your
-specific set up, you may not. The defaults NGINX uses, for example, should give
-you no problems when used as an HTTP cache.
+```ruby
+config.action_controller.asset_host = 'mycdnsubdomain.fictional-cdn.com'
+```
+
+NOTE: You only need to provide the "host", this is the subdomain and root
+domain, you do not need to specify a protocol or "scheme" such as `http://` or
+`https://`. When a web page is requested, the protocol in the link to your asset
+that is generated will match how the webpage is accessed by default.
+
+You can also set this value through an [environment
+variable](http://en.wikipedia.org/wiki/Environment_variable) to make running a
+staging copy of your site easier:
+
+```
+config.action_controller.asset_host = ENV['CDN_HOST']
+```
+
+
+
+Note: You would need to set `CDN_HOST` on your server to `mycdnsubdomain
+.fictional-cdn.com` for this to work.
+
+Once you have configured your server and your CDN when you serve a webpage that
+has an asset:
+
+```erb
+<%= asset_path('smile.png') %>
+```
+
+Instead of returning a path such as `/assets/smile.png` (digests are left out
+for readability). The URL generated will have the full path to your CDN.
-If you want to serve only some assets from your CDN, you can use custom
-`:host` option of `asset_url` helper, which overwrites value set in
+```
+http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
+```
+
+If the CDN has a copy of `smile.png` it will serve it to the browser and your
+server doesn't even know it was requested. If the CDN does not have a copy it
+will try to find it a the "origin" `example.com/assets/smile.png` and then store
+it for future use.
+
+If you want to serve only some assets from your CDN, you can use custom `:host`
+option your asset helper, which overwrites value set in
`config.action_controller.asset_host`.
-```ruby
-asset_url 'image.png', :host => 'http://cdn.example.com'
+```erb
+<%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>
```
+#### Customize CDN Caching Behavior
+
+A CDN works by caching content. If the CDN has stale or bad content, then it is
+hurting rather than helping your application. The purpose of this section is to
+describe general caching behavior of most CDNs, your specific provider may
+behave slightly differently.
+
+##### CDN Request Caching
+
+While a CDN is described as being good for caching assets, in reality caches the
+entire request. This includes the body of the asset as well as any headers. The
+most important one being `Cache-Control` which tells the CDN (and web browsers)
+how to cache contents. This means that if someone requests an asset that does
+not exist `/assets/i-dont-exist.png` and your Rails application returns a 404,
+then your CDN will likely cache the 404 page if a valid `Cache-Control` header
+is present.
+
+##### CDN Header Debugging
+
+One way to check the headers are cached properly in your CDN is by using [curl](
+http://explainshell.com/explain?cmd=curl+-I+http%3A%2F%2Fwww.example.com). You
+can request the headers from both your server and your CDN to verify they are
+the same:
+
+```
+$ curl -I http://www.example/assets/application-
+d0e099e021c95eb0de3615fd1d8c4d83.css
+HTTP/1.1 200 OK
+Server: Cowboy
+Date: Sun, 24 Aug 2014 20:27:50 GMT
+Connection: keep-alive
+Last-Modified: Thu, 08 May 2014 01:24:14 GMT
+Content-Type: text/css
+Cache-Control: public, max-age=2592000
+Content-Length: 126560
+Via: 1.1 vegur
+```
+
+Versus the CDN copy.
+
+```
+$ curl -I http://mycdnsubdomain.fictional-cdn.com/application-
+d0e099e021c95eb0de3615fd1d8c4d83.css
+HTTP/1.1 200 OK Server: Cowboy Last-
+Modified: Thu, 08 May 2014 01:24:14 GMT Content-Type: text/css
+Cache-Control:
+public, max-age=2592000
+Via: 1.1 vegur
+Content-Length: 126560
+Accept-Ranges:
+bytes
+Date: Sun, 24 Aug 2014 20:28:45 GMT
+Via: 1.1 varnish
+Age: 885814
+Connection: keep-alive
+X-Served-By: cache-dfw1828-DFW
+X-Cache: HIT
+X-Cache-Hits:
+68
+X-Timer: S1408912125.211638212,VS0,VE0
+```
+
+Check your CDN documentation for any additional information they may provide
+such as `X-Cache` or for any additional headers they may add.
+
+##### CDNs and the Cache-Control Header
+
+The [cache control
+header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) is a W3C
+specification that describes how a request can be cached. When no CDN is used, a
+browser will use this information to cache contents. This is very helpful for
+assets that are not modified so that a browser does not need to re-download a
+website's CSS or javascript on every request. Generally we want our Rails server
+to tell our CDN (and browser) that the asset is "public", that means any cache
+can store the request. Also we commonly want to set `max-age` which is how long
+the cache will store the object before invalidating the cache. The `max-age`
+value is set to seconds with a maximum possible value of `31536000` which is one
+year. You can do this in your rails application by setting
+
+```
+config.static_cache_control = "public, max-age=31536000"
+```
+
+Now when your application serves an asset in production, the CDN will store the
+asset for up to a year. Since most CDNs also cache headers of the request, this
+`Cache-Control` will be passed along to all future browsers seeking this asset,
+the browser then knows that it can store this asset for a very long time before
+needing to re-request it.
+
+##### CDNs and URL based Cache Invalidation
+
+Most CDNs will cache contents of an asset based on the complete URL. This means
+that a request to
+
+```
+http://mycdnsubdomain.fictional-cdn.com/assets/smile-123.png
+```
+
+Will be a completely different cache from
+
+```
+http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
+```
+
+If you want to set far future `max-age` in your `Cache-Control` (and you do),
+then make sure when you change your assets that your cache is invalidated. For
+example when changing the smiley face in an image from yellow to blue, you want
+all visitors of your site to get the new blue face. When using a CDN with the
+Rails asset pipeline `config.assets.digest` is set to true by default so that
+each asset will have a different file name when it is changed. This way you
+don't have to ever manually invalidate any items in your cache. By using a
+different unique asset name instead, your users get the latest asset.
+
Customizing the Pipeline
------------------------
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index daf4113b66..c9e0fcd939 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -1321,9 +1321,9 @@ When you declare a `has_many` association, the declaring class automatically gai
* `collection<<(object, ...)`
* `collection.delete(object, ...)`
* `collection.destroy(object, ...)`
-* `collection=objects`
+* `collection=(objects)`
* `collection_singular_ids`
-* `collection_singular_ids=ids`
+* `collection_singular_ids=(ids)`
* `collection.clear`
* `collection.empty?`
* `collection.size`
@@ -1399,7 +1399,7 @@ The `collection.destroy` method removes one or more objects from the collection
WARNING: Objects will _always_ be removed from the database, ignoring the `:dependent` option.
-##### `collection=objects`
+##### `collection=(objects)`
The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
@@ -1411,7 +1411,7 @@ The `collection_singular_ids` method returns an array of the ids of the objects
@order_ids = @customer.order_ids
```
-##### `collection_singular_ids=ids`
+##### `collection_singular_ids=(ids)`
The `collection_singular_ids=` method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
@@ -1810,9 +1810,9 @@ When you declare a `has_and_belongs_to_many` association, the declaring class au
* `collection<<(object, ...)`
* `collection.delete(object, ...)`
* `collection.destroy(object, ...)`
-* `collection=objects`
+* `collection=(objects)`
* `collection_singular_ids`
-* `collection_singular_ids=ids`
+* `collection_singular_ids=(ids)`
* `collection.clear`
* `collection.empty?`
* `collection.size`
@@ -1895,7 +1895,7 @@ The `collection.destroy` method removes one or more objects from the collection
@part.assemblies.destroy(@assembly1)
```
-##### `collection=objects`
+##### `collection=(objects)`
The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate.
@@ -1907,7 +1907,7 @@ The `collection_singular_ids` method returns an array of the ids of the objects
@assembly_ids = @part.assembly_ids
```
-##### `collection_singular_ids=ids`
+##### `collection_singular_ids=(ids)`
The `collection_singular_ids=` method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index d0f3a596fe..cbcd053950 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -363,7 +363,7 @@ class ProductsController < ApplicationController
end
```
-If you don't have any special response processing and are using the default rendering mechanism (i.e. you're not using respond_to or calling render yourself) then you've got an easy helper in fresh_when:
+If you don't have any special response processing and are using the default rendering mechanism (i.e. you're not using `respond_to` or calling render yourself) then you've got an easy helper in `fresh_when`:
```ruby
class ProductsController < ApplicationController
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 38f9609287..667281d1aa 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -112,7 +112,7 @@ numbers. New applications filter out passwords by adding the following `config.f
* `config.log_tags` accepts a list of methods that the `request` object responds to. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications.
-* `config.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to an instance of `ActiveSupport::Logger`, with auto flushing off in production mode.
+* `config.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to an instance of `ActiveSupport::Logger`.
* `config.middleware` allows you to configure the application's middleware. This is covered in depth in the [Configuring Middleware](#configuring-middleware) section below.
@@ -137,7 +137,7 @@ numbers. New applications filter out passwords by adding the following `config.f
* `config.assets.enabled` a flag that controls whether the asset
pipeline is enabled. It is set to true by default.
-* `config.assets.raise_runtime_errors`* Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`.
+* `config.assets.raise_runtime_errors` Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`.
* `config.assets.compress` a flag that enables the compression of compiled assets. It is explicitly set to true in `config/environments/production.rb`.
@@ -471,6 +471,8 @@ There are a few configuration options available in Active Support:
* `config.active_support.bare` enables or disables the loading of `active_support/all` when booting Rails. Defaults to `nil`, which means `active_support/all` is loaded.
+* `config.active_support.test_order` sets the order that test cases are executed. Possible values are `:sorted` and `:random`. Currently defaults to `:sorted`. In Rails 5.0, the default will be changed to `:random` instead.
+
* `config.active_support.escape_html_entities_in_json` enables or disables the escaping of HTML entities in JSON serialization. Defaults to `false`.
* `config.active_support.use_standard_json_time_format` enables or disables serializing dates to ISO 8601 format. Defaults to `true`.
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 54b4230e16..3d9ec578ae 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -45,36 +45,14 @@ $ cd rails
The test suite must pass with any submitted code. No matter whether you are writing a new patch, or evaluating someone else's, you need to be able to run the tests.
-Install first libxml2 and libxslt together with their development files for Nokogiri. In Ubuntu that's
+Install first SQLite3 and its development files for the `sqlite3` gem. Mac OS X
+users are done with:
```bash
-$ sudo apt-get install libxml2 libxml2-dev libxslt1-dev
+$ brew install sqlite3
```
-If you are on Fedora or CentOS, you can run
-
-```bash
-$ sudo yum install libxml2 libxml2-devel libxslt libxslt-devel
-```
-
-If you are running Arch Linux, you're done with:
-
-```bash
-$ sudo pacman -S libxml2 libxslt
-```
-
-On FreeBSD, you just have to run:
-
-```bash
-# pkg_add -r libxml2 libxslt
-```
-
-Alternatively, you can install the `textproc/libxml2` and `textproc/libxslt`
-ports.
-
-If you have any problems with these libraries, you can install them manually by compiling the source code. Just follow the instructions at the [Red Hat/CentOS section of the Nokogiri tutorials](http://nokogiri.org/tutorials/installing_nokogiri.html#red_hat__centos) .
-
-Also, SQLite3 and its development files for the `sqlite3-ruby` gem - in Ubuntu you're done with just
+In Ubuntu you're done with just:
```bash
$ sudo apt-get install sqlite3 libsqlite3-dev
@@ -95,7 +73,7 @@ $ sudo pacman -S sqlite
For FreeBSD users, you're done with:
```bash
-# pkg_add -r sqlite3
+# pkg install sqlite3
```
Or compile the `databases/sqlite3` port.
@@ -117,7 +95,7 @@ This command will install all dependencies except the MySQL and PostgreSQL Ruby
NOTE: If you would like to run the tests that use memcached, you need to ensure that you have it installed and running.
-You can use [Homebrew](http://brew.sh/) to install memcached on OSX:
+You can use [Homebrew](http://brew.sh/) to install memcached on OS X:
```bash
$ brew install memcached
@@ -135,6 +113,20 @@ Or use yum on Fedora or CentOS:
$ sudo yum install memcached
```
+If you are running on Arch Linux:
+
+```bash
+$ sudo pacman -S memcached
+```
+
+For FreeBSD users, you're done with:
+
+```bash
+# pkg install memcached
+```
+
+Alternatively, you can compile the `databases/memcached` port.
+
With the dependencies now installed, you can run the test suite with:
```bash
@@ -181,7 +173,19 @@ The Active Record test suite requires a custom config file: `activerecord/test/c
#### MySQL and PostgreSQL
-To be able to run the suite for MySQL and PostgreSQL we need their gems. Install first the servers, their client libraries, and their development files. In Ubuntu just run
+To be able to run the suite for MySQL and PostgreSQL we need their gems. Install
+first the servers, their client libraries, and their development files.
+
+On OS X, you can run:
+
+```bash
+$ brew install mysql
+$ brew install postgresql
+```
+
+Follow the instructions given by Homebrew to start these.
+
+In Ubuntu just run:
```bash
$ sudo apt-get install mysql-server libmysqlclient15-dev
@@ -206,17 +210,9 @@ $ sudo pacman -S postgresql postgresql-libs
FreeBSD users will have to run the following:
```bash
-# pkg_add -r mysql56-client mysql56-server
-# pkg_add -r postgresql92-client postgresql92-server
-```
-
-You can use [Homebrew](http://brew.sh/) to install MySQL and PostgreSQL on OSX:
-
-```bash
-$ brew install mysql
-$ brew install postgresql
+# pkg install mysql56-client mysql56-server
+# pkg install postgresql93-client postgresql93-server
```
-Follow instructions given by [Homebrew](http://brew.sh/) to start these.
Or install them through ports (they are located under the `databases` folder).
If you run into troubles during the installation of MySQL, please see
@@ -252,18 +248,20 @@ $ cd activerecord
$ bundle exec rake db:mysql:build
```
-PostgreSQL's authentication works differently. A simple way to set up the development environment for example is to run with your development account
-This is not needed when installed via [Homebrew](http://brew.sh).
+PostgreSQL's authentication works differently. To setup the development environment
+with your development account, on Linux or BSD, you just have to run:
```bash
$ sudo -u postgres createuser --superuser $USER
```
-And for OS X (when installed via [Homebrew](http://brew.sh))
+
+and for OS X:
+
```bash
$ createuser --superuser $USER
```
-and then create the test databases with
+Then you need to create the test databases with
```bash
$ cd activerecord
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index 048eb9a6e3..9ced77dfd7 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -276,7 +276,7 @@ The name passed to `form_for` controls the key used in `params` to access the fo
The helper methods called on the form builder are identical to the model object helpers except that it is not necessary to specify which object is being edited since this is already managed by the form builder.
-You can create a similar binding without actually creating `<form>` tags with the `fields_for` helper. This is useful for editing additional model objects with the same form. For example if you had a `Person` model with an associated `ContactDetail` model you could create a form for creating both like so:
+You can create a similar binding without actually creating `<form>` tags with the `fields_for` helper. This is useful for editing additional model objects with the same form. For example, if you had a `Person` model with an associated `ContactDetail` model, you could create a form for creating both like so:
```erb
<%= form_for @person, url: {action: "create"} do |person_form| %>
@@ -534,7 +534,7 @@ Both of these families of helpers will create a series of select boxes for the d
### Barebones Helpers
-The `select_*` family of helpers take as their first argument an instance of `Date`, `Time` or `DateTime` that is used as the currently selected value. You may omit this parameter, in which case the current date is used. For example
+The `select_*` family of helpers take as their first argument an instance of `Date`, `Time` or `DateTime` that is used as the currently selected value. You may omit this parameter, in which case the current date is used. For example:
```erb
<%= select_date Date.today, prefix: :start_date %>
@@ -548,7 +548,7 @@ outputs (with actual option values omitted for brevity)
<select id="start_date_day" name="start_date[day]"> ... </select>
```
-The above inputs would result in `params[:start_date]` being a hash with keys `:year`, `:month`, `:day`. To get an actual `Date`, `Time` or `DateTime` object you would have to extract these values and pass them to the appropriate constructor, for example
+The above inputs would result in `params[:start_date]` being a hash with keys `:year`, `:month`, `:day`. To get an actual `Date`, `Time` or `DateTime` object you would have to extract these values and pass them to the appropriate constructor, for example:
```ruby
Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i)
@@ -591,9 +591,9 @@ NOTE: In many cases the built-in date pickers are clumsy as they do not aid the
### Individual Components
-Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component `select_year`, `select_month`, `select_day`, `select_hour`, `select_minute`, `select_second`. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for `select_year`, "month" for `select_month` etc.) although this can be overridden with the `:field_name` option. The `:prefix` option works in the same way that it does for `select_date` and `select_time` and has the same default value.
+Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component `select_year`, `select_month`, `select_day`, `select_hour`, `select_minute`, `select_second`. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example, "year" for `select_year`, "month" for `select_month` etc.) although this can be overridden with the `:field_name` option. The `:prefix` option works in the same way that it does for `select_date` and `select_time` and has the same default value.
-The first parameter specifies which value should be selected and can either be an instance of a `Date`, `Time` or `DateTime`, in which case the relevant component will be extracted, or a numerical value. For example
+The first parameter specifies which value should be selected and can either be an instance of a `Date`, `Time` or `DateTime`, in which case the relevant component will be extracted, or a numerical value. For example:
```erb
<%= select_year(2009) %>
@@ -623,7 +623,7 @@ Rails provides the usual pair of helpers: the barebones `file_field_tag` and the
### What Gets Uploaded
-The object in the `params` hash is an instance of a subclass of `IO`. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of `File` backed by a temporary file. In both cases the object will have an `original_filename` attribute containing the name the file had on the user's computer and a `content_type` attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in `#{Rails.root}/public/uploads` under the same name as the original file (assuming the form was the one in the previous example).
+The object in the `params` hash is an instance of a subclass of `IO`. Depending on the size of the uploaded file it may in fact be a `StringIO` or an instance of `File` backed by a temporary file. In both cases the object will have an `original_filename` attribute containing the name the file had on the user's computer and a `content_type` attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in `#{Rails.root}/public/uploads` under the same name as the original file (assuming the form was the one in the previous example).
```ruby
def upload
@@ -645,7 +645,7 @@ Unlike other forms making an asynchronous file upload form is not as simple as p
Customizing Form Builders
-------------------------
-As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of `FormBuilder` (or a subclass thereof). Form builders encapsulate the notion of displaying form elements for a single object. While you can of course write helpers for your forms in the usual way, you can also subclass `FormBuilder` and add the helpers there. For example
+As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of `FormBuilder` (or a subclass thereof). Form builders encapsulate the notion of displaying form elements for a single object. While you can of course write helpers for your forms in the usual way, you can also subclass `FormBuilder` and add the helpers there. For example:
```erb
<%= form_for @person do |f| %>
@@ -684,12 +684,12 @@ If `f` is an instance of `FormBuilder` then this will render the `form` partial,
Understanding Parameter Naming Conventions
------------------------------------------
-As you've seen in the previous sections, values from forms can be at the top level of the `params` hash or nested in another hash. For example in a standard `create`
+As you've seen in the previous sections, values from forms can be at the top level of the `params` hash or nested in another hash. For example, in a standard `create`
action for a Person model, `params[:person]` would usually be a hash of all the attributes for the person to create. The `params` hash can also contain arrays, arrays of hashes and so on.
Fundamentally HTML forms don't know about any sort of structured data, all they generate is name-value pairs, where pairs are just plain strings. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.
-TIP: You may find you can try out examples in this section faster by using the console to directly invoke Racks' parameter parser. For example,
+TIP: You may find you can try out examples in this section faster by using the console to directly invoke Rack's parameter parser. For example,
```ruby
Rack::Utils.parse_query "name=fred&phone=0123456789"
@@ -698,7 +698,7 @@ Rack::Utils.parse_query "name=fred&phone=0123456789"
### Basic Structures
-The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in `params`. For example if a form contains
+The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in `params`. For example, if a form contains:
```html
<input id="person_name" name="person[name]" type="text" value="Henry"/>
@@ -712,7 +712,7 @@ the `params` hash will contain
and `params[:person][:name]` will retrieve the submitted value in the controller.
-Hashes can be nested as many levels as required, for example
+Hashes can be nested as many levels as required, for example:
```html
<input id="person_address_city" name="person[address][city]" type="text" value="New York"/>
@@ -724,7 +724,7 @@ will result in the `params` hash being
{'person' => {'address' => {'city' => 'New York'}}}
```
-Normally Rails ignores duplicate parameter names. If the parameter name contains an empty set of square brackets [] then they will be accumulated in an array. If you wanted people to be able to input multiple phone numbers, you could place this in the form:
+Normally Rails ignores duplicate parameter names. If the parameter name contains an empty set of square brackets `[]` then they will be accumulated in an array. If you wanted users to be able to input multiple phone numbers, you could place this in the form:
```html
<input name="person[phone_number][]" type="text"/>
@@ -732,11 +732,11 @@ Normally Rails ignores duplicate parameter names. If the parameter name contains
<input name="person[phone_number][]" type="text"/>
```
-This would result in `params[:person][:phone_number]` being an array.
+This would result in `params[:person][:phone_number]` being an array containing the inputted phone numbers.
### Combining Them
-We can mix and match these two concepts. For example, one element of a hash might be an array as in the previous example, or you can have an array of hashes. For example a form might let you create any number of addresses by repeating the following form fragment
+We can mix and match these two concepts. One element of a hash might be an array as in the previous example, or you can have an array of hashes. For example, a form might let you create any number of addresses by repeating the following form fragment
```html
<input name="addresses[][line1]" type="text"/>
@@ -746,7 +746,7 @@ We can mix and match these two concepts. For example, one element of a hash migh
This would result in `params[:addresses]` being an array of hashes with keys `line1`, `line2` and `city`. Rails decides to start accumulating values in a new hash whenever it encounters an input name that already exists in the current hash.
-There's a restriction, however, while hashes can be nested arbitrarily, only one level of "arrayness" is allowed. Arrays can be usually replaced by hashes, for example instead of having an array of model objects one can have a hash of model objects keyed by their id, an array index or some other parameter.
+There's a restriction, however, while hashes can be nested arbitrarily, only one level of "arrayness" is allowed. Arrays can usually be replaced by hashes; for example, instead of having an array of model objects, one can have a hash of model objects keyed by their id, an array index or some other parameter.
WARNING: Array parameters do not play well with the `check_box` helper. According to the HTML specification unchecked checkboxes submit no value. However it is often convenient for a checkbox to always submit a value. The `check_box` helper fakes this by creating an auxiliary hidden input with the same name. If the checkbox is unchecked only the hidden input is submitted and if it is checked then both are submitted but the value submitted by the checkbox takes precedence. When working with array parameters this duplicate submission will confuse Rails since duplicate input names are how it decides when to start a new array element. It is preferable to either use `check_box_tag` or to use hashes instead of arrays.
@@ -856,7 +856,7 @@ Or if you don't want to render an `authenticity_token` field:
Building Complex Forms
----------------------
-Many apps grow beyond simple forms editing a single object. For example when creating a `Person` you might want to allow the user to (on the same form) create multiple address records (home, work, etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary.
+Many apps grow beyond simple forms editing a single object. For example, when creating a `Person` you might want to allow the user to (on the same form) create multiple address records (home, work, etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary.
### Configuring the Model
@@ -908,7 +908,7 @@ end
```
The `fields_for` yields a form builder. The parameters' name will be what
-`accepts_nested_attributes_for` expects. For example when creating a user with
+`accepts_nested_attributes_for` expects. For example, when creating a user with
2 addresses, the submitted parameters would look like:
```ruby
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 964bb30856..1769448531 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1627,7 +1627,7 @@ controller. Again, we'll use the same generator we used before:
$ bin/rails generate controller Comments
```
-This creates six files and one empty directory:
+This creates five files and one empty directory:
| File/Directory | Purpose |
| -------------------------------------------- | ---------------------------------------- |
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 1023598aa4..0761d5b39c 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -676,6 +676,22 @@ en:
<div><%= t('title.html') %></div>
```
+Interpolation escapes as needed though. For example, given:
+
+```yaml
+en:
+ welcome_html: "<b>Welcome %{username}!</b>"
+```
+
+you can safely pass the username as set by the user:
+
+```erb
+<%# This is safe, it is going to be escaped if needed. %>
+<%= t('welcome_html', username: @current_user.username %>
+```
+
+Safe strings on the other hand are interpolated verbatim.
+
NOTE: Automatic conversion to HTML safe translate text is only available from the `translate` view helper method.
![i18n demo html safe](images/i18n/demo_html_safe.png)
diff --git a/guides/source/initialization.md b/guides/source/initialization.md
index b81b048c35..53bf3039fa 100644
--- a/guides/source/initialization.md
+++ b/guides/source/initialization.md
@@ -111,7 +111,6 @@ A standard Rails application depends on several gems, specifically:
* i18n
* mail
* mime-types
-* polyglot
* rack
* rack-cache
* rack-mount
@@ -121,7 +120,6 @@ A standard Rails application depends on several gems, specifically:
* rake
* sqlite3
* thor
-* treetop
* tzinfo
### `rails/commands.rb`
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index 60571750a1..ac254fc000 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -248,7 +248,8 @@ service requests that are expecting something other than proper HTML.
NOTE: By default, if you use the `:plain` option, the text is rendered without
using the current layout. If you want Rails to put the text into the current
-layout, you need to add the `layout: true` option.
+layout, you need to add the `layout: true` option and use the `.txt.erb`
+extension for the layout file.
#### Rendering HTML
diff --git a/guides/source/maintenance_policy.md b/guides/source/maintenance_policy.md
index 6f8584b3b7..7f084dd54c 100644
--- a/guides/source/maintenance_policy.md
+++ b/guides/source/maintenance_policy.md
@@ -39,7 +39,7 @@ Only the latest release series will receive bug fixes. When enough bugs are
fixed and its deemed worthy to release a new gem, this is the branch it happens
from.
-**Currently included series:** `4.1.Z`, `4.0.Z`.
+**Currently included series:** `4.2.Z`, `4.1.Z`.
Security Issues
---------------
@@ -54,7 +54,7 @@ be built from 1.2.2, and then added to the end of 1-2-stable. This means that
security releases are easy to upgrade to if you're running the latest version
of Rails.
-**Currently included series:** `4.1.Z`, `4.0.Z`.
+**Currently included series:** `4.2.Z`, `4.1.Z`.
Severe Security Issues
----------------------
@@ -63,7 +63,7 @@ For severe security issues we will provide new versions as above, and also the
last major release series will receive patches and new versions. The
classification of the security issue is judged by the core team.
-**Currently included series:** `4.1.Z`, `4.0.Z`, `3.2.Z`.
+**Currently included series:** `4.2.Z`, `4.1.Z`, `3.2.Z`.
Unsupported Release Series
--------------------------
diff --git a/guides/source/routing.md b/guides/source/routing.md
index af8c1bbcc4..b1a287f53a 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -756,7 +756,7 @@ get '*a/foo/*b', to: 'test#index'
would match `zoo/woo/foo/bar/baz` with `params[:a]` equals `'zoo/woo'`, and `params[:b]` equals `'bar/baz'`.
-NOTE: By requesting `'/foo/bar.json'`, your `params[:pages]` will be equals to `'foo/bar'` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this:
+NOTE: By requesting `'/foo/bar.json'`, your `params[:pages]` will be equal to `'foo/bar'` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this:
```ruby
get '*pages', to: 'pages#show', format: false
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 407445f449..2c6797d1fd 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -8,7 +8,7 @@ This guide provides steps to be followed when you upgrade your applications to a
General Advice
--------------
-Before attempting to upgrade an existing application, you should be sure you have a good reason to upgrade. You need to balance out several factors: the need for new features, the increasing difficulty of finding support for old code, and your available time and skills, to name a few.
+Before attempting to upgrade an existing application, you should be sure you have a good reason to upgrade. You need to balance several factors: the need for new features, the increasing difficulty of finding support for old code, and your available time and skills, to name a few.
### Test Coverage
@@ -55,7 +55,11 @@ a [pull request](https://github.com/rails/rails/edit/master/guides/source/upgrad
### Web Console
-TODO: setup instructions for web console on existing apps.
+First, add `gem 'web-console', '~> 2.0.0.beta3'` to the `:development` group in your Gemfile and run `bundle install` (it won't have been included when you upgraded Rails). Once it's been installed, you can simply drop a reference to the console helper (i.e., `<%= console %>`) into any view you want to enable it for. A console will also be provided on any error page you view in your development environment.
+
+Additionally, you can tell Rails to automatically mount a VT100-compatible console on a predetermined path by setting `config.web_console.automount = true` in your `config/environments/development.rb`. You can specify the path by setting `config.web_console.default_mount_path` (note that this defaults to `/console`).
+
+TODO: Update `web-console` version to release version.
### Responders
@@ -63,7 +67,40 @@ TODO: mention https://github.com/rails/rails/pull/16526
### Error handling in transaction callbacks
-TODO: mention https://github.com/rails/rails/pull/16537
+Currently, Active Record suppresses errors raised
+within `after_rollback` or `after_commit` callbacks and only prints them to
+the logs. In the next version, these errors will no longer be suppressed.
+Instead, the errors will propagate normally just like in other Active
+Record callbacks.
+
+When you define a `after_rollback` or `after_commit` callback, you
+will receive a deprecation warning about this upcoming change. When
+you are ready, you can opt into the new behvaior and remove the
+deprecation warning by adding following configuration to your
+`config/application.rb`:
+
+ config.active_record.raise_in_transactional_callbacks = true
+
+See [#14488](https://github.com/rails/rails/pull/14488) and
+[#16537](https://github.com/rails/rails/pull/16537) for more details.
+
+### Ordering of test cases
+
+In Rails 5.0, test cases will be executed in random order by default. In
+anticipation of this change, Rails 4.2 introduced a new configuration option
+`active_support.test_order` for explicitly specifying the test ordering. This
+allows you to either lock down the current behavior by setting the option to
+`:sorted`, or opt into the future behavior by setting the option to `:random`.
+
+If you do not specify a value for this option, a deprecation warning will be
+emitted. To avoid this, add the following line to your test environment:
+
+```ruby
+# config/environments/test.rb
+Rails.application.configure do
+ config.active_support.test_order = :sorted # or `:random` if you prefer
+end
+```
### Serialized attributes
@@ -393,7 +430,7 @@ included in the newly introduced `ActiveRecord::FixtureSet.context_class`, in
`test_helper.rb`.
```ruby
-class FixtureFileHelpers
+module FixtureFileHelpers
def file_sha(path)
Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
end