Rails 4.0 Strong Parameters nested attributes 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]

Leave a Comment