我对Rails很新,我老实说对我正在做的事情感到困惑,抱歉遗漏了这里的任何基础......
此related question没有帮助
尝试通过API将文件从iOS客户端应用程序上传到Heroku上托管的我的rails应用程序。使用form.file_field上传时,安装的Paperclip gem和文件上传效果很好。但不是来自API。
undefined method `[]' for #<ActionDispatch::Http::UploadedFile
进行PUT方法上传/ api / v1 / foos / 1时的文件
模型
class Foo < ActiveRecord::Base
has_attached_file :foo_file
validates_attachment : foo_file, content_type: { content_type: ["application/xml"] }
end
控制器
class Api::V1::FoosController < Api::V1::BaseController
def update
result = { status: "failed" }
begin
params[:foo_file] = parse_foo_file_data(params[:foo_file]) if params[:foo_file]
item = Foo.find(params[:id])
item.foo_file = params[:foo_file]
if item.save
result[:status] = "success"
end
rescue Exception => e
Rails.logger.error "#{e.message}"
end
ensure
clean_tempfile
foo = Foo.find(params[:id])
authorize foo
if !foo.update_attributes(update_params)
return api_error(status: 422, errors: foo.errors)
end
render json: result.to_json
end
def parse_foo_file_data(foo_file_data)
@tempfile = Tempfile.new('item_foo_file')
@tempfile.binmode
@tempfile.write Base64.decode64(foo_file_data.read)
@tempfile.rewind
uploaded_file = ActionDispatch::Http::UploadedFile.new(
tempfile: @tempfile,
original_filename: foo_file_data.original_filename
)
uploaded_file.content_type = foo_file_data.content_type
uploaded_file
end
def clean_tempfile
if @tempfile
@tempfile.close
@tempfile.unlink
end
end
def update_params
params.require(:app).permit(
:name, :user_id, :foo_file
)
end
end
最终,我将非常感谢您将此文件上传并附加到foo对象的foo_file参数的任何帮助。我认为这与我指出的未定义的方法错误有关。或者我可能只是完全偏离基础。感谢您的时间和帮助!
编辑:
新服务器日志
Started PUT "/api/v1/foos/1
Processing by Foo::V1::FoosController#update as JSON
Parameters:
{"foo"=>{"name"=>"newnameB"}, "foo_file"=>#<ActionDispatch::Http::UploadedFile:0x007fac81c82168 @tempfile=#<Tempfile:/tmp/RackMultipart20160523-6-q6pyac.xml>, @original_filename="Main.xml", @content_type="multipart/form-data", @headers="Content-Disposition: form-data; name=\"foo_file\"; filename=\"Main.xml\"\r\nContent-Type: multipart/form-data\r\n">, "id"=>"1"}
undefined method `gsub' for nil:NilClass
Completed 200 OK in 25ms (Views: 0.4ms | ActiveRecord: 3.6ms)
答案 0 :(得分:0)
在update
的开头附近,在这一行:
params[:foo_file] = parse_foo_file_data(params[:foo_file]) if params[:foo_file]
你致电pase_foo_file_data(params[:foo_file])
。您可以查看日志params[:foo_file]
是否为ActionDispatch::Http::UploadedFile
对象。
在下面,parse_foo_file_data
的定义如下:
def parse_foo_file_data(foo_file_data)
@tempfile = Tempfile.new('item_foo_file')
@tempfile.binmode
@tempfile.write Base64.decode64(foo_file_data[:data])
@tempfile.rewind
# ... etc
在第三行,你有foo_file_data[:data]
。但是foo_file_data
是一个ActionDispatch :: Http :: UploadedFile对象,that class doesn't provide a []
method。
您最有可能尝试的是从UploadedFile对象中获取数据,在这种情况下,您需要的内容更多@tempfile.write Base64.decode64(foo_file_data.read)
当您尝试进一步调用foo_file_data[:content_type]
时,您会遇到类似的问题,需要foo_file_data.content_type
。