Rails Rails 4 - Strong parameters 使用经验

michael_roshen · 2014年11月17日 · 最后由 gazeldx 回复于 2019年06月25日 · 7624 次阅读

Strong parameters 原理简介

rails4 使用Strong Parameters机制,避免非法的参数进入到应用中

post_params  {:title => "post", :body => "post body"}
Post.create(post_params)

没有进行permit可以,也可以创建成功, debug发现使用params创建post的时候就会报错

@post = Post.create(params[:post])

ActiveModel::ForbiddenAttributesError

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

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

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

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

ActionController::Parameters提供了permitted?方法


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

def permitted?
    ...
end

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


{: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哪些属性对于创建一篇文章是允许的,

def create
  post_params params.require(:post).permit(:title, :body)
  @post = Post.new(post_params)
end
#文章的属性属性值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

嵌套属性

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

共收到 14 条回复

stong parameters? strong parameters?

#3楼 @badboy 看资料,原来是火星文大哥,哈哈

做api的时候,post 一个json data,strong parameters 没法收到参数了,这个是咋解决的?

#10楼 @naitnix set http header Content-Type: 'application/json'

#11楼 @matrixbirds 那post一个jsonapi呢?怎么解析参数?

如何找到 #5楼 @michael_roshen

sanitize_for_mass_assignment

这个方法?我rails5.0的api里面查找没有找到

This article is really good.

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册