aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/4_1_release_notes.md37
-rw-r--r--guides/source/action_controller_overview.md45
-rw-r--r--guides/source/action_view_overview.md17
-rw-r--r--guides/source/active_record_querying.md2
-rw-r--r--guides/source/active_support_core_extensions.md25
-rw-r--r--guides/source/caching_with_rails.md20
-rw-r--r--guides/source/command_line.md8
-rw-r--r--guides/source/configuring.md8
-rw-r--r--guides/source/documents.yaml1
-rw-r--r--guides/source/getting_started.md53
-rw-r--r--guides/source/i18n.md2
-rw-r--r--guides/source/layouts_and_rendering.md7
-rw-r--r--guides/source/migrations.md160
-rw-r--r--guides/source/plugins.md6
-rw-r--r--guides/source/routing.md36
-rw-r--r--guides/source/security.md13
-rw-r--r--guides/source/upgrading_ruby_on_rails.md44
-rw-r--r--guides/source/working_with_javascript_in_rails.md4
18 files changed, 251 insertions, 237 deletions
diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md
index a859553b1b..822943d81e 100644
--- a/guides/source/4_1_release_notes.md
+++ b/guides/source/4_1_release_notes.md
@@ -291,6 +291,10 @@ for detailed changes.
with `config.active_record.maintain_test_schema = false`. ([Pull
Request](https://github.com/rails/rails/pull/13528))
+* Introduce `Rails.gem_version` as a convenience method to return
+ `Gem::Version.new(Rails.version)`, suggesting a more reliable way to perform
+ version comparison. ([Pull Request](https://github.com/rails/rails/pull/14103))
+
Action Pack
-----------
@@ -346,10 +350,14 @@ for detailed changes.
params "deep munging" that was used to address security vulnerability
CVE-2013-0155. ([Pull Request](https://github.com/rails/rails/pull/13188))
-* New config option `config.action_dispatch.cookies_serializer` for specifying
- a serializer for the signed and encrypted cookie jars. (Pull Requests [1](https://github.com/rails/rails/pull/13692), [2](https://github.com/rails/rails/pull/13945) / [More Details](upgrading_ruby_on_rails.html#cookies-serializer))
+* New config option `config.action_dispatch.cookies_serializer` for specifying a
+ serializer for the signed and encrypted cookie jars. (Pull Requests
+ [1](https://github.com/rails/rails/pull/13692),
+ [2](https://github.com/rails/rails/pull/13945) /
+ [More Details](upgrading_ruby_on_rails.html#cookies-serializer))
-* Added `render :plain`, `render :html` and `render :body`. ([Pull Request](https://github.com/rails/rails/pull/14062) /
+* Added `render :plain`, `render :html` and `render
+ :body`. ([Pull Request](https://github.com/rails/rails/pull/14062) /
[More Details](upgrading_ruby_on_rails.html#rendering-content-from-string))
@@ -388,7 +396,7 @@ for detailed changes.
* Removed deprecated `scope` use without passing a callable object.
* Removed deprecated `transaction_joinable=` in favor of `begin_transaction`
- with `d:joinable` option.
+ with a `:joinable` option.
* Removed deprecated `decrement_open_transactions`.
@@ -457,10 +465,10 @@ for detailed changes.
### Notable changes
-* Default scopes are no longer overriden by chained conditions.
+* Default scopes are no longer overridden by chained conditions.
Before this change when you defined a `default_scope` in a model
- it was overriden by chained conditions in the same field. Now it
+ it was overridden by chained conditions in the same field. Now it
is merged like any other scope. [More Details](upgrading_ruby_on_rails.html#changes-on-default-scopes).
* Added `ActiveRecord::Base.to_param` for convenient "pretty" URLs derived from
@@ -543,15 +551,15 @@ for detailed changes.
* Make `touch` fire the `after_commit` and `after_rollback`
callbacks. ([Pull Request](https://github.com/rails/rails/pull/12031))
-* Enable partial indexes for `sqlite >=
- 3.8.0`. ([Pull Request](https://github.com/rails/rails/pull/13350))
+* Enable partial indexes for `sqlite >= 3.8.0`.
+ ([Pull Request](https://github.com/rails/rails/pull/13350))
* Make `change_column_null`
- revertable. ([Commit](https://github.com/rails/rails/commit/724509a9d5322ff502aefa90dd282ba33a281a96))
+ revertible. ([Commit](https://github.com/rails/rails/commit/724509a9d5322ff502aefa90dd282ba33a281a96))
* Added a flag to disable schema dump after migration. This is set to `false`
- by defualt in the production environment for new applications. ([Pull Request](https://github.com/rails/rails/pull/13948))
-
+ by default in the production environment for new applications.
+ ([Pull Request](https://github.com/rails/rails/pull/13948))
Active Model
------------
@@ -703,13 +711,14 @@ for detailed changes.
* Default the new `I18n.enforce_available_locales` config to `true`, meaning
`I18n` will make sure that all locales passed to it must be declared in the
`available_locales`
- list. ([Pull Request](https://github.com/rails/rails/commit/8e21ae37ad9fef6b7393a84f9b5f2e18a831e49a))
+ list. ([Pull Request](https://github.com/rails/rails/pull/13341))
-* Introduce Module#concerning: a natural, low-ceremony way to separate
+* Introduce `Module#concerning`: a natural, low-ceremony way to separate
responsibilities within a
class. ([Commit](https://github.com/rails/rails/commit/1eee0ca6de975b42524105a59e0521d18b38ab81))
-* Added `Object#present_in` to simplify value whitelisting. ([Commit](https://github.com/rails/rails/commit/4edca106daacc5a159289eae255207d160f22396))
+* Added `Object#presence_in` to simplify value whitelisting.
+ ([Commit](https://github.com/rails/rails/commit/4edca106daacc5a159289eae255207d160f22396))
Credits
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 5b5f53c9be..0f46ba8698 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -381,16 +381,31 @@ You can also pass a `:domain` key and specify the domain name for the cookie:
YourApp::Application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com"
```
-Rails sets up (for the CookieStore) a secret key used for signing the session data. This can be changed in `config/initializers/secret_token.rb`
+Rails sets up (for the CookieStore) a secret key used for signing the session data. This can be changed in `config/secrets.yml`
```ruby
# Be sure to restart your server when you modify this file.
-# Your secret key for verifying the integrity of signed cookies.
+# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
+
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
-YourApp::Application.config.secret_key_base = '49d3f3de9ed86c74b94ad6bd0...'
+# You can use `rake secret` to generate a secure secret key.
+
+# Make sure the secrets in this file are kept private
+# if you're sharing your code publicly.
+
+development:
+ secret_key_base: a75d...
+
+test:
+ secret_key_base: 492f...
+
+# Do not keep production secrets in the repository,
+# instead read values from the environment.
+production:
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
```
NOTE: Changing the secret when using the `CookieStore` will invalidate all existing sessions.
@@ -604,6 +619,30 @@ It is also possible to pass a custom serializer that responds to `load` and
Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializer
```
+When using the `:json` or `:hybrid` serializer, you should beware that not all
+Ruby objects can be serialized as JSON. For example, `Date` and `Time` objects
+will be serialized as strings, and `Hash`es will have their keys stringified.
+
+```ruby
+class CookiesController < ApplicationController
+ def set_cookie
+ cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014
+ redirect_to action: 'read_cookie'
+ end
+
+ def read_cookie
+ cookies.encrypted[:expiration_date] # => "2014-03-20"
+ end
+end
+```
+
+It's advisable that you only store simple data (strings and numbers) in cookies.
+If you have to store complex objects, you would need to handle the conversion
+manually when reading the values on subsequent requests.
+
+If you use the cookie session store, this would apply to the `session` and
+`flash` hash as well.
+
Rendering XML and JSON data
---------------------------
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index 6a355a5177..74f95bfcfd 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -1550,7 +1550,7 @@ end
Sanitizes a block of CSS code.
-#### strip_links(html)
+#### strip_links(html)
Strips all link tags from text leaving just the link text.
```ruby
@@ -1568,9 +1568,9 @@ strip_links('Blog: <a href="http://myblog.com/">Visit</a>.')
# => Blog: Visit.
```
-#### strip_tags(html)
+#### strip_tags(html)
-Strips all HTML tags from the html, including comments.
+Strips all HTML tags from the html, including comments.
This uses the html-scanner tokenizer and so its HTML parsing ability is limited by that of html-scanner.
```ruby
@@ -1585,6 +1585,17 @@ strip_tags("<b>Bold</b> no more! <a href='more.html'>See more</a>")
NB: The output may still contain unescaped '<', '>', '&' characters and confuse browsers.
+### CsrfHelper
+
+Returns meta tags "csrf-param" and "csrf-token" with the name of the cross-site
+request forgery protection parameter and token, respectively.
+
+```html
+<%= csrf_meta_tags %>
+```
+
+NOTE: Regular forms generate hidden fields so they do not use these tags. More
+details can be found in the [Rails Security Guide](security.html#cross-site-request-forgery-csrf).
Localized Views
---------------
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 4900f176a6..0a332d7dd9 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -961,7 +961,7 @@ SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id =
WARNING: This method only works with `INNER JOIN`.
-Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clause for those associations when using the `joins` method.
+Active Record lets you use the names of the [associations](association_basics.html) defined on the model as a shortcut for specifying `JOIN` clauses for those associations when using the `joins` method.
For example, consider the following `Category`, `Post`, `Comment`, `Guest` and `Tag` models:
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 2ad09f599b..5698dc0413 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -157,9 +157,9 @@ Active Support provides `duplicable?` to programmatically query an object about
```ruby
"foo".duplicable? # => true
-"".duplicable? # => true
+"".duplicable? # => true
0.0.duplicable? # => false
-false.duplicable? # => false
+false.duplicable? # => false
```
By definition all objects are `duplicable?` except `nil`, `false`, `true`, symbols, numbers, class, and module objects.
@@ -2719,11 +2719,14 @@ The method `transform_keys` accepts a block and returns a hash that has applied
# => {"" => nil, "A" => :a, "1" => 1}
```
-The result in case of collision is undefined:
+In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
```ruby
{"a" => 1, a: 2}.transform_keys { |key| key.to_s.upcase }
-# => {"A" => 2}, in my test, can't rely on this result though
+# The result could either be
+# => {"A"=>2}
+# or
+# => {"A"=>1}
```
This method may be useful for example to build specialized conversions. For instance `stringify_keys` and `symbolize_keys` use `transform_keys` to perform their key conversions:
@@ -2758,11 +2761,14 @@ The method `stringify_keys` returns a hash that has a stringified version of the
# => {"" => nil, "a" => :a, "1" => 1}
```
-The result in case of collision is undefined:
+In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
```ruby
{"a" => 1, a: 2}.stringify_keys
-# => {"a" => 2}, in my test, can't rely on this result though
+# The result could either be
+# => {"a"=>2}
+# or
+# => {"a"=>1}
```
This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionView::Helpers::FormHelper` defines:
@@ -2799,11 +2805,14 @@ The method `symbolize_keys` returns a hash that has a symbolized version of the
WARNING. Note in the previous example only one key was symbolized.
-The result in case of collision is undefined:
+In case of key collision, one of the values will be chosen. The chosen value may not always be the same given the same hash:
```ruby
{"a" => 1, a: 2}.symbolize_keys
-# => {:a=>2}, in my test, can't rely on this result though
+# The result could either be
+# => {:a=>2}
+# or
+# => {:a=>1}
```
This method may be useful for example to easily accept both symbols and strings as options. For instance `ActionController::UrlRewriter` defines
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index 0d45e5fb28..e898d75d1a 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -140,6 +140,26 @@ You can also combine the two schemes which is called "Russian Doll Caching":
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.
+### Low-Level Caching
+
+Sometimes you need to cache a particular value or query result, instead of caching view fragments. Rails caching mechanism works great for storing __any__ kind of information.
+
+The most efficient way to implement low-level caching is using the `Rails.cache.fetch` method. This method does both reading and writing to the cache. When passed only a single argument, the key is fetched and value from the cache is returned. If a block is passed, the result of the block will be cached to the given key and the result is returned.
+
+Consider the following example. An application has a `Product` model with an instance method that looks up the product’s price on a competing website. The data returned by this method would be perfect for low-level caching:
+
+```ruby
+class Product < ActiveRecord::Base
+ def competing_price
+ Rails.cache.fetch("#{cache_key}/competing_price", expires_in: 12.hours) do
+ Competitor::API.find_price(id)
+ end
+ end
+end
+```
+
+NOTE: Notice that in this example we used `cache_key` method, so the resulting cache-key will be something like `products/233-20140225082222765838000/competing_price`. `cache_key` generates a string based on the model’s `id` and `updated_at` attributes. This is a common convention and has the benefit of invalidating the cache whenever the product is updated. In general, when you use low-level caching for instance level information, you need to generate a cache key.
+
### SQL Caching
Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index 3b80faec7f..57283f7c40 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -411,7 +411,7 @@ The `doc:` namespace has the tools to generate documentation for your app, API d
### `notes`
-`rake notes` will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension `.builder`, `.rb`, `.erb`, `.haml` and `.slim` for both default and custom annotations.
+`rake notes` will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is done in files with extension `.builder`, `.rb`, `.rake`, `.yml`, `.yaml`, `.ruby`, `.css`, `.js` and `.erb` for both default and custom annotations.
```bash
$ rake notes
@@ -425,6 +425,12 @@ app/models/school.rb:
* [ 17] [FIXME]
```
+You can add support for new file extensions using `config.annotations.register_extensions` option, which receives a list of the extensions with its corresponding regex to match it up.
+
+```ruby
+config.annotations.register_extensions("scss", "sass", "less") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ }
+```
+
If you are looking for a specific annotation, say FIXME, you can use `rake notes:fixme`. Note that you have to lower case the annotation's name.
```bash
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 7b72e27b96..460fd3c301 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -110,7 +110,7 @@ numbers. New applications filter out passwords by adding the following `config.f
* `config.log_level` defines the verbosity of the Rails logger. This option defaults to `:debug` for all modes except production, where it defaults to `:info`.
-* `config.log_tags` accepts a list of methods that respond to `request` object. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications.
+* `config.log_tags` accepts a list of methods that the `request` object responds to. 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.
@@ -118,7 +118,7 @@ numbers. New applications filter out passwords by adding the following `config.f
* `config.reload_classes_only_on_change` enables or disables reloading of classes only when tracked files change. By default tracks everything on autoload paths and is set to true. If `config.cache_classes` is true, this option is ignored.
-* `config.secret_key_base` used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `config.secret_key_base` initialized to a random key in `config/initializers/secret_token.rb`.
+* `secrets.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`.
* `config.serve_static_assets` configures Rails itself to serve static assets. Defaults to true, but in the production environment is turned off as the server software (e.g. Nginx or Apache) used to run the application should serve static assets instead. Unlike the default setting set this to true when running (absolutely not recommended!) or testing your app in production mode using WEBrick. Otherwise you won't be able use page caching and requests for files that exist regularly under the public directory will anyway hit your Rails app.
@@ -274,7 +274,7 @@ All these configuration options are delegated to the `I18n` library.
* `config.active_record.pluralize_table_names` specifies whether Rails will look for singular or plural table names in the database. If set to true (the default), then the Customer class will use the `customers` table. If set to false, then the Customer class will use the `customer` table.
-* `config.active_record.default_timezone` determines whether to use `Time.local` (if set to `:local`) or `Time.utc` (if set to `:utc`) when pulling dates and times from the database. The default is `:utc` for Rails, although Active Record defaults to `:local` when used outside of Rails.
+* `config.active_record.default_timezone` determines whether to use `Time.local` (if set to `:local`) or `Time.utc` (if set to `:utc`) when pulling dates and times from the database. The default is `:utc`.
* `config.active_record.schema_format` controls the format for dumping the database schema to a file. The options are `:ruby` (the default) for a database-independent version that depends on migrations, or `:sql` for a set of (potentially database-dependent) SQL statements.
@@ -939,4 +939,4 @@ ActiveRecord::ConnectionTimeoutError - could not obtain a database connection wi
If you get the above error, you might want to increase the size of connection
pool by incrementing the `pool` option in `database.yml`
-NOTE. As Rails is multi-threaded by default, there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections.
+NOTE. If you are running in a multi-threaded environment, there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections.
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index e4653b47fc..a160c462b2 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -167,7 +167,6 @@
-
name: Ruby on Rails 4.1 Release Notes
url: 4_1_release_notes.html
- work_in_progress: true
description: Release notes for Rails 4.1.
-
name: Ruby on Rails 4.0 Release Notes
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index a16b9ac8da..c54c9efe94 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -57,9 +57,9 @@ learned elsewhere, you may have a less happy experience.
The Rails philosophy includes two major guiding principles:
-* **Don't Repeat Yourself:** DRY is a principle of software development which
+* **Don't Repeat Yourself:** DRY is a principle of software development which
states that "Every piece of knowledge must have a single, unambiguous, authoritative
- representation within a system." By not writing the same information over and over
+ representation within a system." By not writing the same information over and over
again, our code is more maintainable, more extensible, and less buggy.
* **Convention Over Configuration:** Rails has opinions about the best way to do many
things in a web application, and defaults to this set of conventions, rather than
@@ -206,7 +206,7 @@ This will fire up WEBrick, a web server distributed with Ruby by default. To see
your application in action, open a browser window and navigate to
<http://localhost:3000>. You should see the Rails default information page:
-![Welcome aboard screenshot](images/getting_started/rails_welcome.jpg)
+![Welcome aboard screenshot](images/getting_started/rails_welcome.png)
TIP: To stop the web server, hit Ctrl+C in the terminal window where it's
running. To verify the server has stopped you should see your command prompt
@@ -749,10 +749,33 @@ article. Try it! You should get an error that looks like this:
Rails has several security features that help you write secure applications,
and you're running into one of them now. This one is called
-`strong_parameters`, which requires us to tell Rails exactly which parameters
-we want to accept in our controllers. In this case, we want to allow the
-`title` and `text` parameters, so change your `create` controller action to
-look like this:
+`[strong_parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`,
+which requires us to tell Rails exactly which parameters are allowed into
+our controller actions.
+
+Why do you have to bother? The ability to grab and automatically assign
+all controller parameters to your model in one shot makes the programmer's
+job easier, but this convenience also allows malicious use. What if a
+request to the server was crafted to look like a new article form submit
+but also included extra fields with values that violated your applications
+integrity? They would be 'mass assigned' into your model and then into the
+database along with the good stuff - potentially breaking your application
+or worse.
+
+We have to whitelist our controller parameters to prevent wrongful
+mass assignment. In this case, we want to both allow and require the
+`title` and `text` parameters for valid use of `create`. The syntax for
+this introduces `require` and `permit`. The change will involve one line:
+
+```ruby
+ @article = Article.new(params.require(:article).permit(:title, :text))
+```
+
+This is often factored out into its own method so it can be reused by
+multiple actions in the same controller, for example `create` and `update`.
+Above and beyond mass assignment issues, the method is often made
+`private` to make sure it can't be called outside its intended context.
+Here is the result:
```ruby
def create
@@ -768,13 +791,7 @@ private
end
```
-See the `permit`? It allows us to accept both `title` and `text` in this
-action.
-
-TIP: Note that `def article_params` is private. This new approach prevents an
-attacker from setting the model's attributes by manipulating the hash passed to
-the model.
-For more information, refer to
+TIP: For more information, refer to the reference above and
[this blog article about Strong Parameters](http://weblog.rubyonrails.org/2012/3/21/strong-parameters/).
### Showing Articles
@@ -900,7 +917,7 @@ Also add a link in `app/views/articles/new.html.erb`, underneath the form, to
go back to the `index` action:
```erb
-<%= form_for :article do |f| %>
+<%= form_for :article, url: articles_path do |f| %>
...
<% end %>
@@ -1121,8 +1138,8 @@ via the `PATCH` HTTP method which is the HTTP method you're expected to use to
The first parameter of the `form_tag` can be an object, say, `@article` which would
cause the helper to fill in the form with the fields of the object. Passing in a
-symbol (`:article`) with the same name as the instance variable (`@article`) also
-automagically leads to the same behavior. This is what is happening here. More details
+symbol (`:article`) with the same name as the instance variable (`@article`) also
+automagically leads to the same behavior. This is what is happening here. More details
can be found in [form_for documentation](http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for).
Next we need to create the `update` action in
@@ -1396,7 +1413,7 @@ class CreateComments < ActiveRecord::Migration
t.text :body
# this line adds an integer column called `article_id`.
- t.references :article, index: true
+ t.references :article, index: true
t.timestamps
end
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index d72717fa3b..bef738b75b 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -137,7 +137,7 @@ If you want to translate your Rails application to a **single language other tha
However, you would probably like to **provide support for more locales** in your application. In such case, you need to set and pass the locale between requests.
-WARNING: You may be tempted to store the chosen locale in a _session_ or a <em>cookie</em>, however **do not do this**. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [<em>RESTful</em>](http://en.wikipedia.org/wiki/Representational_State_Transfer). Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
+WARNING: You may be tempted to store the chosen locale in a _session_ or a <em>cookie</em>. However, **do not do this**. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [<em>RESTful</em>](http://en.wikipedia.org/wiki/Representational_State_Transfer). Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
The _setting part_ is easy. You can set the locale in a `before_action` in the `ApplicationController` like this:
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index 66ed6f2e08..bd33c5a146 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -304,10 +304,13 @@ type, by using the `:body` option to `render`:
render body: "raw"
```
-TIP: This option should be used only if you explicitly want the content type to
-be unset. Using `:plain` or `:html` might be more appropriate in most of the
+TIP: This option should be used only if you don't care about the content type of
+the response. Using `:plain` or `:html` might be more appropriate in most of the
time.
+NOTE: Unless overriden, your response returned from this render option will be
+`text/html`, as that is the default content type of Action Dispatch response.
+
#### Options for `render`
Calls to the `render` method generally accept four options:
diff --git a/guides/source/migrations.md b/guides/source/migrations.md
index 64c4e1e07e..bfee55a95d 100644
--- a/guides/source/migrations.md
+++ b/guides/source/migrations.md
@@ -18,9 +18,10 @@ After reading this guide, you will know:
Migration Overview
------------------
-Migrations are a convenient way to alter your database schema over time in a
-consistent and easy way. They use a Ruby DSL so that you don't have to write
-SQL by hand, allowing your schema and changes to be database independent.
+Migrations are a convenient way to
+[alter your database schema over time](http://en.wikipedia.org/wiki/Schema_migration)
+in a consistent and easy way. They use a Ruby DSL so that you don't have to
+write SQL by hand, allowing your schema and changes to be database independent.
You can think of each migration as being a new 'version' of the database. A
schema starts off with nothing in it, and each migration modifies it to add or
@@ -818,159 +819,6 @@ The `revert` method can be helpful when writing a new migration to undo
previous migrations in whole or in part
(see [Reverting Previous Migrations](#reverting-previous-migrations) above).
-Using Models in Your Migrations
--------------------------------
-
-When creating or updating data in a migration it is often tempting to use one
-of your models. After all, they exist to provide easy access to the underlying
-data. This can be done, but some caution should be observed.
-
-For example, problems occur when the model uses database columns which are (1)
-not currently in the database and (2) will be created by this or a subsequent
-migration.
-
-Consider this example, where Alice and Bob are working on the same code base
-which contains a `Product` model:
-
-Bob goes on vacation.
-
-Alice creates a migration for the `products` table which adds a new column and
-initializes it:
-
-```ruby
-# db/migrate/20100513121110_add_flag_to_product.rb
-
-class AddFlagToProduct < ActiveRecord::Migration
- def change
- add_column :products, :flag, :boolean
- reversible do |dir|
- dir.up { Product.update_all flag: false }
- end
- end
-end
-```
-
-She also adds a validation to the `Product` model for the new column:
-
-```ruby
-# app/models/product.rb
-
-class Product < ActiveRecord::Base
- validates :flag, inclusion: { in: [true, false] }
-end
-```
-
-Alice adds a second migration which adds another column to the `products`
-table and initializes it:
-
-```ruby
-# db/migrate/20100515121110_add_fuzz_to_product.rb
-
-class AddFuzzToProduct < ActiveRecord::Migration
- def change
- add_column :products, :fuzz, :string
- reversible do |dir|
- dir.up { Product.update_all fuzz: 'fuzzy' }
- end
- end
-end
-```
-
-She also adds a validation to the `Product` model for the new column:
-
-```ruby
-# app/models/product.rb
-
-class Product < ActiveRecord::Base
- validates :flag, inclusion: { in: [true, false] }
- validates :fuzz, presence: true
-end
-```
-
-Both migrations work for Alice.
-
-Bob comes back from vacation and:
-
-* Updates the source - which contains both migrations and the latest version
- of the Product model.
-* Runs outstanding migrations with `rake db:migrate`, which
- includes the one that updates the `Product` model.
-
-The migration crashes because when the model attempts to save, it tries to
-validate the second added column, which is not in the database when the _first_
-migration runs:
-
-```
-rake aborted!
-An error has occurred, this and all later migrations canceled:
-
-undefined method `fuzz' for #<Product:0x000001049b14a0>
-```
-
-A fix for this is to create a local model within the migration. This keeps
-Rails from running the validations, so that the migrations run to completion.
-
-When using a local model, it's a good idea to call
-`Product.reset_column_information` to refresh the Active Record cache for the
-`Product` model prior to updating data in the database.
-
-If Alice had done this instead, there would have been no problem:
-
-```ruby
-# db/migrate/20100513121110_add_flag_to_product.rb
-
-class AddFlagToProduct < ActiveRecord::Migration
- class Product < ActiveRecord::Base
- end
-
- def change
- add_column :products, :flag, :boolean
- Product.reset_column_information
- reversible do |dir|
- dir.up { Product.update_all flag: false }
- end
- end
-end
-```
-
-```ruby
-# db/migrate/20100515121110_add_fuzz_to_product.rb
-
-class AddFuzzToProduct < ActiveRecord::Migration
- class Product < ActiveRecord::Base
- end
-
- def change
- add_column :products, :fuzz, :string
- Product.reset_column_information
- reversible do |dir|
- dir.up { Product.update_all fuzz: 'fuzzy' }
- end
- end
-end
-```
-
-There are other ways in which the above example could have gone badly.
-
-For example, imagine that Alice creates a migration that selectively
-updates the `description` field on certain products. She runs the
-migration, commits the code, and then begins working on the next feature,
-which is to add a new column `fuzz` to the products table.
-
-She creates two migrations for this new feature, one which adds the new
-column, and a second which selectively updates the `fuzz` column based on
-other product attributes.
-
-These migrations run just fine, but when Bob comes back from his vacation
-and calls `rake db:migrate` to run all the outstanding migrations, he gets a
-subtle bug: The descriptions have defaults, and the `fuzz` column is present,
-but `fuzz` is `nil` on all products.
-
-The solution is again to use `Product.reset_column_information` before
-referencing the Product model in a migration, ensuring the Active Record's
-knowledge of the table structure is current before manipulating data in those
-records.
-
Schema Dumping and You
----------------------
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index 720ca5d117..fe4215839f 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -92,12 +92,12 @@ Run `rake` to run the test. This test should fail because we haven't implemented
Great - now you are ready to start development.
-In `lib/yaffle.rb`, add `require "yaffle/core_ext"`:
+In `lib/yaffle.rb`, add `require 'yaffle/core_ext'`:
```ruby
# yaffle/lib/yaffle.rb
-require "yaffle/core_ext"
+require 'yaffle/core_ext'
module Yaffle
end
@@ -149,7 +149,7 @@ end
```ruby
# yaffle/lib/yaffle.rb
-require "yaffle/core_ext"
+require 'yaffle/core_ext'
require 'yaffle/acts_as_yaffle'
module Yaffle
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 9c495bf09d..eef618f28d 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -352,15 +352,15 @@ end
The comments resource here will have the following routes generated for it:
-| HTTP Verb | Path | Controller#Action | Named Helper |
-| --------- | -------------------------------------- | ----------------- | ------------------- |
-| GET | /posts/:post_id/comments(.:format) | comments#index | post_comments |
-| POST | /posts/:post_id/comments(.:format) | comments#create | post_comments |
-| GET | /posts/:post_id/comments/new(.:format) | comments#new | new_post_comment |
-| GET | /sekret/comments/:id/edit(.:format) | comments#edit | edit_comment |
-| GET | /sekret/comments/:id(.:format) | comments#show | comment |
-| PATCH/PUT | /sekret/comments/:id(.:format) | comments#update | comment |
-| DELETE | /sekret/comments/:id(.:format) | comments#destroy | comment |
+| HTTP Verb | Path | Controller#Action | Named Helper |
+| --------- | -------------------------------------- | ----------------- | --------------------- |
+| GET | /posts/:post_id/comments(.:format) | comments#index | post_comments_path |
+| POST | /posts/:post_id/comments(.:format) | comments#create | post_comments_path |
+| GET | /posts/:post_id/comments/new(.:format) | comments#new | new_post_comment_path |
+| GET | /sekret/comments/:id/edit(.:format) | comments#edit | edit_comment_path |
+| GET | /sekret/comments/:id(.:format) | comments#show | comment_path |
+| PATCH/PUT | /sekret/comments/:id(.:format) | comments#update | comment_path |
+| DELETE | /sekret/comments/:id(.:format) | comments#destroy | comment_path |
The `:shallow_prefix` option adds the specified parameter to the named helpers:
@@ -374,15 +374,15 @@ end
The comments resource here will have the following routes generated for it:
-| HTTP Verb | Path | Controller#Action | Named Helper |
-| --------- | -------------------------------------- | ----------------- | ------------------- |
-| GET | /posts/:post_id/comments(.:format) | comments#index | post_comments |
-| POST | /posts/:post_id/comments(.:format) | comments#create | post_comments |
-| GET | /posts/:post_id/comments/new(.:format) | comments#new | new_post_comment |
-| GET | /comments/:id/edit(.:format) | comments#edit | edit_sekret_comment |
-| GET | /comments/:id(.:format) | comments#show | sekret_comment |
-| PATCH/PUT | /comments/:id(.:format) | comments#update | sekret_comment |
-| DELETE | /comments/:id(.:format) | comments#destroy | sekret_comment |
+| HTTP Verb | Path | Controller#Action | Named Helper |
+| --------- | -------------------------------------- | ----------------- | ------------------------ |
+| GET | /posts/:post_id/comments(.:format) | comments#index | post_comments_path |
+| POST | /posts/:post_id/comments(.:format) | comments#create | post_comments_path |
+| GET | /posts/:post_id/comments/new(.:format) | comments#new | new_post_comment_path |
+| GET | /comments/:id/edit(.:format) | comments#edit | edit_sekret_comment_path |
+| GET | /comments/:id(.:format) | comments#show | sekret_comment_path |
+| PATCH/PUT | /comments/:id(.:format) | comments#update | sekret_comment_path |
+| DELETE | /comments/:id(.:format) | comments#destroy | sekret_comment_path |
### Routing concerns
diff --git a/guides/source/security.md b/guides/source/security.md
index ece431dae7..a40c99cbfd 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -95,9 +95,16 @@ Rails 2 introduced a new default session storage, CookieStore. CookieStore saves
That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA1, for compatibility). So _don't use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters_.
-`config.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `config.secret_key_base` initialized to a random key in `config/initializers/secret_token.rb`, e.g.:
+`secrets.secret_key_base` is used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get `secrets.secret_key_base` initialized to a random key present in `config/secrets.yml`, e.g.:
- YourApp::Application.config.secret_key_base = '49d3f3de9ed86c74b94ad6bd0...'
+ development:
+ secret_key_base: a75d...
+
+ test:
+ secret_key_base: 492f...
+
+ production:
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Older versions of Rails use CookieStore, which uses `secret_token` instead of `secret_key_base` that is used by EncryptedCookieStore. Read the upgrade documentation for more information.
@@ -1005,7 +1012,7 @@ Used to control which sites are allowed to bypass same origin policies and send
Environmental Security
----------------------
-It is beyond the scope of this guide to inform you on how to secure your application code and environments. However, please secure your database configuration, e.g. `config/database.yml`, and your server-side secret, e.g. stored in `config/initializers/secret_token.rb`. You may want to further restrict access, using environment-specific versions of these files and any others that may contain sensitive information.
+It is beyond the scope of this guide to inform you on how to secure your application code and environments. However, please secure your database configuration, e.g. `config/database.yml`, and your server-side secret, e.g. stored in `config/secrets.yml`. You may want to further restrict access, using environment-specific versions of these files and any others that may contain sensitive information.
Additional Resources
--------------------
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index da124e21a4..d58024df3d 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -111,6 +111,50 @@ in your application, you can add an initializer file with the following content:
This would transparently migrate your existing `Marshal`-serialized cookies into the
new `JSON`-based format.
+When using the `:json` or `:hybrid` serializer, you should beware that not all
+Ruby objects can be serialized as JSON. For example, `Date` and `Time` objects
+will be serialized as strings, and `Hash`es will have their keys stringified.
+
+```ruby
+class CookiesController < ApplicationController
+ def set_cookie
+ cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014
+ redirect_to action: 'read_cookie'
+ end
+
+ def read_cookie
+ cookies.encrypted[:expiration_date] # => "2014-03-20"
+ end
+end
+```
+
+It's advisable that you only store simple data (strings and numbers) in cookies.
+If you have to store complex objects, you would need to handle the conversion
+manually when reading the values on subsequent requests.
+
+If you use the cookie session store, this would apply to the `session` and
+`flash` hash as well.
+
+### Flash structure changes
+
+Flash message keys are
+[normalized to strings](https://github.com/rails/rails/commit/a668beffd64106a1e1fedb71cc25eaaa11baf0c1). They
+can still be accessed using either symbols or strings. Lopping through the flash
+will always yield string keys:
+
+```ruby
+flash["string"] = "a string"
+flash[:symbol] = "a symbol"
+
+# Rails < 4.1
+flash.keys # => ["string", :symbol]
+
+# Rails >= 4.1
+flash.keys # => ["string", "symbol"]
+```
+
+Make sure you are comparing Flash message keys against strings.
+
### Changes in JSON handling
There are a few major changes related to JSON handling in Rails 4.1.
diff --git a/guides/source/working_with_javascript_in_rails.md b/guides/source/working_with_javascript_in_rails.md
index a8695ec034..aba3c9ed61 100644
--- a/guides/source/working_with_javascript_in_rails.md
+++ b/guides/source/working_with_javascript_in_rails.md
@@ -111,7 +111,9 @@ paintIt = (element, backgroundColor, textColor) ->
element.style.color = textColor
$ ->
- $("a[data-background-color]").click ->
+ $("a[data-background-color]").click (e) ->
+ e.preventDefault()
+
backgroundColor = $(this).data("background-color")
textColor = $(this).data("text-color")
paintIt(this, backgroundColor, textColor)