2012-04-15 26 views
13

AndroidクライアントからRails JSON APIサーバーにファイルをアップロードします。レールコントローラでファイルをRails JSON APIサーバーにPaperclipとMultipartリクエストでアップロードする

Content-Type: multipart/form-data; boundary=d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5 
Host: 10.0.2.2:3000 
Connection: Keep-Alive 
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4) 

--d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5 
Content-Disposition: form-data; name="POSTDATA" 
Content-Type: application/json; charset=UTF-8 
Content-Transfer-Encoding: 8bit 

{"tags":["test"],"location_id":1,"post":{"content":"test"}} 
--d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5 
Content-Disposition: form-data; name="IMAGEDATA"; filename="testimage.jpg" 
Content-Type: image/jpeg 
Content-Transfer-Encoding: binary 

<BINARY DATA? 
--d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5-- 

私はこのコードで新しいポスト作成しています:

@parsed_json = JSON(params[:POSTDATA]) 
@post = @current_user.posts.new(@parsed_json["post"]) 

は、私はそのように見えるのAndroidクライアントからのマルチパート/フォーム要求を送信しています

どのようにして、Paperclipはマルチパートフォームから添付ファイルを保存できますか?

私はこのような何かでそれを行うことができます。

if params.has_key?(:IMAGEDATA) 
    photo = params[:IMAGEDATA] 
    photo.rewind 

    @filename = "/tmp/tempfile" 
    File.open(@filename, "wb") do |file| 
     file.write(photo.read) 
    end 

    @post.photo = File.open(@filename) 
    end 

が、それはまた、THERマルチパートリクエストに渡されているファイル名が使用されていない、最善の解決策のように見えていません。

+0

どのようにすればいいですか? –

答えて

4

だから、私はあなたのPostモデルを推測していることは、このようなものになります。

class Post < ActiveRecord::Base 
    has_attached_file :photo, :styles => { ... } 
    ... 
end 

ですから、このような単純な何かを行うことができるはず:

@post.photo = params[:IMAGEDATA] if params[:IMAGEDATA].present? 
@post.save if @post.valid? 

をそして、それは保存してください写真。

もっと複雑なことをする必要がある場合は、フォームデータをPaperclipのフォーマットが期待するデータに再配置してみてください。さらに深く掘り下げる必要がある場合は、take a look inside Paperclip's Paperclip::Attachment class。これを行うには

スタックオーバーフローのクロスリファレンス

12

純粋なJSONの方法は、コンテンツ・タイプのマルチパートフォームを渡すと、ファイルを渡さないことですjson内のbase64でエンコードされた文字列。

私は感謝このポストをこれを考え出した:http://www.rqna.net/qna/xyxun-paperclip-throws-nohandlererror-with-base64-photo.html

は、ここでは、JSONの例です:コントローラプロセスにおけるその後

"{\"account\":{\"first_name\":\"John\",\"last_name\":\"Smith\",\"email\":\"[email protected]\",\"password\":\"testtest\",\"avatar\":{\"data\":\"INSERT BASE64 ENCODED STRING OF FILE HERE\",\"filename\":\"avatar.jpg\",\"content_type\":\"image/jpg\"}}}" 

このように、着信アバターモデルを保存する前に。

def process_avatar 
    if params[:account] && params[:account][:avatar] 
    data = StringIO.new(Base64.decode64(params[:account][:avatar][:data])) 
    data.class.class_eval { attr_accessor :original_filename, :content_type } 
    data.original_filename = params[:account][:avatar][:filename] 
    data.content_type = params[:account][:avatar][:content_type] 
    params[:account][:avatar] = data 
    end 
end 
+0

これまでのところ動作しています。私は問題ありませんが、実際にparams [:account] [:avatar]にStringIOクラスを埋め込むことで、これがどのように機能するのか、誰かに教えていただけますか? –

+1

画像が大きすぎてbase64文字列の場合、Errno :: E2BIG例外がクラッシュして発生します。 –

+1

私は、ここに書かれているように、この論理をモデルにもっときれいだと思います:http://eggie5.com/54-ios-rails-image-uploads – eggie5

関連する問題