Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
532 views
in Technique[技术] by (71.8m points)

ruby - Rails 4.0 Strong Parameters nested attributes with a key that points to a hash

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"
Content-Type: image/jpeg
">
     }
   }
 },
 "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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...