繁体   English   中英

声明强参数中的值不能是数组或单一标量类型

[英]Declare that the value in strong params must NOT be an array or of a one scalar type

应用程序接受 GET 请求以索引产品并接受page参数(应该是整数)。

例如http://localhost/products?page=2

有没有办法确保它真的是 integer?

或者实际上问题是:有没有办法确保它不是数组?

例如http://localhost/products?page[]=2http://localhost/products?page[random_key]=2

这将导致代码某处出错。

现在,我知道有一种方法可以声明它应该是一个数组或一个 json:

要声明 params 中的值必须是允许标量值的数组,map 是空数组的键:

params.permit(id: [])

我能想到的最简单的方法就是直接测试它是否不是数组:

run_the_code unless params[:page].is_a?(Array)
# or
run_the_code if params[:page].is_a?(Integer)

但是没有更简单的方法来使用 ActionParameters API 吗?

例如

params.permit(page: :integer)

强参数 API 实际上只设计用于做一件事——将参数切分到白名单,以避免恶意用户设法分配他们不应该分配的属性的大规模分配漏洞。 它不关心验证参数的存在或类型。 那不是它的工作。

如果您只使用.permit(:page) ,则不必担心它是一个数组,因为允许的标量类型不包括哈希或 arrays。但这实际上更多地用于防止 setter 方法可以接受的漏洞利用a hash 然后验证参数的类型。

还有一个小事实,即表单数据对(在查询和请求正文中)都没有类型化——它只是字符串,实际上只是将参数转换为预期类型的后端。 params[:page].is_a?(Integer)因此将始终为假。 除了解析哈希和 arrays Rack 实际上没有任何内置类型提示,例如?page(i)=2就像您在某些框架中会发现的那样。

通常在 Rails 中,model 处理用户输入的类型转换并提供验证。

# this is ridiculously overkill
class Paginator
  include ActiveModel::Model
  include ActiveModel::Attributes
  attribute :page, :integer
  attribute :per_page, :integer
  validates :page, numericality: { only_integer: true }
  validates :per_page, numericality: { only_integer: true }

  def to_query
    attributes.symbolize_keys.compact_blank
  end
end
paginator = Paginator.new(params.permit(:page, :per_page))
if paginator.valid?
  Othermodel.paginate(**paginator.to_query)
end

然而,有些 gem 提供替代方法,例如干式验证,或者您可以简单地编写一个方法,如果不能将参数强制转换为非零值 integer 则拒绝该参数。

private 

def page
  params.permit(:page).to_i.then{ |n| n.zero? ? nil : n }
end 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM