我使用以下参数创建一个http put请求:
{“post”=> {“files”=> {“file1”=>“file_content_1”,“file2”=>“file_content_2”}},“id”=>“4”}
我需要在我的代码中允许哈希数组。基于manuals,我尝试过这样的:
> params.require(:post).permit(:files) # does not work
> params.require(:post).permit(:files => {}) # does not work, empty hash as result
> params.require(:post).permit! # works, but all params are enabled
如何正确使用?
UPD1:file1,file2 - 是动态密钥
通过设计强params不允许使用动态键作为值的哈希,因此..在这种情况下,您需要手动将files
列入白名单。
params.require(:post).tap do |whitelisted|
whitelisted[:files] = params[:post][:files]
end
Send params as array type like name=date[]**strong text**
def user_post
dates = params[:date]
#render json: { 'response' => params }
i = 0
dates.each do |date|
locations = params['location_'+"#{i}"]
user_names = params['user_'+"#{i}"]
currency_rates = params['currency_'+"#{i}"]
flags = params['flag_'+"#{i}"]
j = 0
locations.each do |location|
User.new(user_name: user_names[j], currency_name: flags[j],
currency_rate: currency_rates[j], currency_flag: flags[j], location: location).save
j =+ 1
end
i =+ 1
end
def
我没有得到任何许多提议的工作答案(Rails 5),没有:
我正在使用这个解决方案。 它使用标准的强参数装备来清理大多数参数,并且显式地添加Hash属性。
# Assuming:
class MyObject < ApplicationRecord
serialize :hash_attr as: Hash
#...
end
# MyObjectsController method to filter params:
def my_object_params
# capture the hashed attribute value, as a Hash
hash_attr = params[:my_object] && params[:my_object][:hash_attr] ?
params[my_object][:hash_attr].to_unsafe_h : {}
# clean up the params
safe_params = params.require(:my_object).permit(:attr1, :attr2) # ... etc
# and add the hashed value back in
safe_params.to_unsafe_h.merge hash_attr: hash_attr
end
让我们使用更复杂的数据子集:
task: {
code: "Some Task",
enabled: '1',
subtask_attributes: {
'1' => { field: 'something', rules: {length_10: true, phone: false, presence: false }} ,
'2' => { field: 'another', rules: {length_10: true, phone: false, presence: false }}
}
}
所以我们将它发送到Strong Parameters进行处理:
params = ActionController::Parameters.new({
task: {
code: "Some Task",
enabled: '1',
subtask_attributes: {
'1' => { field: 'something', rules: {length_10: true, phone: false, presence: false }} ,
'2' => { field: 'another', rules: {length_10: true, phone: false, presence: false }}
}
}
})
我们将无法在Rails 4中的强参数中指定:规则,因为它是数据的哈希:
permitted = params.require(:task).permit(:code, :enabled, subtask_attributes: [:field, :rules])
Unpermitted parameter: rules
Unpermitted parameter: rules
那么,如果您想将特定属性和数据哈希集合列入白名单,该怎么办?接受的答案不会将指定的属性列入白名单。你必须这样做:
params.require(:task).permit(
:code, :enabled,
subtask_attributes: [:field, :rules],
)
# whitelist the validation rules hash
params.require(:task).tap do |whitelisted|
params[:task][:subtask_attributes].each do |k,v|
whitelisted[:subtask_attributes][k] = params[:task][:subtask_attributes][k]
whitelisted.permit!
end
end
在尝试了几个解决方案后,没有一个工作。只有Aboved适用于包含任意哈希数据的has_many关联中的嵌套属性。
在rails 5.1.2中,现在可以使用:
params.require(:post).permit(:files => {})
见https://github.com/rails/rails/commit/e86524c0c5a26ceec92895c830d1355ae47a7034
我知道这是一个老帖子。但是,谷歌搜索带我到这个结果,我想分享我的发现:
这是我发现的另一种解决方案(Rails 4):
params = ActionController::Parameters.new({"post"=>{"files"=>{"file1"=>"file_content_1", "file2"=>"file_content_2"}}, "id"=>"4"})
params.require(:post).permit(files: params[:post][:files].keys)
# Returns: {"files"=>{"file1"=>"file_content_1", "file2"=>"file_content_2"}}
此答案与已接受答案之间的区别在于此解决方案将参数限制为仅1级动态键。接受的答案允许多个深度。
[编辑]评论的有用提示
“哦,你需要验证params [:post] [。files]是否存在,否则键将失败”
奥兰多的答案有效,但结果参数集从false
方法返回permitted?
。如果您以后在post
哈希中包含您想要包含在结果中的其他参数,那么您还不清楚如何继续。
这是另一种方式
permitted_params = params.require(:post).permit(:other, :parameters)
permitted_params.merge(params[:post][:files])
这是我们在Rails 5.0.0中必须做的事情,希望这有助于某人。
files = params[:post].delete(:files) if params[:post][:files]
params.require(:post).permit(:id).tap do |whitelisted|
whitelisted[:files] = files.permit!
end
就我而言,只有一个属性具有动态键,
def post_params
marking_keys = Set.new
params[:post][:marking].keys.collect {|ii| marking_keys.add(ii)}
params.require(:post).permit(:name, marking: marking_keys.to_a)
end
这是解决这个问题的另一种方法:
def post_params
permit_key_params(params[:post]) do
params.require(:post)
end
end
def permit_key_params(hash)
permitted_params = yield
dynamic_keys = hash.keys
dynamic_keys.each do |key|
values = hash.delete(key)
permitted_params[key] = values if values
end
permitted_params
end
这适用于post: { something: {...}, something_else: {...} }
您可以使用临时变量来构建允许的列表,如下所示:
permitted = params.require(:post).permit(:id)
permitted[:post][:files] = params[:post][:files].permit!
这是一个简单的方法(适用于rails 5):
def my_params
data_params = preset_data_params
params.require(:my_stuff).permit(
:some,
:stuff,
data: data_params
)
end
def preset_data_params
return {} unless params[:my_stuff]
return {} unless params[:my_stuff][:data]
params[:my_stuff][:data].keys
end