ruby-on-rails - 使用带有嵌套原始 JSON 参数的强参数
问题描述
我的 Web 应用程序中有一个更新表单,但在允许我从该表单接收的参数时遇到了问题。这是参数到达控制器的方式:
<ActionController::Parameters {"company"=>{"description"=>"description",
"email_address"=>"contact@gmail.com",
"hours"=>"{\"fri\":[],\"mon\":[[\"09:00\",\"16:00\"]],\"sat\":[],
\"sun\":[[\"09:00\",\"16:00\"]],
\"thu\":[[\"09:00\",\"12:00\"], [\"13:00\",\"16:00\"]],
\"tue\":[[\"08:45\",\"16:00\"]],\"wed\":[[\"09:00\",\"16:00\"]]}"},
"controller"=>"my_controller", "action"=>"update"} permitted: false>
它们都以字符串的形式到达控制器,但 hours 被解析为 json(使用JSON.parse
),结果如下:
{"fri"=>[], "mon"=>[["09:00", "16:00"]], "sat"=>[], "sun"=>[["09:00", "16:00"]],
"thu"=>[["09:00", "12:00"], ["13:00", "16:00"]], "tue"=>[["08:45", "16:00"]],
"wed"=>[["09:00", "16:00"]]}
例如,营业时间代表商店的营业时间。它以星期几分开。并且每一天都可以没有一天的价值,只有一个或两个价值。解析小时后是数组的散列,这些数组可以是空的,也可以有一个或两个数组。
我的问题是在使用params.require(:company).permit()
. 我尝试了许多不同的方法,例如:
params.require(:company).permit(:description, : email_address, :hours)
params.require(:company).permit(:description, : email_address, hours: {})
params.require(:company).permit(:description, : email_address, hours: [])
params.require(:company).permit(:description, : email_address, hours: { [sun: [], mon: [], tue: [], wed: [], thu: [], fri: [], sat: [] })
params.require(:company).permit(:description, : email_address, hours: [ [sun: [], mon: [], tue: [], wed: [], thu: [], fri: [], sat: [] ])
- 和别的
但它失败或只是允许它没有任何内容,例如:
<ActionController::Parameters {"description"=>"description",
"email_address"=>"contact@gmail.com",
"hours"=><ActionController::Parameters {"sun"=>[], "mon"=>[], "tue"=>[],
"wed"=>[], "thu"=>[], "fri"=>[], "sat"=>[]} permitted: true>} permitted: true>
谢谢!
解决方案
据我所知, Rails 实际上没有将嵌套数组列入白名单的语法。
这个会:
params.require(:company)
.permit(:description, :email_address, hours: { mon: [] })
允许 中的任何标量值company[:hours][:mon]
。但是数组不是允许的标量类型之一:
[ String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile ]
这解释了为什么这些值被“丢弃”。我认为rails根本不知道该做什么permit(hours: { mon: [[]] })
。
但是,如果您只是修复传入的 JSON 或在 Ruby 中转换它,这很容易避免。
json = if params[:company][:hours].present?
# @todo handle JSON parsing errors
# use each_with_object instead if your Ruby is older than 2.4
JSON.parse(params[:company][:hours])
&.transform_values { |v| v.empty? ? v : v.first }
end
params.merge(
hours: json
).permit(
:description, :email_address,
hours: { sun: [], mon: [], tue: [], wed: [], thu: [], fri: [], sat: [] }
)
这是有效的,因为它转换"mon"=>[["09:00", "16:00"]]
为"mon"=>["09:00", "16:00"]
“09:00”、“16:00”是字符串,因此是允许的标量值。
推荐阅读
- excel - 引用 vba 中的表格范围
- javascript - MVC 从控制器获取数据以使用 AJAX 查看有什么问题?
- javascript - Strapi上的Graphql过滤器使用“where”方法检查记录是否包含空数组
- python - 如何在python中将十进制转换为二进制值?
- css - 如何在 Angular 中切换暗模式
- visual-studio-code - 在VSCode中打开“.sql”文件时如何隐藏突出显示的行
- java - 底部导航视图
- javascript - React & D3.js:重新渲染组件会导致重新渲染相同的图形问题:
- python - 向主数据源查询 panda DataFrame 列
- python - Python 无法从图像中读取文本 [Python OCR with Tesseract]