![](/img/trans.png)
[英]action controller strong params with value that can be either scalar OR array?
[英]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[]=2
或http://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.