2012-04-15 6 views
13

Ich möchte eine Datei von einem Android Client auf einen Rails JSON API Server hochladen.Hochladen einer Datei auf den Rails JSON API Server mit Paperclip und Multipart Anfrage

Ich schicke eine multipart/form Anfrage aus dem Android-Client, der so aussieht:

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-- 

in den Schienen-Controller Ich schaffe das neue Post mit diesem Code:

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

Wie mache ich Paperclip den Anhang aus dem mehrteiligen Formular speichern?

ich kann es mit etwas wie folgt aus:

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 

aber es sieht nicht wie die beste Lösung, auch die Dateinamen, die in ther mehrt Anforderung übergeben wird nicht verwendet wird.

+0

irgendwelche ideen wie dies zu tun? –

Antwort

4

Also, ich bin Ihr Post Modell erraten sieht ungefähr so ​​aus:

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

So sollten Sie in der Lage sein, etwas so einfaches wie dies zu tun:

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

Und es sollte die sparen Foto.

Wenn Sie etwas komplizierteres tun müssen, versuchen Sie, die Formulardaten in die Daten umzuordnen, die das Format Paperclip erwartet. Und wenn Sie tiefer graben müssen, take a look inside Paperclip's Paperclip::Attachment class.

Stack-Überlauf Querverweis

12

Der reine json Weg, dies zu tun, ist nicht mehrtForm-Content-Typen zu übergeben und die Datei über, eine Base64-codierte Zeichenfolge im JSON.

ich dachte das ich durch diesen Beitrag: http://www.rqna.net/qna/xyxun-paperclip-throws-nohandlererror-with-base64-photo.html

Hier ist ein Beispiel für die 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\"}}}" 

Dann im Controller Prozess den eingehenden Avatar, wie dies vor, das Modell zu speichern.

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

Das funktioniert so weit. Mir geht es gut, aber kann mir jemand erklären, wie das funktionieren kann, dass wir tatsächlich Params [: account] [: avatar] mit StringIO-Klasse füllen? –

+1

Das ist halb so gut für mich, wenn das Bild zu groß ist und auch die Base64-Zeichenkette, stürzt es ab und löst die Errno :: E2BIG-Ausnahme aus. –

+1

Ich denke, es ist mehr sauber zu dieser Logik für das Modell wie hier dokumentiert: http://ggie5.com/54-ios-rails-image-uploads – eggie5

Verwandte Themen