Rails强参数如何兼容字符串、字符串数组与哈希数组类型?
解决Rails强参数支持三种value类型的问题
要让强参数同时支持字符串、字符串数组、哈希数组三种value类型,需要结合Rails强参数的基础语法,再手动补充字符串数组的允许逻辑(默认permit会过滤掉非哈希结构的数组元素)。
修改后的强参数代码
def project_params # 先允许基础字段和哈希数组类型的value permitted_params = params.require(:project).permit( :name, field_values_attributes: [ :field_component_id, :value, # 允许单个字符串value value: [ :id, attributes: [:uid, :email, :full_name] ] ] ) # 手动恢复被过滤的字符串数组类型value if params[:project][:field_values_attributes].present? permitted_params[:field_values_attributes].each_with_index do |permitted_fv, index| original_fv = params[:project][:field_values_attributes][index] # 判断原始value是否是全字符串的数组,且当前permitted的value被过滤为空 if original_fv[:value].is_a?(Array) && original_fv[:value].all? { |v| v.is_a?(String) } permitted_fv[:value] = original_fv[:value] end end end permitted_params end
说明
- 第一步的
permit语句已经支持单个字符串和哈希数组类型的value,但对于字符串数组,Rails会自动过滤数组中的字符串元素,导致value变为空数组。 - 第二步通过遍历原始参数,检查每个
field_values_attributes的value是否为全字符串数组,如果是,就把原始值赋值给已通过permit的参数,从而保留字符串数组类型的value。
可选简洁写法(利用merge和自定义过滤)
如果你不想手动遍历,也可以用merge结合自定义参数提取:
def project_params base_params = params.require(:project).permit( :name, field_values_attributes: [ :field_component_id, value: [ :id, attributes: [:uid, :email, :full_name] ] ] ) # 提取字符串数组类型的value并合并到已permit的参数中 string_array_values = params[:project][:field_values_attributes]&.map do |fv| if fv[:value].is_a?(Array) && fv[:value].all?(String) { field_component_id: fv[:field_component_id], value: fv[:value] } end end.compact if string_array_values.present? base_params[:field_values_attributes] = base_params[:field_values_attributes].map do |permitted_fv| matching = string_array_values.find { |s| s[:field_component_id] == permitted_fv[:field_component_id] } matching ? permitted_fv.merge(matching) : permitted_fv end end base_params end
内容的提问来源于stack exchange,提问作者Miroslav
相关产品推荐
相关产品推荐

