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]
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…