Joh*_*ohn 34 ruby ruby-on-rails strong-parameters ruby-on-rails-4
我正在玩Rails 4.x beta并尝试使用carrierwave获取嵌套属性.不确定我正在做的是正确的方向.搜索后,最后查看导轨源和强参数,我发现了下面的注释.
Run Code Online (Sandbox Code Playgroud)# Note that if you use +permit+ in a key that points to a hash, # it won't allow all the hash. You also need to specify which # attributes inside the hash should be whitelisted.
所以它说你必须在has中指定每一个单独的属性,我尝试了以下内容:
帕拉姆的例子:
{"utf8"=>"?",
"authenticity_token"=>"Tm54+v9DYdBtWJ7qPERWzdEBkWnDQfuAQrfT9UE8VD=",
"screenshot"=>{
"title"=>"afs",
"assets_attributes"=>{
"0"=>{
"filename"=>#<ActionDispatch::Http::UploadedFile:0x00000004edbe40
@tempfile=#<File:/tmp/RackMultipart20130123-18328-navggd>,
@original_filename="EK000005.JPG",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"screenshot[assets_attributes][0][filename]\"; filename=\"EK000005.JPG\"\r\nContent-Type: image/jpeg\r\n">
}
}
},
"commit"=>"Create Screenshot"}
Run Code Online (Sandbox Code Playgroud)
调节器
def screenshot_params
params.require(:screenshot).permit(:title,
:assets_attributes => [:filename => [:@tempfile,:@original_filename,:@content_type,:@headers]
Run Code Online (Sandbox Code Playgroud)
以上不是"工作"(它不触发载波)但是当我使用我发现的标准嵌套示例时,我不再收到错误(未经许可的参数:文件名):
def screenshot_params
params.require(:screenshot).permit(:title, assets_attributes: :filename)
Run Code Online (Sandbox Code Playgroud)
如果有人能提供帮助就会很棒.我无法找到嵌套了一个指向哈希的键的示例.
Jim*_*lle 33
我的另一个答案大多是错误的 - 新答案.
在你的params散列中,:filename与另一个散列没有关联,它与一个ActiveDispatch :: Http :: UploadedFile对象相关联.你的上一个代码行:
def screenshot_params
params.require(:screenshot).permit(:title, assets_attributes: :filename)
Run Code Online (Sandbox Code Playgroud)
实际上是正确的,但是不允许使用filename属性,因为它不是允许的标量类型之一.如果打开控制台,并初始化此形状的params对象:
params = ActionController::Parameters.new screenshot: { title: "afa", assets_attributes: {"0" => {filename: 'a string'}}}
Run Code Online (Sandbox Code Playgroud)
然后在最后一行上运行它:
p = params.require(:screenshot).permit(:title, assets_attributes: :filename)
# => {"title" => "afa", "assets_attributes"=>{"0"=>{"filename"=>"abc"}}}
Run Code Online (Sandbox Code Playgroud)
但是,如果你对上传文件的params哈希做同样的事情,你会得到
upload = ActionDispatch::Http::UplaodedFile.new tempfile: StringIO.new("abc"), filename: "abc"
params = ActionController::Parameters.new screenshot: { title: "afa", assets_attributes: {"0" => {filename: upload}}}
p = params.require(:screenshot).permit(:title, assets_attributes: :filename)
# => {"title" => "afa", "assets_attributes"=>{"0"=>{}}}
Run Code Online (Sandbox Code Playgroud)
因此,它可能值得对Rails提出错误或拉取请求,同时,您必须使用原始params
对象直接访问filename参数:
params[:screenshot][:assets_attributes]["0"][:filename]
Run Code Online (Sandbox Code Playgroud)
Pat*_*Gee 14
所以,你正在处理has_many表单和强参数.
这是params hash的一部分:
"assets_attributes"=>{
"0"=>{
"filename"=>#<ActionDispatch::Http::UploadedFile:0x00000004edbe40
@tempfile=#<File:/tmp/RackMultipart20130123-18328-navggd>,
@original_filename="EK000005.JPG",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"screenshot[assets_attributes][0][filename]\"; filename=\"EK000005.JPG\"\r\nContent-Type: image/jpeg\r\n">
}
}
Run Code Online (Sandbox Code Playgroud)
当你定义像这样的强参数时......
permit(:assets_attributes => [:filename])
Run Code Online (Sandbox Code Playgroud)
事情破裂了,因为rails希望filename
它能够实现这一目标"0"
这个数字是什么意思?这是id
您通过表单提交的资产.现在最初你可能认为你必须做类似的事情
permit(:assets_attributes => [:id => [:filename]])
Run Code Online (Sandbox Code Playgroud)
这看起来遵循其他强参数语法约定.但是,无论好坏,他们都会让事情变得更容易,而你所要写的就是:
permit(:assets_attributes => [:asset_id, :filename])
Run Code Online (Sandbox Code Playgroud)
编辑 - 正如jpwynn在评论中指出的那样,在Rails 4.2.4+中,正确的语法是
permit(:assets_attributes => [:id, :filename])
Run Code Online (Sandbox Code Playgroud)
这应该工作.
当您使用强大的参数击中墙壁时,最好的办法是在控制器中抛出调试器并进行测试.params.require(:something).permit(:other_things)
只是一个方法链,所以你可以在完整的params哈希上尝试不同的东西,直到找到有效的方法.
尝试
def screenshot_params
params.require(:screenshot).permit(:title, :assets_attributes => [:filename, :id, :screenshot_id])
end
Run Code Online (Sandbox Code Playgroud)
大约一个月前我遇到过这个问题,有些人正在寻找这个解决方案.它正在添加:id或:screenshot_id来修复问题(或两者,我都记不清了).这虽然适用于我的代码.