mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
integrate the strong params README into the AC guide.
The current ActionController guide does not mention strong parameters at all. I integrated the README into the guide to explain the API. I also included a section to illustrate that the API does not solve all possible whitelisting scenarios. The origin was #9454.
This commit is contained in:
parent
8fe904b5ca
commit
fb63753031
1 changed files with 118 additions and 0 deletions
|
@ -6,6 +6,7 @@ In this guide you will learn how controllers work and how they fit into the requ
|
|||
After reading this guide, you will know:
|
||||
|
||||
* How to follow the flow of a request through a controller.
|
||||
* How to restrict parameters passed to your controller.
|
||||
* Why and how to store data in the session or cookies.
|
||||
* How to work with filters to execute code during request processing.
|
||||
* How to use Action Controller's built-in HTTP authentication.
|
||||
|
@ -170,6 +171,123 @@ These options will be used as a starting point when generating URLs, so it's pos
|
|||
|
||||
If you define `default_url_options` in `ApplicationController`, as in the example above, it would be used for all URL generation. The method can also be defined in one specific controller, in which case it only affects URLs generated there.
|
||||
|
||||
### Strong Parameters
|
||||
|
||||
With strong parameters Action Controller parameters are forbidden to
|
||||
be used in Active Model mass assignments until they have been
|
||||
whitelisted. This means you'll have to make a conscious choice about
|
||||
which attributes to allow for mass updating and thus prevent
|
||||
accidentally exposing that which shouldn't be exposed.
|
||||
|
||||
In addition, parameters can be marked as required and flow through a
|
||||
predefined raise/rescue flow to end up as a 400 Bad Request with no
|
||||
effort.
|
||||
|
||||
```ruby
|
||||
class PeopleController < ActionController::Base
|
||||
# This will raise an ActiveModel::ForbiddenAttributes exception
|
||||
# because it's using mass assignment without an explicit permit
|
||||
# step.
|
||||
def create
|
||||
Person.create(params[:person])
|
||||
end
|
||||
|
||||
# This will pass with flying colors as long as there's a person key
|
||||
# in the parameters, otherwise it'll raise a
|
||||
# ActionController::MissingParameter exception, which will get
|
||||
# caught by ActionController::Base and turned into that 400 Bad
|
||||
# Request reply.
|
||||
def update
|
||||
person = current_account.people.find(params[:id])
|
||||
person.update_attributes!(person_params)
|
||||
redirect_to person
|
||||
end
|
||||
|
||||
private
|
||||
# Using a private method to encapsulate the permissible parameters
|
||||
# is just a good pattern since you'll be able to reuse the same
|
||||
# permit list between create and update. Also, you can specialize
|
||||
# this method with per-user checking of permissible attributes.
|
||||
def person_params
|
||||
params.require(:person).permit(:name, :age)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### Permitted Scalar Values
|
||||
|
||||
Given
|
||||
|
||||
```ruby
|
||||
params.permit(:id)
|
||||
```
|
||||
|
||||
the key `:id` will pass the whitelisting if it appears in `params` and
|
||||
it has a permitted scalar value associated. Otherwise the key is going
|
||||
to be filtered out, so arrays, hashes, or any other objects cannot be
|
||||
injected.
|
||||
|
||||
The permitted scalar types are `String`, `Symbol`, `NilClass`,
|
||||
`Numeric`, `TrueClass`, `FalseClass`, `Date`, `Time`, `DateTime`,
|
||||
`StringIO`, `IO`, `ActionDispatch::Http::UploadedFile` and
|
||||
`Rack::Test::UploadedFile`.
|
||||
|
||||
To declare that the value in `params+ must be an array of permitted
|
||||
scalar values map the key to an empty array:
|
||||
|
||||
```ruby
|
||||
params.permit(:id => [])
|
||||
```
|
||||
|
||||
To whitelist an entire hash of parameters, the `permit!+ method can be
|
||||
used
|
||||
|
||||
```ruby
|
||||
params.require(:log_entry).permit!
|
||||
```
|
||||
|
||||
This will mark the `:log_entry` parameters hash and any subhash of it
|
||||
permitted. Extreme care should be taken when using `permit!` as it
|
||||
will allow all current and future model attributes to be
|
||||
mass-assigned.
|
||||
|
||||
#### Nested Parameters
|
||||
|
||||
You can also use permit on nested parameters, like:
|
||||
|
||||
```ruby
|
||||
params.permit(:name, {:emails => []},
|
||||
:friends => [ :name,
|
||||
{ :family => [ :name ], :hobbies => [] }])
|
||||
```
|
||||
|
||||
This declaration whitelists the `name`, `emails` and `friends`
|
||||
attributes. It is expected that `emails` will be an array of permitted
|
||||
scalar values and that `friends` will be an array of resources with
|
||||
specific attributes : they should have a `name` attribute (any
|
||||
permitted scalar values allowed), a `hobbies` attribute as an array of
|
||||
permitted scalar values, and a `family` attribute which is restricted
|
||||
to having a `name` (any permitted scalar values allowed, too).
|
||||
|
||||
#### Outside the Scope of Strong Parameters
|
||||
|
||||
The strong parameter API was designed with the most common use cases
|
||||
in mind. It is not meant as a silver bullet to handle all your
|
||||
whitelisting problems. However you can easily mix the API with your
|
||||
own code to adapt to your situation.
|
||||
|
||||
Imagine a situation where you want to whitelist an attribute
|
||||
containing a hash with any keys. Using strong parameters you can't
|
||||
allow a hash with any keys but you can use a simple assignment to get
|
||||
the job done:
|
||||
|
||||
```ruby
|
||||
def product_params
|
||||
params.require(:product).permit(:name).tap do |whitelisted|
|
||||
whitelisted[:data] = params[:product][:data]
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Session
|
||||
-------
|
||||
|
|
Loading…
Reference in a new issue