Ruby on rails 通过JSON API上载图像时出现类型错误

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

我使用Carrierwave将图像直接上传到AmazonS3。我有一个用于上传的JSON API,在客户端中将图像编码为Base64并发送。 我按照教程的博客帖子做了这件事

图像上载失败,控制台上显示此消息:

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