rails4 - Stong parameters



## Stong parameters 原理简介
rails4 使用Strong Parameters机制,避免非法的参数进入到应用中

```ruby
    post_params = {:title => "post", :body => "post body"}
    Post.create(post_params)
```
没有进行permit可以,也可以创建成功, debug发现使用params创建post的时候就会报错

```ruby
    @post = Post.create(params[:post])
```
ActiveModel::ForbiddenAttributesError

那么这里需要注意的是: 使用hash 和 params创建对象的不同之处,原理是这样的

```ruby
    params.class
    => ActionController::Parameters
    params.class.ancestors
    => ActionController::Parameters, ActiveSupport::HashWithIndifferentAccess, Hash, ...
```

在创建ActiveRecord::Base对象的时候,rails会检查时候有permitted?方法,如果没有进行permit
则会抛出异常

```ruby
    def sanitize_for_mass_assignment(attributes)
        if attributes.respond_to?(:permitted?) && !attributes.permitted?
            raise ActiveModel::ForbiddenAttributesError
        else
            attributes
        end
    end
```

ActionController::Parameters提供了permitted?方法
```ruby

    {:title => "post", :body => "post body"}

    def permitted?
        ...
    end

```
普通Hash对象,则没有 permitted?方法
```ruby

    {:title => "post", :body => "post body"}

```
所以Strong parameters是通过params来严格控制传进来的参数的,而不是在模型层进行检验,
还是可以通过普通hash作为参数进行创建对象

当使用属性值hash来创建一个对象的时候,直接调用permit即可
但是如何使用permit来处理复杂的,甚至嵌套的属性值的,实践证明,可以使用一下这个规则来处理

To Permit a Hash, Pass an Array
To Permit an Array, Pass a Hash


## Stong parameters 的混乱, 分别来解释一下

##To Permit a Hash, Pass an Array

rails4需要我们将参数列入到白名单,或者经过我们的允许,才能传递到应用中,
这就是rails4比较重要的一个特性:Strong parameters
增强Controller层安全机制,有效的避免破坏性的,垃圾性的参数进入到应用中。


下面是它的简单应用,首先告诉rails哪些属性对于创建一篇文章是允许的,
```ruby
def create
  post_params =params.require(:post).permit(:title, :body)
  @post = Post.new(post_params)
end
```

```ruby
    #文章的属性属性值hash
     Hash: post_params = {:title => "post", :body => "post body"}
    #允许的参数值Array
    Array: params.permit([:title, :body])
```
可以看出,我们通过permit一个Array允许这个hash的参数进入到我们的应用中,
这就是To Permit a Hash, Pass an Array

## To Permit an Array, Pass a Hash
通过api传过来的json数据是这样的,我们如何来创建post对象呢

parsed_json = {
    :title => "post", :body => "post body",
    :comments => [
        {:content => "comment one"},
        {:content => "comment two"}       
    ]
}

params.require(:post).permit(:title, :body, :comments =>[:content])

Array:[{:content => "comment one"},{:content => "comment two"}]
 Hash: :comments =>[:content]
当我们要传递comments内容这个Array的时候, 我们需要在permit函数中指定Hash,
:comments =>[:content]
这就是To Permit an Array, Pass a Hash


## 嵌套属性

```ruby
    class Post < ActiveRecord::Base
        has_many :comments
        accepts_nested_attributes_for :comments
    end

    post_params = params.require(:post).permit(
        :title, :body,
        :comments_attributes => [:text, :id]
    )

    @post = Post.create(post_params)
```

## 原文
 http://patshaughnessy.net/2014/6/16/a-rule-of-thumb-for-strong-parameters

 

## 博文

 http://michael-roshen.iteye.com/blog/2157161

 

## 欢迎关注微信订阅号,ruby程序员

rails4 - Stong parameters
 


你可能感兴趣的:(parameter,stong)