aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/4_0_release_notes.md10
-rw-r--r--guides/source/action_controller_overview.md4
-rw-r--r--guides/source/action_mailer_basics.md1
-rw-r--r--guides/source/active_record_querying.md3
-rw-r--r--guides/source/active_record_validations_callbacks.md19
-rw-r--r--guides/source/asset_pipeline.md2
-rw-r--r--guides/source/command_line.md20
-rw-r--r--guides/source/debugging_rails_applications.md60
-rw-r--r--guides/source/documents.yaml4
-rw-r--r--guides/source/i18n.md6
-rw-r--r--guides/source/layout.html.erb52
-rw-r--r--guides/source/migrations.md2
-rw-r--r--guides/source/performance_testing.md3
-rw-r--r--guides/source/routing.md12
-rw-r--r--guides/source/security.md137
-rw-r--r--guides/source/upgrading_ruby_on_rails.md23
16 files changed, 201 insertions, 157 deletions
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index c3921ea541..cce5bc5331 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -538,7 +538,7 @@ Active Record
* `mysql` and `mysql2` connections will set `SQL_MODE=STRICT_ALL_TABLES` by default to avoid silent data loss. This can be disabled by specifying `strict: false` in `config/database.yml`.
-* Added default order to `ActiveRecord::Base#first` to assure consistent results among diferent database engines. Introduced `ActiveRecord::Base#take` as a replacement to the old behavior.
+* Added default order to `ActiveRecord::Base#first` to assure consistent results among different database engines. Introduced `ActiveRecord::Base#take` as a replacement to the old behavior.
* Added an `:index` option to automatically create indexes for `references` and `belongs_to` statements in migrations. This can be either a boolean or a hash that is identical to options available to the `add_index` method:
@@ -652,6 +652,14 @@ Active Record
* PostgreSQL hstore types are automatically deserialized from the database.
+* Added `#update_columns` method which updates the attributes from the passed-in hash without calling save, hence skipping validations and callbacks. `ActiveRecordError` will be raised when called on new objects or when at least one of the attributes is marked as read only.
+
+ ```ruby
+ post.attributes # => {"id"=>2, "title"=>"My title", "body"=>"My content", "author"=>"Peter"}
+ post.update_columns({title: 'New title', author: 'Sebastian'}) # => true
+ post.attributes # => {"id"=>2, "title"=>"New title", "body"=>"My content", "author"=>"Sebastian"}
+ ```
+
### Deprecations
* Deprecated most of the 'dynamic finder' methods. All dynamic methods except for `find_by_...` and `find_by_...!` are deprecated. Here's how you can rewrite the code:
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index e6a6b05166..824ffb5d7a 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -174,8 +174,8 @@ Your application has a session for each user in which you can store small amount
* ActionDispatch::Session::CookieStore - Stores everything on the client.
* ActionDispatch::Session::CacheStore - Stores the data in the Rails cache.
-* ActionDispatch::Session::ActiveRecordStore - Stores the data in a database using Active Record. (require `activerecord-session_store` gem).
-* ActionDispatch::Session::MemCacheStore - Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).
+* @ActionDispatch::Session::ActiveRecordStore@ - Stores the data in a database using Active Record. (require `activerecord-session_store` gem).
+* @ActionDispatch::Session::MemCacheStore@ - Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).
All session stores use a cookie to store a unique ID for each session (you must use a cookie, Rails will not allow you to pass the session ID in the URL as this is less secure).
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index de5c15fe54..5e731d0a18 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -482,7 +482,6 @@ The following configuration options are best made in one of the environment file
|`deliveries`|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.|
|`default_options`|Allows you to set default values for the `mail` method options (`:from`, `:reply_to`, etc.).|
|`async`|Setting this flag will turn on asynchronous message sending, message rendering and delivery will be pushed to `Rails.queue` for processing.|
-|`default_options`|Allows you to set default values for the `mail` method options (`:from`, `:reply_to`, etc.).|
### Example Action Mailer Configuration
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 2fb0bf1d69..1ae6a1f204 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -68,7 +68,6 @@ The methods are:
* `none`
* `offset`
* `order`
-* `none`
* `preload`
* `readonly`
* `references`
@@ -547,8 +546,6 @@ By default, `Model.find` selects all the fields from the result set using `selec
To select only a subset of fields from the result set, you can specify the subset via the `select` method.
-NOTE: If the `select` method is used, all the returning objects will be [read only](#readonly-objects).
-
For example, to select only `viewable_by` and `locked` columns:
```ruby
diff --git a/guides/source/active_record_validations_callbacks.md b/guides/source/active_record_validations_callbacks.md
index e5957d8acb..f32c1050ce 100644
--- a/guides/source/active_record_validations_callbacks.md
+++ b/guides/source/active_record_validations_callbacks.md
@@ -995,6 +995,25 @@ class User < ActiveRecord::Base
end
```
+Callbacks can also be registered to only fire on certain lifecycle events:
+<ruby>
+class User < ActiveRecord::Base
+ before_validation :normalize_name, :on => :create
+
+ # :on takes an array as well
+ after_validation :set_location, :on => [ :create, :update ]
+
+ protected
+ def normalize_name
+ self.name = self.name.downcase.titleize
+ end
+
+ def set_location
+ self.location = LocationService.query(self)
+ end
+end
+</ruby>
+
It is considered good practice to declare callback methods as protected or private. If left public, they can be called from outside of the model and violate the principle of object encapsulation.
Available Callbacks
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index be7ca5107d..fc0092a93e 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -42,7 +42,7 @@ The first feature of the pipeline is to concatenate assets. This is important in
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..
+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.
The second feature of the asset pipeline is asset minification or compression. For CSS files, this is done by removing whitespace and comments. For JavaScript, more complex processes can be applied. You can choose from a set of built in options or specify your own.
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index b66b30a117..22645babfe 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -480,15 +480,9 @@ The `tmp:` namespaced tasks will help you clear the `Rails.root/tmp` directory:
* `rake secret` will give you a pseudo-random key to use for your session secret.
* `rake time:zones:all` lists all the timezones Rails knows about.
-### Writing Rake Tasks
+### Custom Rake Tasks
-If you have (or want to write) any automation scripts outside your app (data import, checks, etc), you can make them as rake tasks. It's easy.
-
-INFO: [Complete guide about how to write tasks](http://rake.rubyforge.org/files/doc/rakefile_rdoc.html) is available in the official documentation.
-
-Tasks should be placed in `Rails.root/lib/tasks` and should have a `.rake` extension.
-
-Each task should be defined in next format (dependencies are optional):
+Custom rake tasks have a `.rake` extension and are placed in `Rails.root/lib/tasks`.
```ruby
desc "I am short, but comprehensive description for my cool task"
@@ -498,7 +492,7 @@ task :task_name => [:prerequisite_task, :another_task_we_depend_on] do
end
```
-If you need to pass parameters, you can use next format (both arguments and dependencies are optional):
+To pass arguments to your custom rake task:
```ruby
task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
@@ -509,7 +503,7 @@ end
You can group tasks by placing them in namespaces:
```ruby
-namespace :do
+namespace :db do
desc "This task does nothing"
task :nothing do
# Seriously, nothing
@@ -517,13 +511,13 @@ namespace :do
end
```
-You can see your tasks to be listed by `rake -T` command. And, according to the examples above, you can invoke them as follows:
+Invocation of the tasks will look like:
```bash
rake task_name
rake "task_name[value 1]" # entire argument string should be quoted
-rake do:nothing
-```
+rake db:nothing
+```
NOTE: If your need to interact with your application models, perform database queries and so on, your task should depend on the `environment` task, which will load your application code.
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 9f8a3d942c..a72f54a1b8 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -638,60 +638,7 @@ Debugging Memory Leaks
A Ruby application (on Rails or not), can leak memory - either in the Ruby code or at the C code level.
-In this section, you will learn how to find and fix such leaks by using tools such as BleakHouse and Valgrind.
-
-### BleakHouse
-
-[BleakHouse](https://github.com/evan/bleak_house/) is a library for finding memory leaks.
-
-If a Ruby object does not go out of scope, the Ruby Garbage Collector won't sweep it since it is referenced somewhere. Leaks like this can grow slowly and your application will consume more and more memory, gradually affecting the overall system performance. This tool will help you find leaks on the Ruby heap.
-
-To install it run:
-
-```bash
-$ gem install bleak_house
-```
-
-Then setup your application for profiling. Then add the following at the bottom of config/environment.rb:
-
-```ruby
-require 'bleak_house' if ENV['BLEAK_HOUSE']
-```
-
-Start a server instance with BleakHouse integration:
-
-```bash
-$ RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house rails server
-```
-
-Make sure to run a couple hundred requests to get better data samples, then press `CTRL-C`. The server will stop and Bleak House will produce a dumpfile in `/tmp`:
-
-```
-** BleakHouse: working...
-** BleakHouse: complete
-** Bleakhouse: run 'bleak /tmp/bleak.5979.0.dump' to analyze.
-```
-
-To analyze it, just run the listed command. The top 20 leakiest lines will be listed:
-
-```
- 191691 total objects
- Final heap size 191691 filled, 220961 free
- Displaying top 20 most common line/class pairs
- 89513 __null__:__null__:__node__
- 41438 __null__:__null__:String
- 2348 /opt/local//lib/ruby/site_ruby/1.8/rubygems/specification.rb:557:Array
- 1508 /opt/local//lib/ruby/gems/1.8/specifications/gettext-1.90.0.gemspec:14:String
- 1021 /opt/local//lib/ruby/gems/1.8/specifications/heel-0.2.0.gemspec:14:String
- 951 /opt/local//lib/ruby/site_ruby/1.8/rubygems/version.rb:111:String
- 935 /opt/local//lib/ruby/site_ruby/1.8/rubygems/specification.rb:557:String
- 834 /opt/local//lib/ruby/site_ruby/1.8/rubygems/version.rb:146:Array
- ...
-```
-
-This way you can find where your application is leaking memory and fix it.
-
-If [BleakHouse](https://github.com/evan/bleak_house/) doesn't report any heap growth but you still have memory growth, you might have a broken C extension, or real leak in the interpreter. In that case, try using Valgrind to investigate further.
+In this section, you will learn how to find and fix such leaks by using tool such as Valgrind.
### Valgrind
@@ -708,10 +655,8 @@ There are some Rails plugins to help you to find errors and debug your applicati
* [Footnotes](https://github.com/josevalim/rails-footnotes:) Every Rails page has footnotes that give request information and link back to your source via TextMate.
* [Query Trace](https://github.com/ntalbott/query_trace/tree/master:) Adds query origin tracing to your logs.
-* [Query Stats](https://github.com/dan-manges/query_stats/tree/master:) A Rails plugin to track database queries.
-* [Query Reviewer](http://code.google.com/p/query-reviewer/:) This rails plugin not only runs "EXPLAIN" before each of your select queries in development, but provides a small DIV in the rendered output of each page with the summary of warnings for each query that it analyzed.
+* [Query Reviewer](https://github.com/nesquena/query_reviewer:) This rails plugin not only runs "EXPLAIN" before each of your select queries in development, but provides a small DIV in the rendered output of each page with the summary of warnings for each query that it analyzed.
* [Exception Notifier](https://github.com/smartinez87/exception_notification/tree/master:) Provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application.
-* [Exception Logger](https://github.com/defunkt/exception_logger/tree/master:) Logs your Rails exceptions in the database and provides a funky web interface to manage them.
References
----------
@@ -726,4 +671,3 @@ References
* [Debugging with ruby-debug](http://bashdb.sourceforge.net/ruby-debug.html)
* [ruby-debug cheat sheet](http://cheat.errtheblog.com/s/rdebug/)
* [Ruby on Rails Wiki: How to Configure Logging](http://wiki.rubyonrails.org/rails/pages/HowtoConfigureLogging)
-* [Bleak House Documentation](http://blog.evanweaver.com/files/doc/fauna/bleak_house/)
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 2acdcca39c..0b22423798 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -146,6 +146,10 @@
work_in_progress: true
description: This guide helps in upgrading applications to latest Ruby on Rails versions.
-
+ name: Ruby on Rails 4.0 Release Notes
+ url: 4_0_release_notes.html
+ description: Release notes for Rails 4.0.
+ -
name: Ruby on Rails 3.2 Release Notes
url: 3_2_release_notes.html
description: Release notes for Rails 3.2.
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index f3360156cc..a3c6b514a4 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -816,7 +816,8 @@ So, for example, instead of the default error message `"can not be blank"` you c
#### Translations for the Active Record `error_messages_for` Helper
-If you are using the Active Record `error_messages_for` helper, you will want to add translations for it.
+If you are using the Active Record `error_messages_for` helper, you will want to add
+translations for it.
Rails ships with the following translations:
@@ -831,6 +832,9 @@ en:
body: "There were problems with the following fields:"
```
+NOTE: In order to use this helper, you need to install [DynamicForm](https://github.com/joelmoss/dynamic_form)
+gem by adding this line to your Gemfile: `gem 'dynamic_form'`.
+
### Overview of Other Built-In Methods that Provide I18n Support
Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. Here's a brief overview.
diff --git a/guides/source/layout.html.erb b/guides/source/layout.html.erb
index 0a8daf7ae5..397dd62638 100644
--- a/guides/source/layout.html.erb
+++ b/guides/source/layout.html.erb
@@ -4,9 +4,9 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width, initial-scale=1">
<title><%= yield(:page_title) || 'Ruby on Rails Guides' %></title>
-
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
@@ -25,24 +25,30 @@
<% end %>
<div id="topNav">
<div class="wrapper">
- <strong>More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
- <a href="http://rubyonrails.org/">Overview</a> |
- <a href="http://rubyonrails.org/download">Download</a> |
- <a href="http://rubyonrails.org/deploy">Deploy</a> |
- <a href="https://github.com/rails/rails">Code</a> |
- <a href="http://rubyonrails.org/screencasts">Screencasts</a> |
- <a href="http://rubyonrails.org/documentation">Documentation</a> |
- <a href="http://rubyonrails.org/ecosystem">Ecosystem</a> |
- <a href="http://rubyonrails.org/community">Community</a> |
- <a href="http://weblog.rubyonrails.org/">Blog</a>
+ <strong class="more-info-label">More at <a href="http://rubyonrails.org/">rubyonrails.org:</a> </strong>
+ <span class="red-button more-info-button">
+ More Ruby on Rails
+ </span>
+ <ul class="more-info-links s-hidden">
+ <li class="more-info"><a href="http://rubyonrails.org/">Overview</a></li>
+ <li class="more-info"><a href="http://rubyonrails.org/download">Download</a></li>
+ <li class="more-info"><a href="http://rubyonrails.org/deploy">Deploy</a></li>
+ <li class="more-info"><a href="https://github.com/rails/rails">Code</a></li>
+ <li class="more-info"><a href="http://rubyonrails.org/screencasts">Screencasts</a></li>
+ <li class="more-info"><a href="http://rubyonrails.org/documentation">Documentation</a></li>
+ <li class="more-info"><a href="http://rubyonrails.org/ecosystem">Ecosystem</a></li>
+ <li class="more-info"><a href="http://rubyonrails.org/community">Community</a></li>
+ <li class="more-info"><a href="http://weblog.rubyonrails.org/">Blog</a></li>
+ </ul>
</div>
</div>
<div id="header">
<div class="wrapper clearfix">
<h1><a href="index.html" title="Return to home page">Guides.rubyonrails.org</a></h1>
<ul class="nav">
- <li><a href="index.html">Home</a></li>
- <li class="index"><a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu">Guides Index</a>
+ <li><a class="nav-item" href="index.html">Home</a></li>
+ <li class="guides-index guides-index-large">
+ <a href="index.html" onclick="guideMenu(); return false;" id="guidesMenu" class="guides-index-item nav-item">Guides Index</a>
<div id="guides" class="clearfix" style="display: none;">
<hr />
<% ['L', 'R'].each do |position| %>
@@ -57,9 +63,22 @@
<% end %>
</div>
</li>
- <li><a href="contributing_to_ruby_on_rails.html">Contribute</a></li>
- <li><a href="credits.html">Credits</a></li>
+ <li><a class="nav-item" href="contributing_to_ruby_on_rails.html">Contribute</a></li>
+ <li><a class="nav-item" href="credits.html">Credits</a></li>
+ <li class="guides-index guides-index-small">
+ <select class="guides-index-item nav-item">
+ <option value="index.html">Guides Index</option>
+ <% docs_for_menu.each do |section| %>
+ <optgroup label="<%= section['name'] %>">
+ <% finished_documents(section['documents']).each do |document| %>
+ <option value="<%= document['url'] %>"><%= document['name'] %></option>
+ <% end %>
+ </optgroup>
+ <% end %>
+ </select>
+ </li>
</ul>
+ </div>
</div>
</div>
<hr class="hide" />
@@ -113,6 +132,8 @@
</div>
</div>
+ <script type="text/javascript" src="javascripts/jquery.min.js"></script>
+ <script type="text/javascript" src="javascripts/responsive-tables.js"></script>
<script type="text/javascript" src="javascripts/guides.js"></script>
<script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
@@ -121,6 +142,7 @@
<script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
<script type="text/javascript">
SyntaxHighlighter.all()
+ $(guidesIndex.bind);
</script>
</body>
</html>
diff --git a/guides/source/migrations.md b/guides/source/migrations.md
index ccbdffc9c7..705b65ee8b 100644
--- a/guides/source/migrations.md
+++ b/guides/source/migrations.md
@@ -330,7 +330,7 @@ end
As always, what has been generated for you is just a starting point. You can add
or remove from it as you see fit by editing the
-db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb file.
+@db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb@ file.
NOTE: The generated migration file for destructive migrations will still be
old-style using the `up` and `down` methods. This is because Rails needs to know
diff --git a/guides/source/performance_testing.md b/guides/source/performance_testing.md
index 528b9c35b3..f111ce610f 100644
--- a/guides/source/performance_testing.md
+++ b/guides/source/performance_testing.md
@@ -658,9 +658,8 @@ Useful Links
### Rails Plugins and Gems
* [Rails Analyzer](http://rails-analyzer.rubyforge.org)
-* [Palmist](http://www.flyingmachinestudios.com/programming/announcing-palmist)
* [Rails Footnotes](https://github.com/josevalim/rails-footnotes/tree/master)
-* [Query Reviewer](https://github.com/dsboulder/query_reviewer/tree/master)
+* [Query Reviewer](https://github.com/nesquena/query_reviewer)
* [MiniProfiler](http://www.miniprofiler.com)
### Generic Tools
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 27fd2a35c4..3acb7fa0e5 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -401,6 +401,18 @@ resources :photos do
end
```
+#### Adding Routes for Additional New Actions
+
+To add an alternate new action using the `:on` shortcut:
+
+```ruby
+resources :comments do
+ get 'preview', :on => :new
+end
+```
+
+This will enable Rails to recognize paths such as `/comments/new/preview` with GET, and route to the `preview` action of `CommentsController`. It will also create the `preview_new_comment_url` and `preview_new_comment_path` route helpers.
+
#### A Note of Caution
If you find yourself adding many extra actions to a resourceful route, it's time to stop and ask yourself whether you're disguising the presence of another resource.
diff --git a/guides/source/security.md b/guides/source/security.md
index 3a6a894695..0186386059 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -375,18 +375,25 @@ The common admin interface works like this: it's located at www.example.com/admi
Mass Assignment
---------------
-WARNING: _Without any precautions `Model.new(params[:model]`) allows attackers to set any database column's value._
+WARNING: _Without any precautions `Model.new(params[:model]`) allows attackers to set
+any database column's value._
-The mass-assignment feature may become a problem, as it allows an attacker to set any model's attributes by manipulating the hash passed to a model's `new()` method:
+The mass-assignment feature may become a problem, as it allows an attacker to set
+any model's attributes by manipulating the hash passed to a model's `new()` method:
```ruby
def signup
- params[:user] # => {:name => “ow3ned”, :admin => true}
+ params[:user] # => {:name=>"ow3ned", :admin=>true}
@user = User.new(params[:user])
end
```
-Mass-assignment saves you much work, because you don't have to set each value individually. Simply pass a hash to the `new` method, or `assign_attributes=` a hash value, to set the model's attributes to the values in the hash. The problem is that it is often used in conjunction with the parameters (params) hash available in the controller, which may be manipulated by an attacker. He may do so by changing the URL like this:
+Mass-assignment saves you much work, because you don't have to set each value
+individually. Simply pass a hash to the `new` method, or `assign_attributes=`
+a hash value, to set the model's attributes to the values in the hash. The
+problem is that it is often used in conjunction with the parameters (params)
+hash available in the controller, which may be manipulated by an attacker.
+He may do so by changing the URL like this:
```
http://www.example.com/user/signup?user[name]=ow3ned&user[admin]=1
@@ -395,12 +402,19 @@ http://www.example.com/user/signup?user[name]=ow3ned&user[admin]=1
This will set the following parameters in the controller:
```ruby
-params[:user] # => {:name => “ow3ned”, :admin => true}
+params[:user] # => {:name=>"ow3ned", :admin=>true}
```
-So if you create a new user using mass-assignment, it may be too easy to become an administrator.
+So if you create a new user using mass-assignment, it may be too easy to become
+an administrator.
-Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the `attributes=` method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3. The `accepts_nested_attributes_for` declaration provides us the ability to extend mass assignment to model associations (`has_many`, `has_one`, `has_and_belongs_to_many`). For example:
+Note that this vulnerability is not restricted to database columns. Any setter
+method, unless explicitly protected, is accessible via the `attributes=` method.
+In fact, this vulnerability is extended even further with the introduction of
+nested mass assignment (and nested object forms) in Rails 2.3. The
+`accepts_nested_attributes_for` declaration provides us the ability to extend
+mass assignment to model associations (`has_many`, `has_one`,
+`has_and_belongs_to_many`). For example:
```ruby
class Person < ActiveRecord::Base
@@ -414,77 +428,84 @@ Note that this vulnerability is not restricted to database columns. Any setter m
end
```
-As a result, the vulnerability is extended beyond simply exposing column assignment, allowing attackers the ability to create entirely new records in referenced tables (children in this case).
+As a result, the vulnerability is extended beyond simply exposing column
+assignment, allowing attackers the ability to create entirely new records
+in referenced tables (children in this case).
### Countermeasures
-To avoid this, Rails provides two class methods in your Active Record class to control access to your attributes. The `attr_protected` method takes a list of attributes that will not be accessible for mass-assignment. For example:
+To avoid this, Rails provides an interface for protecting attributes from
+end-user assignment called Strong Parameters. This makes Action Controller
+parameters forbidden until they have been whitelisted, so you will have to
+make a conscious choice about which attributes to allow for mass assignment
+and thus prevent accidentally exposing that which shouldn’t be exposed.
-```ruby
-attr_protected :admin
-```
-
-`attr_protected` also optionally takes a role option using :as which allows you to define multiple mass-assignment groupings. If no role is defined then attributes will be added to the :default role.
+NOTE. Before Strong Parameters arrived, mass-assignment protection was a
+model's task provided by Active Model. This has been extracted to the
+[ProtectedAttributes](https://github.com/rails/protected_attributes)
+gem. In order to use `attr_accessible` and `attr_protected` helpers in
+your models, you should add `protected_attributes` to your Gemfile.
-```ruby
-attr_protected :last_login, :as => :admin
-```
+Why we moved mass-assignment protection out of the model and into
+the controller? The whole point of the controller is to control the
+flow between user and application, including authentication, authorization,
+and, as part of that, access control.
-A much better way, because it follows the whitelist-principle, is the `attr_accessible` method. It is the exact opposite of `attr_protected`, because _it takes a list of attributes that will be accessible_. All other attributes will be protected. This way you won't forget to protect attributes when adding new ones in the course of development. Here is an example:
+Strong Parameters provides two methods to the `params` hash to control
+access to your attributes: `require` and `permit`. The former is used
+to mark parameters as required and the latter limits which attributes
+should be allowed for mass updating using the slice pattern. For example:
```ruby
-attr_accessible :name
-attr_accessible :name, :is_admin, :as => :admin
-```
-
-If you want to set a protected attribute, you will to have to assign it individually:
+def signup
+ params[:user]
+ # => {:name=>"ow3ned", :admin=>true}
+ permitted_params = params.require(:user).permit(:name)
+ # => {:name=>"ow3ned"}
-```ruby
-params[:user] # => {:name => "ow3ned", :admin => true}
-@user = User.new(params[:user])
-@user.admin # => false # not mass-assigned
-@user.admin = true
-@user.admin # => true
+ @user = User.new(permitted_params)
+end
```
-When assigning attributes in Active Record using `attributes=` the :default role will be used. To assign attributes using different roles you should use `assign_attributes` which accepts an optional :as options parameter. If no :as option is provided then the :default role will be used. You can also bypass mass-assignment security by using the `:without_protection` option. Here is an example:
+In the example above, `require` is checking whether a `user` key is present or not
+in the parameters, if it's not present, it'll raise an `ActionController::MissingParameter`
+exception, which will be caught by `ActionController::Base` and turned into a
+400 Bad Request reply. Then `permit` whitelists the attributes that should be
+allowed for mass assignment.
-```ruby
-@user = User.new
+A good pattern to encapsulate the permissible parameters is to use a private method
+since you'll be able to reuse the same permit list between different actions.
-@user.assign_attributes({ :name => 'Josh', :is_admin => true })
-@user.name # => Josh
-@user.is_admin # => false
+```ruby
+def signup
+ @user = User.new(user_params)
+ # ...
+end
-@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :as => :admin)
-@user.name # => Josh
-@user.is_admin # => true
+def update
+ @user = User.find(params[:id]
+ @user.update_attributes!(user_params)
+ # ...
+end
-@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
-@user.name # => Josh
-@user.is_admin # => true
+private
+ def user_params
+ params.require(:user).permit(:name)
+ end
```
-In a similar way, `new`, `create`, `create!`, `update_attributes`, and `update_attributes!` methods all respect mass-assignment security and accept either `:as` or `:without_protection` options. For example:
+Also, you can specialize this method with per-user checking of permissible
+attributes.
```ruby
-@user = User.new({ :name => 'Sebastian', :is_admin => true }, :as => :admin)
-@user.name # => Sebastian
-@user.is_admin # => true
+def user_params
+ filters = [:name]
+ filters << :admin if current_user.try(:admin?)
-@user = User.create({ :name => 'Sebastian', :is_admin => true }, :without_protection => true)
-@user.name # => Sebastian
-@user.is_admin # => true
-```
-
-A more paranoid technique to protect your whole project would be to enforce that all models define their accessible attributes. This can be easily achieved with a very simple application config option of:
-
-```ruby
-config.active_record.whitelist_attributes = true
+ params.require(:user).permit(*filters)
+end
```
-This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an `attr_accessible` or `attr_protected` declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via `attr_accessible` or `attr_protected`) as dictated by your failing tests.
-
User Management
---------------
@@ -669,7 +690,7 @@ A blacklist can be a list of bad e-mail addresses, non-public actions or bad HTM
* Allow &lt;strong&gt; instead of removing &lt;script&gt; against Cross-Site Scripting (XSS). See below for details.
* Don't try to correct user input by blacklists:
* This will make the attack work: "&lt;sc&lt;script&gt;ript&gt;".gsub("&lt;script&gt;", "")
- * But reject malformed input
+ * But reject malformed input
Whitelists are also a good approach against the human factor of forgetting something in the blacklist.
@@ -1059,7 +1080,7 @@ config.action_dispatch.default_headers.clear
Here is the list of common headers:
* X-Frame-Options
-_'SAMEORIGIN' in Rails by default_ - allow framing on same domain. Set it to 'DENY' to deny framing at all or 'ALLOWALL' if you want to allow framing for all website.
+_'SAMEORIGIN' in Rails by default_ - allow framing on same domain. Set it to 'DENY' to deny framing at all or 'ALLOWALL' if you want to allow framing for all website.
* X-XSS-Protection
_'1; mode=block' in Rails by default_ - use XSS Auditor and block page if XSS attack is detected. Set it to '0;' if you want to switch XSS Auditor off(useful if response contents scripts from request parameters)
* X-Content-Type-Options
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 1eb8ff2f59..0ae0e30ab7 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -51,10 +51,31 @@ Rails 4.0 has changed `serialized_attributes` and `attr_readonly` to class metho
### Active Model
-Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`. Now when confirmation validations fail the error will be attached to `:#{attribute}_confirmation` instead of `attribute`.
+Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`.
+Now when confirmation validations fail the error will be attached to
+`:#{attribute}_confirmation` instead of `attribute`.
+
+Rails 4.0 has changed `ActiveModel::Serializers::JSON.include_root_in_json` default
+value to `false`. Now, Active Model Serializers and Active Record objects have the
+same default behaviour. This means that you can comment or remove the following option
+in the `config/initializers/wrap_parameters.rb` file:
+
+```ruby
+# Disable root element in JSON by default.
+# ActiveSupport.on_load(:active_record) do
+# self.include_root_in_json = false
+# end
+```
### Action Pack
+Rails 4.0 has deprecated `ActionController::Base.page_cache_extension` option. Use
+`ActionController::Base.default_static_extension` instead.
+
+Rails 4.0 has removed Action and Page caching from ActionPack. You will need to
+add the `actionpack-action_caching` gem in order to use `caches_action` and
+the `actionpack-page_caching` to use `caches_pages` in your controllers.
+
Rails 4.0 changed how `assert_generates`, `assert_recognizes`, and `assert_routing` work. Now all these assertions raise `Assertion` instead of `ActionController::RoutingError`.
Rails 4.0 also changed the way unicode character routes are drawn. Now you can draw unicode character routes directly. If you already draw such routes, you must change them, for example: