aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.rdoc2
-rw-r--r--actionpack/lib/abstract_controller/translation.rb9
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb16
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb24
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb48
-rw-r--r--actionpack/lib/action_view/template.rb3
-rw-r--r--activerecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/lib/active_record/base.rb4
-rw-r--r--activerecord/lib/active_record/fixtures.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb2
-rw-r--r--activesupport/lib/active_support/proxy_object.rb2
-rw-r--r--guides/source/4_0_release_notes.md5
-rw-r--r--guides/source/action_controller_overview.md4
-rw-r--r--guides/source/active_record_basics.md2
-rw-r--r--guides/source/active_record_callbacks.md1
-rw-r--r--guides/source/asset_pipeline.md20
-rw-r--r--guides/source/caching_with_rails.md47
-rw-r--r--guides/source/configuring.md2
-rw-r--r--guides/source/development_dependencies_install.md14
-rw-r--r--guides/source/engines.md23
-rw-r--r--guides/source/migrations.md4
-rw-r--r--guides/source/nested_model_forms.md2
-rw-r--r--guides/source/security.md1
-rw-r--r--guides/source/testing.md2
-rw-r--r--guides/source/working_with_javascript_in_rails.md2
26 files changed, 198 insertions, 49 deletions
diff --git a/README.rdoc b/README.rdoc
index 91a5f27add..bb9c418e0b 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -27,7 +27,7 @@ and render view templates in order to generate the appropriate HTTP response.
In Rails, the Controller and View layers are handled together by Action Pack.
These two layers are bundled in a single package due to their heavy interdependence.
-This is unlike the relationship between Active Record and Action Pack which are
+This is unlike the relationship between Active Record and Action Pack, which are
independent. Each of these packages can be used independently outside of Rails. You
can read more about Action Pack in its {README}[link:/rails/rails/blob/master/actionpack/README.rdoc].
diff --git a/actionpack/lib/abstract_controller/translation.rb b/actionpack/lib/abstract_controller/translation.rb
index b6c484d188..db48022b9f 100644
--- a/actionpack/lib/abstract_controller/translation.rb
+++ b/actionpack/lib/abstract_controller/translation.rb
@@ -1,5 +1,13 @@
module AbstractController
module Translation
+ # Delegates to <tt>I18n.translate</tt>. Also aliased as <tt>t</tt>.
+ #
+ # When the given key starts with a period, it will be scoped by the current
+ # controller and action. So if you call <tt>translate(".foo")</tt> from
+ # <tt>PeopleController#index</tt>, it will convert the call to
+ # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
+ # to translate many keys within the same controller / action and gives you a
+ # simple framework for scoping them consistently.
def translate(*args)
key = args.first
if key.is_a?(String) && (key[0] == '.')
@@ -11,6 +19,7 @@ module AbstractController
end
alias :t :translate
+ # Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
def localize(*args)
I18n.localize(*args)
end
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 91cf4784db..e7e8905d7e 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -137,6 +137,7 @@ module ActionDispatch # :nodoc:
@committed
end
+ # Sets the HTTP status code.
def status=(status)
@status = Rack::Utils.status_code(status)
end
@@ -145,16 +146,24 @@ module ActionDispatch # :nodoc:
@content_type = content_type.to_s
end
- # The response code of the request
+ # The response code of the request.
def response_code
@status
end
- # Returns a String to ensure compatibility with Net::HTTPResponse
+ # Returns a string to ensure compatibility with <tt>Net::HTTPResponse</tt>.
def code
@status.to_s
end
+ # Returns the corresponding message for the current HTTP status code:
+ #
+ # response.status = 200
+ # response.message # => "OK"
+ #
+ # response.status = 404
+ # response.message # => "Not Found"
+ #
def message
Rack::Utils::HTTP_STATUS_CODES[@status]
end
@@ -172,6 +181,8 @@ module ActionDispatch # :nodoc:
stream.to_path
end
+ # Returns the content of the response as a string. This contains the contents
+ # of any calls to <tt>render</tt>.
def body
strings = []
each { |part| strings << part.to_s }
@@ -180,6 +191,7 @@ module ActionDispatch # :nodoc:
EMPTY = " "
+ # Allows you to manually set or override the response body.
def body=(body)
@blank = true if body == EMPTY
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 11743e36f2..5b3a2cae7c 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -182,6 +182,8 @@ module ActionView
# width="30" and height="45", and "50" becomes width="50" and height="50".
# <tt>:size</tt> will be ignored if the value is not in the correct format.
#
+ # ==== Examples
+ #
# image_tag("icon")
# # => <img alt="Icon" src="/assets/icon" />
# image_tag("icon.png")
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 10748aacf4..da8a9dafe4 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -1040,14 +1040,38 @@ module ActionView
end
class FormBuilder
+ # Wraps ActionView::Helpers::DateHelper#date_select for form builders:
+ #
+ # <%= form_for @person do |f| %>
+ # <%= f.date_select :birth_date %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def date_select(method, options = {}, html_options = {})
@template.date_select(@object_name, method, objectify_options(options), html_options)
end
+ # Wraps ActionView::Helpers::DateHelper#time_select for form builders:
+ #
+ # <%= form_for @race do |f| %>
+ # <%= f.time_select :average_lap %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def time_select(method, options = {}, html_options = {})
@template.time_select(@object_name, method, objectify_options(options), html_options)
end
+ # Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:
+ #
+ # <%= form_for @person do |f| %>
+ # <%= f.time_select :last_request_at %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def datetime_select(method, options = {}, html_options = {})
@template.datetime_select(@object_name, method, objectify_options(options), html_options)
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index ae7bfd1ec6..89c24956a3 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -756,26 +756,74 @@ module ActionView
end
class FormBuilder
+ # Wraps ActionView::Helpers::FormOptionsHelper#select for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.select :person_id, Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true }) %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def select(method, choices, options = {}, html_options = {})
@template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
@template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#grouped_collection_select for form builders:
+ #
+ # <%= form_for @city do |f| %>
+ # <%= f.grouped_collection_select :country_id, :country_id, @continents, :countries, :name, :id, :name %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
@template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#time_zone_select for form builders:
+ #
+ # <%= form_for @user do |f| %>
+ # <%= f.time_zone_select :time_zone, nil, include_blank: true %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
@template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
@template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block)
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
@template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block)
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index b927c69260..f73d14c79b 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -80,8 +80,7 @@ module ActionView
# problems with converting the user's data to
# the <tt>default_internal</tt>.
#
- # To do so, simply raise the raise +WrongEncodingError+
- # as follows:
+ # To do so, simply raise +WrongEncodingError+ as follows:
#
# raise WrongEncodingError.new(
# problematic_string,
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 16a46a59d1..06bdabfced 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -191,7 +191,7 @@ module ActiveRecord
# * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
# * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
# * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
- # <tt>Project#milestones.delete(milestone), Project#milestones.destroy(mileston), Project#milestones.find(milestone_id),</tt>
+ # <tt>Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id),</tt>
# <tt>Project#milestones.build, Project#milestones.create</tt>
# * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt>
# <tt>Project#categories.delete(category1), Project#categories.destroy(category1)</tt>
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index bf5793d454..e262401da6 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -162,8 +162,8 @@ module ActiveRecord #:nodoc:
#
# Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects
# by simple queries without turning to SQL. They work by appending the name of an attribute
- # to <tt>find_by_</tt> # like <tt>Person.find_by_user_name</tt>.
- # Instead of writing # <tt>Person.where(user_name: user_name).first</tt>, you just do
+ # to <tt>find_by_</tt> like <tt>Person.find_by_user_name</tt>.
+ # Instead of writing <tt>Person.where(user_name: user_name).first</tt>, you just do
# <tt>Person.find_by_user_name(user_name)</tt>.
#
# It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 5a4ef5991d..2958d08210 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -363,11 +363,11 @@ module ActiveRecord
#
# first:
# name: Smurf
- # *DEFAULTS
+ # <<: *DEFAULTS
#
# second:
# name: Fraggle
- # *DEFAULTS
+ # <<: *DEFAULTS
#
# Any fixture labeled "DEFAULTS" is safely ignored.
class FixtureSet
diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
index 4e4852a5e6..1d3682eaf2 100644
--- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -43,7 +43,7 @@ class DateTime
# Returns a new DateTime where one or more of the elements have been changed
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
- # <tt>:minute</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
+ # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
# passed, then minute and sec is set to 0. If the hour and minute is passed,
# then sec is set to 0. The +options+ parameter takes a hash with any of these
# keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
diff --git a/activesupport/lib/active_support/proxy_object.rb b/activesupport/lib/active_support/proxy_object.rb
index a2bdf1d790..20a0fd8e62 100644
--- a/activesupport/lib/active_support/proxy_object.rb
+++ b/activesupport/lib/active_support/proxy_object.rb
@@ -5,7 +5,7 @@ module ActiveSupport
undef_method :==
undef_method :equal?
- # Let ActiveSupport::BasicObject at least raise exceptions.
+ # Let ActiveSupport::ProxyObject at least raise exceptions.
def raise(*args)
::Object.send(:raise, *args)
end
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index 52571fab60..a678dd9d90 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -7,7 +7,6 @@ Highlights in Rails 4.0:
* Strong Parameters
* Turbolinks
* Russian Doll Caching
-* Asynchronous Mailers
These release notes cover only the major changes. To know about various bug fixes and changes, please refer to the change logs or check out the [list of commits](https://github.com/rails/rails/commits/master) in the main Rails repository on GitHub.
@@ -150,7 +149,7 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activ
Action Pack
-----------
-Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railties/CHANGELOG.md) for detailed changes.
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/actionpack/CHANGELOG.md) for detailed changes.
### Notable changes
@@ -162,7 +161,7 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railt
Active Record
-------------
-Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railties/CHANGELOG.md) for detailed changes.
+Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activerecord/CHANGELOG.md) for detailed changes.
### Notable changes
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index cc80334af3..7260a48c8c 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -58,7 +58,7 @@ Parameters
You will probably want to access data sent in by the user or other parameters in your controller actions. There are two kinds of parameters possible in a web application. The first are parameters that are sent as part of the URL, called query string parameters. The query string is everything after "?" in the URL. The second type of parameter is usually referred to as POST data. This information usually comes from an HTML form which has been filled in by the user. It's called POST data because it can only be sent as part of an HTTP POST request. Rails does not make any distinction between query string parameters and POST parameters, and both are available in the `params` hash in your controller:
```ruby
-class ClientsController < ActionController::Base
+class ClientsController < ApplicationController
# This action uses query string parameters because it gets run
# by an HTTP GET request, but this does not make any difference
# to the way in which the parameters are accessed. The URL for
@@ -479,7 +479,7 @@ In addition to "before" filters, you can also run filters after an action has be
For example, in a website where changes have an approval workflow an administrator could be able to preview them easily, just apply them within a transaction:
```ruby
-class ChangesController < ActionController::Base
+class ChangesController < ApplicationController
around_action :wrap_in_transaction, only: :show
private
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index 062bcd49f4..69d7333e6f 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -1,6 +1,6 @@
Active Record Basics
====================
-
+
This guide is an introduction to Active Record.
After reading this guide, you will know:
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
index 3747b00b82..516457bcd3 100644
--- a/guides/source/active_record_callbacks.md
+++ b/guides/source/active_record_callbacks.md
@@ -157,7 +157,6 @@ The following methods trigger callbacks:
* `save!`
* `save(validate: false)`
* `toggle!`
-* `update`
* `update_attribute`
* `update`
* `update!`
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index fffa31927d..e939606c88 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -37,9 +37,9 @@ You should use the defaults for all new applications unless you have a specific
### Main Features
-The first feature of the pipeline is to concatenate assets. This is important in a production environment, because it can reduce the number of requests that a browser must make to render a web page. Web browsers are limited in the number of requests that they can make in parallel, so fewer requests can mean faster loading for your application.
+The first feature of the pipeline is to concatenate assets. This is important in a production environment, because it can reduce the number of requests that a browser makes to render a web page. Web browsers are limited in the number of requests that they can make in parallel, so fewer requests can mean faster loading for your application.
-Rails 2.x introduced the ability to concatenate JavaScript and CSS assets by placing `:cache => true` at the end of the `javascript_include_tag` and `stylesheet_link_tag` methods. But this technique has some limitations. For example, it cannot generate the caches in advance, and it is not able to transparently include assets provided by third-party libraries.
+Rails 2.x introduced the ability to concatenate JavaScript and CSS assets by placing `cache: true` at the end of the `javascript_include_tag` and `stylesheet_link_tag` methods. But this technique has some limitations. For example, it cannot generate the caches in advance, and it is not able to transparently include assets provided by third-party libraries.
Starting with version 3.1, Rails defaults to concatenating all JavaScript files into one master `.js` file and all CSS files into one master `.css` file. As you'll learn later in this guide, you can customize this strategy to group files any way you like. In production, Rails inserts an MD5 fingerprint into each filename so that the file is cached by the web browser. You can invalidate the cache by altering this fingerprint, which happens automatically whenever you change the file contents.
@@ -369,8 +369,8 @@ If any of the files in the manifest have changed between requests, the server re
Debug mode can also be enabled in the Rails helper methods:
```erb
-<%= stylesheet_link_tag "application", :debug => true %>
-<%= javascript_include_tag "application", :debug => true %>
+<%= stylesheet_link_tag "application", debug: true %>
+<%= javascript_include_tag "application", debug: true %>
```
The `:debug` option is redundant if debug mode is on.
@@ -445,7 +445,7 @@ NOTE. If you are precompiling your assets locally, you can use `bundle install -
The default matcher for compiling files includes `application.js`, `application.css` and all non-JS/CSS files (this will include all image assets automatically):
```ruby
-[ Proc.new{ |path| !%w(.js .css).include?(File.extname(path)) }, /application.(css|js)$/ ]
+[ Proc.new { |path| !%w(.js .css).include?(File.extname(path)) }, /application.(css|js)$/ ]
```
NOTE. The matcher (and other members of the precompile array; see below) is applied to final compiled file names. This means that anything that compiles to JS/CSS is excluded, as well as raw JS/CSS files; for example, `.coffee` and `.scss` files are **not** automatically included as they compile to JS/CSS.
@@ -460,7 +460,7 @@ Or you can opt to precompile all assets with something like this:
```ruby
# config/environments/production.rb
-config.assets.precompile << Proc.new { |path|
+config.assets.precompile << Proc.new do |path|
if path =~ /\.(css|js)\z/
full_path = Rails.application.assets.resolve(path).to_path
app_assets_path = Rails.root.join('app', 'assets').to_path
@@ -474,7 +474,7 @@ config.assets.precompile << Proc.new { |path|
else
false
end
-}
+end
```
NOTE. Always specify an expected compiled filename that ends with js or css, even if you want to add Sass or CoffeeScript files to the precompile array.
@@ -502,14 +502,14 @@ For Apache:
```apache
# The Expires* directives requires the Apache module `mod_expires` to be enabled.
-<LocationMatch "^/assets/.*$">
+<Location /assets/>
# Use of ETag is discouraged when Last-Modified is present
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
-</LocationMatch>
+</Location>
```
For nginx:
@@ -663,7 +663,7 @@ class Transformer
end
```
-To enable this, pass a `new` object to the config option in `application.rb`:
+To enable this, pass a new object to the config option in `application.rb`:
```ruby
config.assets.css_compressor = Transformer.new
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 0228d463cf..e52264f296 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -85,6 +85,51 @@ This fragment is then available to all actions in the `ProductsController` using
```ruby
expire_fragment('all_available_products')
```
+If you want to avoid expiring the fragment manually, whenever an action updates a product, you can define a helper method:
+
+```ruby
+module ProductsHelper
+ def cache_key_for_products
+ count = Product.count
+ max_updated_at = Product.maximum(:updated_at).try(:utc).try(:to_s, :number)
+ "products/all-#{count}-#{max_updated_at}"
+ end
+end
+```
+
+This method generates a cache key that depends on all products and can be used in the view:
+
+```ruby
+<% cache(cache_key_for_products) do %>
+ All available products:
+<% end %>
+```
+You can also use an Active Record model as the cache key:
+
+```ruby
+<% Product.all.each do |p| %>
+ <% cache(p) do %>
+ <%= link_to p.name, product_url(p) %>
+ <% end %>
+<% end %>
+```
+
+Behind the scenes, a method called `cache_key` will be invoked on the model and it returns a string like `products/23-20130109142513`. The cache key includes the model name, the id and finally the updated_at timestamp. Thus it will automatically generate a new fragment when the product is updated because the key changes.
+
+You can also combine the two schemes which is called "Russian Doll Caching":
+
+```ruby
+<% cache(cache_key_for_products) do %>
+ All available products:
+ <% Product.all.each do |p| %>
+ <% cache(p) do %>
+ <%= link_to p.name, product_url(p) %>
+ <% end %>
+ <% end %>
+<% end %>
+```
+
+It's called "Russian Doll Caching" because it nests multiple fragments. The advantage is that if a single product is updated, all the other inner fragments can be reused when regenerating the outer fragment.
### SQL Caching
@@ -93,7 +138,7 @@ Query caching is a Rails feature that caches the result set returned by each que
For example:
```ruby
-class ProductsController < ActionController
+class ProductsController < ApplicationController
def index
# Run a find query
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 4e2b7383a6..c1f31fd2b0 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -303,7 +303,7 @@ The schema dumper adds one additional configuration option:
* `config.action_controller.permit_all_parameters` sets all the parameters for mass assignment to be permitted by default. The default value is `false`.
-* `config.action_controller.raise_on_unpermitted_parameters` enables raising an exception if parameters that are not explicitly permitted are found. The default value is `true` in development and test environments, `false` otherwise.
+* `config.action_controller.action_on_unpermitted_params` enables logging or raising an exception if parameters that are not explicitly permitted are found. Set to `:log` or `:raise` to enable. The default value is `:log` in development and test environments, and `false` in all other environments.
### Configuring Action Dispatch
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index db43d62fcf..6493c1e1ec 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -174,6 +174,20 @@ $ cd activerecord
$ bundle exec rake postgresql:build_databases
```
+It is possible to build databases for both PostgreSQL and MySQL with
+
+```bash
+$ cd activerecord
+$ bundle exec rake db:create
+```
+
+You can cleanup the databases using
+
+```bash
+$ cd activerecord
+$ bundle exec rake db:drop
+```
+
NOTE: Using the rake task to create the test databases ensures they have the correct character set and collation.
NOTE: You'll see the following warning (or localized warning) during activating HStore extension in PostgreSQL 9.1.x or earlier: "WARNING: => is deprecated as an operator".
diff --git a/guides/source/engines.md b/guides/source/engines.md
index f35233993c..459aa8d57e 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -261,9 +261,9 @@ end
This helps prevent conflicts with any other engine or application that may have a post resource as well.
-Finally, two files that are the assets for this resource are generated, `app/assets/javascripts/blorgh/posts.js` and `app/assets/javascripts/blorgh/posts.css`. You'll see how to use these a little later.
+Finally, two files that are the assets for this resource are generated, `app/assets/javascripts/blorgh/posts.js` and `app/assets/stylesheets/blorgh/posts.css`. You'll see how to use these a little later.
-By default, the scaffold styling is not applied to the engine as the engine's layout file, `app/views/blorgh/application.html.erb` doesn't load it. To make this apply, insert this line into the `<head>` tag of this layout:
+By default, the scaffold styling is not applied to the engine as the engine's layout file, `app/views/layouts/blorgh/application.html.erb` doesn't load it. To make this apply, insert this line into the `<head>` tag of this layout:
```erb
<%= stylesheet_link_tag "scaffold" %>
@@ -288,7 +288,7 @@ Now people will only need to go to the root of the engine to see all the posts,
### Generating a comments resource
-Now that the engine can to create new blog posts, it only makes sense to add commenting functionality as well. To do get this, you'll need to generate a comment model, a comment controller and then modify the posts scaffold to display comments and allow people to create new ones.
+Now that the engine can create new blog posts, it only makes sense to add commenting functionality as well. To do this, you'll need to generate a comment model, a comment controller and then modify the posts scaffold to display comments and allow people to create new ones.
Run the model generator and tell it to generate a `Comment` model, with the related table having two columns: a `post_id` integer and `text` text column.
@@ -470,7 +470,7 @@ If you have multiple engines that need migrations copied over, use `railties:ins
$ rake railties:install:migrations
```
-This command, when run for the first time will copy over all the migrations from the engine. When run the next time, it will only copy over migrations that haven't been copied over already. The first run for this command will output something such as this:
+This command, when run for the first time, will copy over all the migrations from the engine. When run the next time, it will only copy over migrations that haven't been copied over already. The first run for this command will output something such as this:
```bash
Copied migration [timestamp_1]_create_blorgh_posts.rb from blorgh
@@ -754,10 +754,9 @@ end
#### Implementing Decorator Pattern Using ActiveSupport::Concern
-Using `Class#class_eval` is great for simple adjustments, but for more complex class modifications, you might want to consider using [`ActiveSupport::Concern`](http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html) helps manage load order of interlinked dependencies at run time allowing you to significantly modularize your code.
+Using `Class#class_eval` is great for simple adjustments, but for more complex class modifications, you might want to consider using [`ActiveSupport::Concern`](http://edgeapi.rubyonrails.org/classes/ActiveSupport/Concern.html). ActiveSupport::Concern manages load order of interlinked dependent modules and classes at run time allowing you to significantly modularize your code.
-**Adding** `Post#time_since_created`<br/>
-**Overriding** `Post#summary`
+**Adding** `Post#time_since_created` and **Overriding** `Post#summary`
```ruby
# MyApp/app/models/blorgh/post.rb
@@ -790,7 +789,7 @@ module Blorgh::Concerns::Models::Post
extend ActiveSupport::Concern
# 'included do' causes the included code to be evaluated in the
- # conext where it is included (post.rb), rather than be
+ # context where it is included (post.rb), rather than be
# executed in the module's context (blorgh/concerns/models/post).
included do
attr_accessor :author_name
@@ -800,9 +799,9 @@ module Blorgh::Concerns::Models::Post
private
- def set_author
- self.author = User.find_or_create_by(name: author_name)
- end
+ def set_author
+ self.author = User.find_or_create_by(name: author_name)
+ end
end
def summary
@@ -840,7 +839,7 @@ Try this now by creating a new file at `app/views/blorgh/posts/index.html.erb` a
### Routes
-Routes inside an engine are, by default, isolated from the application. This is done by the `isolate_namespace` call inside the `Engine` class. This essentially means that the application and its engines can have identically named routes, and that they will not clash.
+Routes inside an engine are, by default, isolated from the application. This is done by the `isolate_namespace` call inside the `Engine` class. This essentially means that the application and its engines can have identically named routes and they will not clash.
Routes inside an engine are drawn on the `Engine` class within `config/routes.rb`, like this:
diff --git a/guides/source/migrations.md b/guides/source/migrations.md
index 617e01bd15..cefbc3b829 100644
--- a/guides/source/migrations.md
+++ b/guides/source/migrations.md
@@ -474,7 +474,7 @@ class ExampleMigration < ActiveRecord::Migration
t.references :category
end
- #add a foreign key
+ # add a foreign key
execute <<-SQL
ALTER TABLE products
ADD CONSTRAINT fk_products_categories
@@ -1011,7 +1011,7 @@ with foreign key constraints in the database.
Although Active Record does not provide any tools for working directly with
such features, the `execute` method can be used to execute arbitrary SQL. You
-could also use some plugin like
+could also use some gem like
[foreigner](https://github.com/matthuhiggins/foreigner) which add foreign key
support to Active Record (including support for dumping foreign keys in
`db/schema.rb`).
diff --git a/guides/source/nested_model_forms.md b/guides/source/nested_model_forms.md
index 93d8e8dfcd..b90b3bb5fc 100644
--- a/guides/source/nested_model_forms.md
+++ b/guides/source/nested_model_forms.md
@@ -98,7 +98,7 @@ A nested model form will _only_ be built if the associated object(s) exist. This
Consider the following typical RESTful controller which will prepare a new Person instance and its `address` and `projects` associations before rendering the `new` template:
```ruby
-class PeopleController < ActionController:Base
+class PeopleController < ApplicationController
def new
@person = Person.new
@person.built_address
diff --git a/guides/source/security.md b/guides/source/security.md
index 3706a61431..769bd130be 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -9,7 +9,6 @@ After reading this guide, you will know:
* The concept of sessions in Rails, what to put in there and popular attack methods.
* How just visiting a site can be a security problem (with CSRF).
* What you have to pay attention to when working with files or providing an administration interface.
-* The Rails-specific mass assignment problem.
* How to manage users: Logging in and out and attack methods on all layers.
* And the most popular injection attack methods.
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 09d6d2d5ee..39a44794a7 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -943,7 +943,7 @@ Cheers!
This is the right time to understand a little more about writing tests for your mailers. The line `ActionMailer::Base.delivery_method = :test` in `config/environments/test.rb` sets the delivery method to test mode so that email will not actually be delivered (useful to avoid spamming your users while testing) but instead it will be appended to an array (`ActionMailer::Base.deliveries`).
-However often in unit tests, mails will not actually be sent, simply constructed, as in the example above, where the precise content of the email is checked against what it should be.
+This way, emails are not actually sent, simply constructed. The precise content of the email can then be checked against what is expected, as in the example above.
### Functional Testing
diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md
index a7ca531123..03ef770352 100644
--- a/guides/source/working_with_javascript_in_rails.md
+++ b/guides/source/working_with_javascript_in_rails.md
@@ -51,7 +51,7 @@ with an id of `results`.
Rails provides quite a bit of built-in support for building web pages with this
technique. You rarely have to write this code yourself. The rest of this guide
-will show you how Rails can help you write web sites in this manner, but it's
+will show you how Rails can help you write websites in this way, but it's
all built on top of this fairly simple technique.
Unobtrusive JavaScript