Rails 4.0 强参数嵌套属性,带有指向哈希的键 [英] Rails 4.0 Strong Parameters nested attributes with a key that points to a hash

查看:57
本文介绍了Rails 4.0 强参数嵌套属性,带有指向哈希的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Rails 4.x 测试版并尝试使用carrierwave 获取嵌套属性.不确定我在做什么是正确的方向.在四处搜索,然后最终查看 rails 源和强参数后,我发现了以下注释.

<块引用>

# 注意,如果在指向散列的键中使用 +permit+,# 它不会允许所有的散列.您还需要指定哪个# 散列中的属性应该被列入白名单.

https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb

所以它说你必须指定 has 中的每一个属性,我尝试了以下操作:

参数示例:

{"utf8"=>"✓","authenticity_token"=>"Tm54+v9DYdBtWJ7qPERWzdEBkWnDQfuAQrfT9UE8VD=",截图"=>{"title"=>"afs",assets_attributes"=>{0"=>{"文件名"=>#<ActionDispatch::Http::UploadedFile:0x00000004edbe40@tempfile=#<文件:/tmp/RackMultipart20130123-18328-navggd>,@original_filename="EK000005.JPG",@content_type="图像/jpeg",@headers="Content-Disposition: form-data; name=\"screenshot[assets_attributes][0][filename]\"; filename=\"EK000005.JPG\"\r\nContent-Type: image/jpeg\r\n">}}},提交"=>创建屏幕截图"}

控制器

def screenshot_paramsparams.require(:screenshot).permit(:title,:assets_attributes =>[:文件名 =>[:@tempfile,:@original_filename,:@content_type,:@headers]

以上不是工作"(它没有触发载波)但是我在使用我发现的标准嵌套示例时不再出现错误(不允许的参数:文件名):

def screenshot_paramsparams.require(:screenshot).permit(:title, assets_attributes: :filename)

如果有人能帮忙就太好了.我无法找到一个带有指向哈希的键嵌套的示例.

解决方案

我的另一个答案大多是错误的 - 新答案.

在您的 params 哈希中,:filename 不与另一个哈希关联,它与 ActiveDispatch::Http::UploadedFile 对象关联.您的最后一行代码:

def screenshot_paramsparams.require(:screenshot).permit(:title, assets_attributes: :filename)

实际上是正确的,但是,文件名属性不被允许,因为它不是允许的标量类型.如果你打开一个控制台,并以这种形式初始化一个 params 对象:

params = ActionController::Parameters.new 截图:{ title: "afa", assets_attributes: {"0" =>{文件名:'一个字符串'}}}

然后针对最后一行运行它:

p = params.require(:screenshot).permit(:title, assets_attributes: :filename)# =>{标题"=>"afa", "assets_attributes"=>{"0"=>{"filename"=>"abc"}}}

但是,如果您对上传文件的 params 哈希执行相同操作,您将得到

upload = ActionDispatch::Http::UplaodedFile.new 临时文件:StringIO.new("abc"),文件名:"abc"params = ActionController::Parameters.new 截图:{ title: "afa", assets_attributes: {"0" =>{文件名:上传}}}p = params.require(:screenshot).permit(:title, assets_attributes: :filename)# =>{标题"=>"afa", "assets_attributes"=>{"0"=>{}}}

因此,可能值得向 Rails 提出错误或拉取请求,同时,您必须使用原始 params 对象直接访问文件名参数:

params[:screenshot][:assets_attributes]["0"][:filename]

I was playing around with Rails 4.x beta and trying to get nested attributes working with carrierwave. Not sure if what I'm doing is the right direction. After searching around, and then eventually looking at the rails source and strong parameters I found the below notes.

# 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.

https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb

So its saying you have to specify every single every single attribute within the has, I tried the following:

Param's example:

{"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"}

Controller

def screenshot_params
  params.require(:screenshot).permit(:title,
    :assets_attributes => [:filename => [:@tempfile,:@original_filename,:@content_type,:@headers] 

The above isn't "working" (its not triggering carrierwave) however I am no longer getting errors (Unpermitted parameters: filename) when using the standard nested examples I found ex:

def screenshot_params
  params.require(:screenshot).permit(:title, assets_attributes: :filename)

If anyone could help it would be great. I was not able to find a example with nested with a key that points to a hash.

解决方案

My other answer was mostly wrong - new answer.

in your params hash, :filename is not associated with another hash, it is associated with an ActiveDispatch::Http::UploadedFile object. Your last code line:

def screenshot_params
  params.require(:screenshot).permit(:title, assets_attributes: :filename)

is actually correct, however, the filename attribute is not being allowed since it is not one of the permitted scalar types. If you open up a console, and initialize a params object in this shape:

params = ActionController::Parameters.new screenshot: { title: "afa", assets_attributes: {"0" => {filename: 'a string'}}}

and then run it against your last line:

p = params.require(:screenshot).permit(:title, assets_attributes: :filename)
# => {"title" => "afa", "assets_attributes"=>{"0"=>{"filename"=>"abc"}}}

However, if you do the same against a params hash with the uploaded file, you get

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"=>{}}}

So, it is probably worth a bug or pull request to Rails, and in the meantime, you will have to directly access the filename parameter using the raw params object:

params[:screenshot][:assets_attributes]["0"][:filename]

这篇关于Rails 4.0 强参数嵌套属性,带有指向哈希的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆