Rails Rails 4 - Strong parameters 使用经验

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

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

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.

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