【问题标题】:TypeError when uploading image via JSON API通过 JSON API 上传图像时出现 TypeError
【发布时间】:2014-08-02 21:09:16
【问题描述】:

我使用 Carrierwave 将图像直接上传到 Amazon S3。我有一个用于上传的 JSON API,我在客户端将图像编码为 Base64 并发送。 我按照this 教程博客文章来做。

图像上传失败并在控制台显示此消息:

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 (?, ?, ?, ?, ?, ?, ?)

我看到它试图为image 列插入数据库的值不是对象的字符串。当我通过浏览器上传(不使用 API)时,image 列中插入的值只是文件名。

我哪里错了?

这是我的控制器:

module Api
    module V1
        class PhotosController < ApplicationController

            def index
                if params[:place_id]
                    place = Place.find(params[:place_id])
                    @photos = place.photos
                end
            end

            def create
                user = User.where(:authentication_token => params[:auth_token])

                place = Place.find(params[:place_id])
                @photo = place.photos.build(photo_params)
                @photo.user_id = user.first.id

                @photo[:image] = parse_image_data(@photo_params[:image]) if @photo_params[:image]
                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]
                )
            end

            def clean_tempfile
                if @tempfile
                    @tempfile.close
                    @tempfile.unlink
                end
            end


        end
    end
end

这是我的模型。我已经在图像上安装了 ImageUploader:

class Photo < ActiveRecord::Base
    validates :image, :presence => true
    belongs_to :place

    mount_uploader :image, ImageUploader    

end

我发送的 JSON 是:

{
    "auth_token": "9ycXsJ2rcWT-gy4gdLSN",
    "email": "myemail@gmail.com",
    "photo": {
        "image": {
            "content_type": "image/jpeg",
            "filename": "image.JPG",
            "file_data": "base64_data",
            "description": "a description"
        }
    }
}

上面的 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()

【问题讨论】:

    标签: ruby-on-rails json ruby-on-rails-4 amazon-s3 carrierwave


    【解决方案1】:

    我终于可以通过 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-22
      • 2023-01-09
      • 2019-03-31
      • 2011-10-07
      • 2012-11-22
      • 1970-01-01
      • 2016-09-21
      • 2010-11-18
      相关资源
      最近更新 更多