Ruby on rails 通过JSON API上载图像时出现类型错误
我使用Carrierwave将图像直接上传到AmazonS3。我有一个用于上传的JSON API,在客户端中将图像编码为Base64并发送。 我按照教程的博客帖子做了这件事 图像上载失败,控制台上显示此消息:Ruby on rails 通过JSON API上载图像时出现类型错误,ruby-on-rails,json,ruby-on-rails-4,amazon-s3,carrierwave,Ruby On Rails,Json,Ruby On Rails 4,Amazon S3,Carrierwave,我使用Carrierwave将图像直接上传到AmazonS3。我有一个用于上传的JSON API,在客户端中将图像编码为Base64并发送。 我按照教程的博客帖子做了这件事 图像上载失败,控制台上显示此消息: INSERT INTO "photos" ("created_at", "description", "image", "place_id", "review_id", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?) [["cr
INSERT INTO "photos" ("created_at", "description", "image", "place_id", "review_id", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?) [["created_at", Sat, 02 Aug 2014 13:43:24 PDT -07:00], ["description", "rainbow"], ["image", #<ActionDispatch::Http::UploadedFile:0x007fb86caf8b98 @tempfile=#<Tempfile:/var/folders/3n/qvctcdv17cn2kp4083pt4f6c0000gn/T/uploaded-photo20140802-7745-1g7ic67>, @original_filename="image.JPG", @content_type=nil, @headers=nil>], ["place_id", 1], ["review_id", 1], ["updated_at", Sat, 02 Aug 2014 13:43:24 PDT -07:00], ["user_id", 1]]
TypeError: can't cast ActionDispatch::Http::UploadedFile to string: INSERT INTO "photos" ("created_at", "description", "image", "place_id", "review_id", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?)
这是我的模型。我已在图像上安装ImageUploader:
class Photo < ActiveRecord::Base
validates :image, :presence => true
belongs_to :place
mount_uploader :image, ImageUploader
end
上述JSON是通过手工制作的测试脚本发送的:
require 'base64'
require 'net/http'
require 'json'
encoded_string = Base64.encode64(File.open("image.JPG", "rb").read)
@host = 'localhost'
@port = '3000'
@post_ws = "/api/places/1/photos/upload"
@image = { :content_type => "image/jpeg", :filename => "image.JPG", :file_data => encoded_string }
@payload = {"auth_token" => "9ycXsJ2rcWT-gy4gdLSN", "email" => "useremail@gmail.com", "photo" => {"image" => @image , "description" => "rainbow", "review_id" => 1 }}.to_json
def post
req = Net::HTTP::Post.new(@post_ws, initheader = {'Content-Type' =>'application/json'})
req.body = @payload
response = Net::HTTP.new(@host, @port).start {|http| http.request(req) }
puts "Response #{response.code} #{response.message}:
#{response.body}"
end
post()
我终于通过API上传了照片。 在
create()
函数中,而不是
@photo[:image] = parse_image_data(@photo_params[:image]) if @photo_params[:image]
我把它改成了
photo_params[:image] = parse_image_data(photo_params[:image]) if photo_params[:image]
以下是完整的代码:
def upload
user = User.where(:authentication_token => params[:auth_token])
place = Place.find(params[:place_id])
photo_params[:image] = parse_image_data(photo_params[:image]) if photo_params[:image]
@photo = place.photos.build(photo_params)
@photo.user_id = user.first.id
if @photo.save
@photo
else
render json: { success: false, error: @photo.errors }
end
ensure
clean_tempfile
end
def photo_params
@photo_params ||= params.require(:photo).permit(:description, :review_id, image:[:content_type, :filename, :file_data])
end
private
def parse_image_data(image_data)
@tempfile = Tempfile.new('uploaded-photo')
@tempfile.binmode
@tempfile.write Base64.decode64(image_data[:file_data])
@tempfile.rewind
ActionDispatch::Http::UploadedFile.new(
:tempfile => @tempfile,
:content_type => image_data[:content_type],
:filename => image_data[:filename],
:original_filename => image_data[:original_filename]
)
end
def clean_tempfile
if @tempfile
@tempfile.close
@tempfile.unlink
end
end
photo_params[:image] = parse_image_data(photo_params[:image]) if photo_params[:image]
def upload
user = User.where(:authentication_token => params[:auth_token])
place = Place.find(params[:place_id])
photo_params[:image] = parse_image_data(photo_params[:image]) if photo_params[:image]
@photo = place.photos.build(photo_params)
@photo.user_id = user.first.id
if @photo.save
@photo
else
render json: { success: false, error: @photo.errors }
end
ensure
clean_tempfile
end
def photo_params
@photo_params ||= params.require(:photo).permit(:description, :review_id, image:[:content_type, :filename, :file_data])
end
private
def parse_image_data(image_data)
@tempfile = Tempfile.new('uploaded-photo')
@tempfile.binmode
@tempfile.write Base64.decode64(image_data[:file_data])
@tempfile.rewind
ActionDispatch::Http::UploadedFile.new(
:tempfile => @tempfile,
:content_type => image_data[:content_type],
:filename => image_data[:filename],
:original_filename => image_data[:original_filename]
)
end
def clean_tempfile
if @tempfile
@tempfile.close
@tempfile.unlink
end
end