aboutsummaryrefslogtreecommitdiffstats
path: root/guides
diff options
context:
space:
mode:
Diffstat (limited to 'guides')
-rw-r--r--guides/rails_guides/generator.rb2
-rw-r--r--guides/rails_guides/helpers.rb2
-rw-r--r--guides/source/action_view_overview.md2
-rw-r--r--guides/source/active_job_basics.md17
-rw-r--r--guides/source/active_model_basics.md14
-rw-r--r--guides/source/active_record_migrations.md2
-rw-r--r--guides/source/active_record_postgresql.md54
-rw-r--r--guides/source/active_support_core_extensions.md2
-rw-r--r--guides/source/api_app.md1
-rw-r--r--guides/source/command_line.md2
-rw-r--r--guides/source/configuring.md2
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md4
-rw-r--r--guides/source/engines.md2
-rw-r--r--guides/source/form_helpers.md21
-rw-r--r--guides/source/i18n.md2
-rw-r--r--guides/source/layouts_and_rendering.md4
-rw-r--r--guides/source/rails_on_rack.md1
-rw-r--r--guides/source/routing.md4
-rw-r--r--guides/source/security.md19
19 files changed, 99 insertions, 58 deletions
diff --git a/guides/rails_guides/generator.rb b/guides/rails_guides/generator.rb
index 43f6f7eecf..b7a94f144c 100644
--- a/guides/rails_guides/generator.rb
+++ b/guides/rails_guides/generator.rb
@@ -194,7 +194,7 @@ module RailsGuides
layout = kindle? ? 'kindle/layout' : 'layout'
File.open(output_path, 'w') do |f|
- view = ActionView::Base.new(source_dir, :edge => @edge, :version => @version, :mobi => "kindle/#{mobi}")
+ view = ActionView::Base.new(source_dir, :edge => @edge, :version => @version, :mobi => "kindle/#{mobi}", :lang => @lang)
view.extend(Helpers)
if guide =~ /\.(\w+)\.erb$/
diff --git a/guides/rails_guides/helpers.rb b/guides/rails_guides/helpers.rb
index a78c2e9fca..5bf73da16c 100644
--- a/guides/rails_guides/helpers.rb
+++ b/guides/rails_guides/helpers.rb
@@ -15,7 +15,7 @@ module RailsGuides
end
def documents_by_section
- @documents_by_section ||= YAML.load_file(File.expand_path('../../source/documents.yaml', __FILE__))
+ @documents_by_section ||= YAML.load_file(File.expand_path("../../source/#{@lang ? @lang + '/' : ''}documents.yaml", __FILE__))
end
def documents_flat
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index 76454e77c7..4b0e9bff7c 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -1247,7 +1247,7 @@ file_field_tag 'attachment'
#### form_tag
-Starts a form tag that points the action to an url configured with `url_for_options` just like `ActionController::Base#url_for`.
+Starts a form tag that points the action to a url configured with `url_for_options` just like `ActionController::Base#url_for`.
```html+erb
<%= form_tag '/articles' do %>
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index e3502d7363..a114686f0f 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -136,10 +136,19 @@ module YourApp
end
```
-NOTE: Since jobs run in parallel to your Rails application, most queuing libraries
+### Starting the Backend
+
+Since jobs run in parallel to your Rails application, most queuing libraries
require that you start a library-specific queuing service (in addition to
-starting your Rails app) for the job processing to work. For information on
-how to do that refer to the documentation of your respective library.
+starting your Rails app) for the job processing to work. Refer to library
+documentation for instructions on starting your queue backend.
+
+Here is a noncomprehensive list of documentation:
+
+- [Sidekiq](https://github.com/mperham/sidekiq/wiki/Active-Job)
+- [Resque](https://github.com/resque/resque/wiki/ActiveJob)
+- [Sucker Punch](https://github.com/brandonhilkert/sucker_punch#active-job)
+- [Queue Classic](https://github.com/QueueClassic/queue_classic#active-job)
Queues
------
@@ -296,7 +305,7 @@ emails asynchronously:
```ruby
I18n.locale = :eo
-UserMailer.welcome(@user).deliver_later # Email will be localized to Esparanto.
+UserMailer.welcome(@user).deliver_later # Email will be localized to Esperanto.
```
diff --git a/guides/source/active_model_basics.md b/guides/source/active_model_basics.md
index 2bdbd792a8..fe2501bd87 100644
--- a/guides/source/active_model_basics.md
+++ b/guides/source/active_model_basics.md
@@ -197,7 +197,7 @@ person.last_name_change # => nil
### Validations
-`ActiveModel::Validations` module adds the ability to validate class objects
+The `ActiveModel::Validations` module adds the ability to validate class objects
like in Active Record.
```ruby
@@ -292,7 +292,7 @@ objects.
### Serialization
-`ActiveModel::Serialization` provides a basic serialization for your object.
+`ActiveModel::Serialization` provides basic serialization for your object.
You need to declare an attributes hash which contains the attributes you want to
serialize. Attributes must be strings, not symbols.
@@ -339,7 +339,7 @@ class Person
end
```
-With the `as_json` you have a hash representing the model.
+With the `as_json` method you have a hash representing the model.
```ruby
person = Person.new
@@ -408,7 +408,7 @@ Person.human_attribute_name('name') # => "Nome"
### Lint Tests
-`ActiveModel::Lint::Tests` allow you to test whether an object is compliant with
+`ActiveModel::Lint::Tests` allows you to test whether an object is compliant with
the Active Model API.
* app/models/person.rb
@@ -461,14 +461,14 @@ an accessor named `password` with certain validations on it.
#### Requirements
-`ActiveModel::SecurePassword` depends on the [`bcrypt`](https://github.com/codahale/bcrypt-ruby 'BCrypt'),
+`ActiveModel::SecurePassword` depends on [`bcrypt`](https://github.com/codahale/bcrypt-ruby 'BCrypt'),
so include this gem in your Gemfile to use `ActiveModel::SecurePassword` correctly.
In order to make this work, the model must have an accessor named `password_digest`.
The `has_secure_password` will add the following validations on the `password` accessor:
1. Password should be present.
2. Password should be equal to its confirmation.
-3. This maximum length of a password is 72 (required by `bcrypt` on which ActiveModel::SecurePassword depends)
+3. The maximum length of a password is 72 (required by `bcrypt` on which ActiveModel::SecurePassword depends)
#### Examples
@@ -489,7 +489,7 @@ person.password = 'aditya'
person.password_confirmation = 'nomatch'
person.valid? # => false
-# When the length of password, exceeds 72.
+# When the length of password exceeds 72.
person.password = person.password_confirmation = 'a' * 100
person.valid? # => false
diff --git a/guides/source/active_record_migrations.md b/guides/source/active_record_migrations.md
index c5ac70143d..67881e6087 100644
--- a/guides/source/active_record_migrations.md
+++ b/guides/source/active_record_migrations.md
@@ -789,7 +789,7 @@ The `rake db:reset` task will drop the database and set it up again. This is
functionally equivalent to `rake db:drop db:setup`.
NOTE: This is not the same as running all the migrations. It will only use the
-contents of the current `schema.rb` file. If a migration can't be rolled back,
+contents of the current `db/schema.rb` or `db/structure.sql` file. If a migration can't be rolled back,
`rake db:reset` may not help you. To find out more about dumping the schema see
[Schema Dumping and You](#schema-dumping-and-you) section.
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index 9d495dfacb..742db7be32 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -85,7 +85,7 @@ Book.where("array_length(ratings, 1) >= 3")
* [type definition](http://www.postgresql.org/docs/current/static/hstore.html)
-NOTE: you need to enable the `hstore` extension to use hstore.
+NOTE: You need to enable the `hstore` extension to use hstore.
```ruby
# db/migrate/20131009135255_create_profiles.rb
@@ -220,11 +220,22 @@ normal text columns:
```ruby
# db/migrate/20131220144913_create_articles.rb
-execute <<-SQL
- CREATE TYPE article_status AS ENUM ('draft', 'published');
-SQL
-create_table :articles do |t|
- t.column :status, :article_status
+def up
+ execute <<-SQL
+ CREATE TYPE article_status AS ENUM ('draft', 'published');
+ SQL
+ create_table :articles do |t|
+ t.column :status, :article_status
+ end
+end
+
+# NOTE: It's important to drop table before dropping enum.
+def down
+ drop_table :articles
+
+ execute <<-SQL
+ DROP TYPE article_status;
+ SQL
end
# app/models/article.rb
@@ -240,13 +251,40 @@ article.status = "published"
article.save!
```
+To add a new value before/after existing one you should use [ALTER TYPE](http://www.postgresql.org/docs/current/static/sql-altertype.html):
+
+```ruby
+# db/migrate/20150720144913_add_new_state_to_articles.rb
+# NOTE: ALTER TYPE ... ADD VALUE cannot be executed inside of a transaction block so here we are using disable_ddl_transaction!
+disable_ddl_transaction!
+
+def up
+ execute <<-SQL
+ ALTER TYPE article_status ADD VALUE IF NOT EXISTS 'archived' AFTER 'published';
+ SQL
+end
+```
+
+NOTE: ENUM values can't be dropped currently. You can read why [here](http://www.postgresql.org/message-id/29F36C7C98AB09499B1A209D48EAA615B7653DBC8A@mail2a.alliedtesting.com).
+
+Hint: to show all the values of the all enums you have, you should call this query in `bin/rails db` or `psql` console:
+
+```sql
+SELECT n.nspname AS enum_schema,
+ t.typname AS enum_name,
+ e.enumlabel AS enum_value
+ FROM pg_type t
+ JOIN pg_enum e ON t.oid = e.enumtypid
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
+```
+
### UUID
* [type definition](http://www.postgresql.org/docs/current/static/datatype-uuid.html)
* [pgcrypto generator function](http://www.postgresql.org/docs/current/static/pgcrypto.html#AEN159361)
* [uuid-ossp generator functions](http://www.postgresql.org/docs/current/static/uuid-ossp.html)
-NOTE: you need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
+NOTE: You need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
extension to use uuid.
```ruby
@@ -361,7 +399,7 @@ A point is casted to an array containing `x` and `y` coordinates.
UUID Primary Keys
-----------------
-NOTE: you need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
+NOTE: You need to enable the `pgcrypto` (only PostgreSQL >= 9.4) or `uuid-ossp`
extension to generate random UUIDs.
```ruby
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 367a1bf7c0..5a68f6c869 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -172,7 +172,7 @@ NOTE: Defined in `active_support/core_ext/object/duplicable.rb`.
### `deep_dup`
-The `deep_dup` method returns deep copy of a given object. Normally, when you `dup` an object that contains other objects, Ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
+The `deep_dup` method returns a deep copy of a given object. Normally, when you `dup` an object that contains other objects, Ruby does not `dup` them, so it creates a shallow copy of the object. If you have an array with a string, for example, it will look like this:
```ruby
array = ['string']
diff --git a/guides/source/api_app.md b/guides/source/api_app.md
index eb762612ee..feaaff166a 100644
--- a/guides/source/api_app.md
+++ b/guides/source/api_app.md
@@ -188,6 +188,7 @@ An API application comes with the following middlewares by default:
- `ActiveSupport::Cache::Strategy::LocalCache::Middleware`
- `ActionDispatch::RequestId`
- `Rails::Rack::Logger`
+- `Rack::Runtime`
- `ActionDispatch::ShowExceptions`
- `ActionDispatch::DebugExceptions`
- `ActionDispatch::RemoteIp`
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index cbfccce788..e85f9fc9c6 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -412,7 +412,7 @@ Ruby version 2.2.2 (x86_64-linux)
RubyGems version 2.4.6
Rack version 1.6
JavaScript Runtime Node.js (V8)
-Middleware Rack::Sendfile, ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
+Middleware Rack::Sendfile, ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
Application root /home/foobar/commandsapp
Environment development
Database adapter sqlite3
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index afdb0ba7eb..87114c4ef0 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -244,7 +244,7 @@ config.middleware.swap ActionController::Failsafe, Lifo::Failsafe
They can also be removed from the stack completely:
```ruby
-config.middleware.delete "Rack::MethodOverride"
+config.middleware.delete Rack::MethodOverride
```
### Configuring i18n
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 625299c113..6d689804a8 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -128,7 +128,7 @@ Contributing to the Rails Documentation
Ruby on Rails has two main sets of documentation: the guides, which help you
learn about Ruby on Rails, and the API, which serves as a reference.
-You can help improve the Rails guides by making them more coherent, consistent or readable, adding missing information, correcting factual errors, fixing typos, or bringing it up to date with the latest edge Rails. To get involved in the translation of Rails guides, please see [Translating Rails Guides](https://wiki.github.com/rails/docrails/translating-rails-guides).
+You can help improve the Rails guides by making them more coherent, consistent or readable, adding missing information, correcting factual errors, fixing typos, or bringing them up to date with the latest edge Rails. To get involved in the translation of Rails guides, please see [Translating Rails Guides](https://wiki.github.com/rails/docrails/translating-rails-guides).
You can either open a pull request to [Rails](http://github.com/rails/rails) or
ask the [Rails core team](http://rubyonrails.org/core) for commit access on
@@ -318,7 +318,7 @@ $ cd activerecord
$ bundle exec rake test:sqlite3
```
-You can now run the tests as you did for `sqlite3`. The tasks are respectively
+You can now run the tests as you did for `sqlite3`. The tasks are respectively:
```bash
test:mysql
diff --git a/guides/source/engines.md b/guides/source/engines.md
index 71844b7990..f961b799f1 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -670,7 +670,7 @@ pre-defined path which may be customizable.
The engine contains migrations for the `blorgh_articles` and `blorgh_comments`
table which need to be created in the application's database so that the
engine's models can query them correctly. To copy these migrations into the
-application use this command:
+application run the following command from the `test/dummy` directory of your Rails engine:
```bash
$ rake blorgh:install:migrations
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index 84a8d695cb..0a6e2e5dba 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -40,7 +40,9 @@ When called without arguments like this, it creates a `<form>` tag which, when s
</form>
```
-You'll notice that the HTML contains `input` element with type `hidden`. This `input` is important, because the form cannot be successfully submitted without it. The hidden input element has name attribute of `utf8` enforces browsers to properly respect your form's character encoding and is generated for all forms whether their actions are "GET" or "POST". The second input element with name `authenticity_token` is a security feature of Rails called **cross-site request forgery protection**, and form helpers generate it for every non-GET form (provided that this security feature is enabled). You can read more about this in the [Security Guide](security.html#cross-site-request-forgery-csrf).
+You'll notice that the HTML contains an `input` element with type `hidden`. This `input` is important, because the form cannot be successfully submitted without it. The hidden input element with the name `utf8` enforces browsers to properly respect your form's character encoding and is generated for all forms whether their action is "GET" or "POST".
+
+The second input element with the name `authenticity_token` is a security feature of Rails called **cross-site request forgery protection**, and form helpers generate it for every non-GET form (provided that this security feature is enabled). You can read more about this in the [Security Guide](security.html#cross-site-request-forgery-csrf).
### A Generic Search Form
@@ -103,9 +105,9 @@ checkboxes, text fields, and radio buttons. These basic helpers, with names
ending in `_tag` (such as `text_field_tag` and `check_box_tag`), generate just a
single `<input>` element. The first parameter to these is always the name of the
input. When the form is submitted, the name will be passed along with the form
-data, and will make its way to the `params` hash in the controller with the
-value entered by the user for that field. For example, if the form contains `<%=
-text_field_tag(:query) %>`, then you would be able to get the value of this
+data, and will make its way to the `params` in the controller with the
+value entered by the user for that field. For example, if the form contains
+`<%= text_field_tag(:query) %>`, then you would be able to get the value of this
field in the controller with `params[:query]`.
When naming inputs, Rails uses certain conventions that make it possible to submit parameters with non-scalar values such as arrays or hashes, which will also be accessible in `params`. You can read more about them in [chapter 7 of this guide](#understanding-parameter-naming-conventions). For details on the precise usage of these helpers, please refer to the [API documentation](http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html).
@@ -212,7 +214,7 @@ month, week, URL, email, number and range inputs are HTML5 controls.
If you require your app to have a consistent experience in older browsers,
you will need an HTML5 polyfill (provided by CSS and/or JavaScript).
There is definitely [no shortage of solutions for this](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills), although a popular tool at the moment is
-[Modernizr](http://www.modernizr.com/), which provides a simple way to add functionality based on the presence of
+[Modernizr](https://modernizr.com/), which provides a simple way to add functionality based on the presence of
detected HTML5 features.
TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the [Security Guide](security.html#logging).
@@ -376,7 +378,7 @@ output:
</form>
```
-When parsing POSTed data, Rails will take into account the special `_method` parameter and acts as if the HTTP method was the one specified inside it ("PATCH" in this example).
+When parsing POSTed data, Rails will take into account the special `_method` parameter and act as if the HTTP method was the one specified inside it ("PATCH" in this example).
Making Select Boxes with Ease
-----------------------------
@@ -711,13 +713,6 @@ action for a Person model, `params[:person]` would usually be a hash of all the
Fundamentally HTML forms don't know about any sort of structured data, all they generate is name-value pairs, where pairs are just plain strings. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.
-TIP: You may find you can try out examples in this section faster by using the console to directly invoke Rack's parameter parser. For example,
-
-```ruby
-Rack::Utils.parse_query "name=fred&phone=0123456789"
-# => {"name"=>"fred", "phone"=>"0123456789"}
-```
-
### Basic Structures
The two basic structures are arrays and hashes. Hashes mirror the syntax used for accessing the value in `params`. For example, if a form contains:
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index ea79855919..87d2fafaf3 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -249,7 +249,7 @@ end
With this approach you will not get a `Routing Error` when accessing your resources such as `http://localhost:3001/books` without a locale. This is useful for when you want to use the default locale when one is not specified.
-Of course, you need to take special care of the root URL (usually "homepage" or "dashboard") of your application. An URL like `http://localhost:3001/nl` will not work automatically, because the `root to: "books#index"` declaration in your `routes.rb` doesn't take locale into account. (And rightly so: there's only one "root" URL.)
+Of course, you need to take special care of the root URL (usually "homepage" or "dashboard") of your application. A URL like `http://localhost:3001/nl` will not work automatically, because the `root to: "books#index"` declaration in your `routes.rb` doesn't take locale into account. (And rightly so: there's only one "root" URL.)
You would probably need to map URLs like these:
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index b425eb126a..71cc030f6a 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -280,7 +280,7 @@ render body: "raw"
```
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
+the response. Using `:plain` or `:html` might be more appropriate most of the
time.
NOTE: Unless overridden, your response returned from this render option will be
@@ -781,7 +781,7 @@ The `javascript_include_tag` helper returns an HTML `script` tag for each source
If you are using Rails with the [Asset Pipeline](asset_pipeline.html) enabled, this helper will generate a link to `/assets/javascripts/` rather than `public/javascripts` which was used in earlier versions of Rails. This link is then served by the asset pipeline.
-A JavaScript file within a Rails application or Rails engine goes in one of three locations: `app/assets`, `lib/assets` or `vendor/assets`. These locations are explained in detail in the [Asset Organization section in the Asset Pipeline Guide](asset_pipeline.html#asset-organization)
+A JavaScript file within a Rails application or Rails engine goes in one of three locations: `app/assets`, `lib/assets` or `vendor/assets`. These locations are explained in detail in the [Asset Organization section in the Asset Pipeline Guide](asset_pipeline.html#asset-organization).
You can specify a full path relative to the document root, or a URL, if you prefer. For example, to link to a JavaScript file that is inside a directory called `javascripts` inside of one of `app/assets`, `lib/assets` or `vendor/assets`, you would do this:
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index 1479e6f263..87f869aff3 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -106,6 +106,7 @@ use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000029a0838>
+use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 1fd38c0940..245689932b 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -79,7 +79,7 @@ it asks the router to map it to a controller action. If the first matching route
resources :photos
```
-Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: '17' }` in `params`.
+Rails would dispatch that request to the `destroy` action on the `photos` controller with `{ id: '17' }` in `params`.
### CRUD, Verbs, and Actions
@@ -1096,7 +1096,7 @@ Video.find_by(identifier: params[:identifier])
```
You can override `ActiveRecord::Base#to_param` of a related model to construct
-an URL:
+a URL:
```ruby
class Video < ActiveRecord::Base
diff --git a/guides/source/security.md b/guides/source/security.md
index 5a6ac9446a..fb9ee7b412 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -196,7 +196,7 @@ This attack method works by including malicious code or a link in a page that ac
![](images/csrf.png)
-In the [session chapter](#sessions) you have learned that most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash is on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is, that it will also send the cookie, if the request comes from a site of a different domain. Let's start with an example:
+In the [session chapter](#sessions) you have learned that most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash is on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is that if the request comes from a site of a different domain, it will also send the cookie. Let's start with an example:
* Bob browses a message board and views a post from a hacker where there is a crafted HTML image element. The element references a command in Bob's project management application, rather than an image file: `<img src="http://www.webapp.com/project/1/destroy">`
* Bob's session at `www.webapp.com` is still alive, because he didn't log out a few minutes ago.
@@ -224,9 +224,9 @@ The HTTP protocol basically provides two main types of requests - GET and POST (
* The interaction _changes the state_ of the resource in a way that the user would perceive (e.g., a subscription to a service), or
* The user is _held accountable for the results_ of the interaction.
-If your web application is RESTful, you might be used to additional HTTP verbs, such as PATCH, PUT or DELETE. Most of today's web browsers, however do not support them - only GET and POST. Rails uses a hidden `_method` field to handle this barrier.
+If your web application is RESTful, you might be used to additional HTTP verbs, such as PATCH, PUT or DELETE. Most of today's web browsers, however, do not support them - only GET and POST. Rails uses a hidden `_method` field to handle this barrier.
-_POST requests can be sent automatically, too_. Here is an example for a link which displays `www.harmless.com` as destination in the browser's status bar. In fact it dynamically creates a new form that sends a POST request.
+_POST requests can be sent automatically, too_. In this example, the link www.harmless.com is shown as the destination in the browser's status bar. But it has actually dynamically created a new form that sends a POST request.
```html
<a href="http://www.harmless.com/" onclick="
@@ -301,7 +301,7 @@ This will redirect the user to the main action if they tried to access a legacy
http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
```
-If it is at the end of the URL it will hardly be noticed and redirects the user to the attacker.com host. A simple countermeasure would be to _include only the expected parameters in a legacy action_ (again a whitelist approach, as opposed to removing unexpected parameters). _And if you redirect to an URL, check it with a whitelist or a regular expression_.
+If it is at the end of the URL it will hardly be noticed and redirects the user to the attacker.com host. A simple countermeasure would be to _include only the expected parameters in a legacy action_ (again a whitelist approach, as opposed to removing unexpected parameters). _And if you redirect to a URL, check it with a whitelist or a regular expression_.
#### Self-contained XSS
@@ -406,7 +406,7 @@ NOTE: _Almost every web application has to deal with authorization and authentic
There are a number of authentication plug-ins for Rails available. Good ones, such as the popular [devise](https://github.com/plataformatec/devise) and [authlogic](https://github.com/binarylogic/authlogic), store only encrypted passwords, not plain-text passwords. In Rails 3.1 you can use the built-in `has_secure_password` method which has similar features.
-Every new user gets an activation code to activate their account when they get an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested an URL like these, they would be logged in as the first activated user found in the database (and chances are that this is the administrator):
+Every new user gets an activation code to activate their account when they get an e-mail with a link in it. After activating the account, the activation_code columns will be set to NULL in the database. If someone requested a URL like these, they would be logged in as the first activated user found in the database (and chances are that this is the administrator):
```
http://localhost:3006/user/activate
@@ -793,15 +793,13 @@ Another proof-of-concept webmail worm is Nduja, a cross-domain worm for four Ita
In December 2006, 34,000 actual user names and passwords were stolen in a [MySpace phishing attack](http://news.netcraft.com/archives/2006/10/27/myspace_accounts_compromised_by_phishers.html). The idea of the attack was to create a profile page named "login_home_index_html", so the URL looked very convincing. Specially-crafted HTML and CSS was used to hide the genuine MySpace content from the page and instead display its own login form.
-The MySpace Samy worm will be discussed in the CSS Injection section.
-
### CSS Injection
INFO: _CSS Injection is actually JavaScript injection, because some browsers (IE, some versions of Safari and others) allow JavaScript in CSS. Think twice about allowing custom CSS in your web application._
-CSS Injection is explained best by a well-known worm, the [MySpace Samy worm](http://namb.la/popular/tech.html). This worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile. Within several hours he had over 1 million friend requests, but it creates too much traffic on MySpace, so that the site goes offline. The following is a technical explanation of the worm.
+CSS Injection is explained best by the well-known [MySpace Samy worm](http://namb.la/popular/tech.html). This worm automatically sent a friend request to Samy (the attacker) simply by visiting his profile. Within several hours he had over 1 million friend requests, which created so much traffic that MySpace went offline. The following is a technical explanation of that worm.
-MySpace blocks many tags, however it allows CSS. So the worm's author put JavaScript into CSS like this:
+MySpace blocked many tags, but allowed CSS. So the worm's author put JavaScript into CSS like this:
```html
<div style="background:url('javascript:alert(1)')">
@@ -825,7 +823,7 @@ The next problem was MySpace filtering the word "javascript", so the author used
<div id="mycode" expr="alert('hah!')" style="background:url('java↵
script:eval(document.all.mycode.expr)')">
```
-Another problem for the worm's author were CSRF security tokens. Without them he couldn't send a friend request over POST. He got around it by sending a GET to the page right before adding a user and parsing the result for the CSRF token.
+Another problem for the worm's author was the [CSRF security tokens](#cross-site-request-forgery-csrf). Without them he couldn't send a friend request over POST. He got around it by sending a GET to the page right before adding a user and parsing the result for the CSRF token.
In the end, he got a 4 KB worm, which he injected into his profile page.
@@ -1059,4 +1057,3 @@ The security landscape shifts and it is important to keep up to date, because mi
* Subscribe to the Rails security [mailing list](http://groups.google.com/group/rubyonrails-security)
* [Keep up to date on the other application layers](http://secunia.com/) (they have a weekly newsletter, too)
* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet)
-