2012-10-09 16 views
6

Kullanıcının web kamerası fotoğrafını profil fotoğrafı olarak ayarlamasına izin vermek için jpegcam kullanıyorum. Bu kütüphane Öyle gibi benim raylar denetleyicisi olsun sever için ham veri gönderme biter: Eğer request.raw_post kaydetmeye çalıştığınızdaBir paperclip kullanarak raw_data fotoğrafı nasıl kaydedilir

def ajax_photo_upload 
    # Rails.logger.info request.raw_post 
    @user = User.find(current_user.id) 
    @user.picture = File.new(request.raw_post) 

Bu çalışma ve ataç/raylar değil başarısız olur.

Errno::ENOENT (No such file or directory - ????JFIF??? 

Ben geçici bir dosya yapmak çözümler gördüm ama Paperclip otomatik olarak tempfile yapmak zorunda w/o request.raw_post kurtarmak için almanın bir yolu olup olmadığını merak olurdu. Orada herhangi bir şık fikir veya çözüm var mı? sunucuda kaydedilmesine geçici bir dosya gerektirdiğinden

ÇİRKİN ÇÖZÜM

class ApiV1::UsersController < ApiV1::APIController 

    def create 
    File.open(upload_path, 'w:ASCII-8BIT') do |f| 
     f.write request.raw_post 
    end 
    current_user.photo = File.open(upload_path) 
    end 

private 

    def upload_path # is used in upload and create 
    file_name = 'temp.jpg' 
    File.join(::Rails.root.to_s, 'public', 'temp', file_name) 
    end 

end 

Bu çirkin (geçici dosyası gerektirir). Bunun nasıl kaydedileceğine dair ipuçları geçici dosya kaydedilmeye gerek kalmadı mı? StringIO kullanılabilir mi?

+2

FileSystem'ı kullanmanın doğru olanı yapmanın mükemmel bir yolu olduğunu biliyor musunuz? Aslında, unix sistemi neredeyse tamamen FileSystem tabanlı, bu yüzden/dev/null'un tüm nedenidir. Bu çözüm hakkında sahip olduğum çok daha geçerli bir konu, yarış koşullarına duyarlı olmasıdır. –

+0

Geçerli olduğundan eminim, ancak bir dosya oluşturduğumda, tüm geçici dosyaları silmek için bir cron işine ihtiyacım var demektir, bu gerçekleşmezse HD'yi doldurmanız ve sunucuyu çökertmeniz gerekebilir. Neden endişelenecek bir şey daha var? Ben zarif bir çözme ile ilgileniyorum bu w/o bir geçici dosyaya ihtiyacım var. Daha az hareketli parçalar? – AnApprentice

+0

@AnApprentice, 'Tempfile' sınıfı eski dosyaları çöp toplayıcı tarafından temizlenir. Cevabımı aşağıya bakın. – Mischa

cevap

14

Önceki çözümümdeki sorun, geçici dosya zaten kapalıydı ve bu nedenle Paperclip tarafından artık kullanılamıyordu. Aşağıdaki çözüm benim için çalışıyor. IMO, en temiz yoldur ve (belgelere göre), geçici dosyalarınızın kullanımdan sonra silinmesini sağlar.

sizin User modeline aşağıdaki yöntemi ekleyin:

def set_picture(data) 
    temp_file = Tempfile.new(['temp', '.jpg'], :encoding => 'ascii-8bit') 

    begin 
    temp_file.write(data) 
    self.picture = temp_file # assumes has_attached_file :picture 
    ensure 
    temp_file.close 
    temp_file.unlink 
    end 
end 

Denetleyici:

current_user.set_picture(request.raw_post) 
current_user.save 

sizin User modeli dosyasının en üstünde require 'tempfile' eklemeyi unutmayın.

+0

Teşekkürler ama fikir bir geçici dosya – AnApprentice

+1

kullanmak değil Sonra ne istediğinizi yapmaya Paperclip kesmek zorunda ya da dosya sistemi üzerinde bir dosya gerektirmeyen farklı bir dosya işleme kütüphanesi kullanmak zorunda. (Carrierwave?) Her neyse, bu çözüm, eski dosyaları temizlemekten endişe ediyorsanız, çöp toplayıcısının sizin için yapması nedeniyle geçerlidir. Geçici dosyalar ile başka hangi endişeleriniz var? – Mischa

+1

Bu arada, normal bir dosya yükleme, bu kodun yaptığı gibi bir geçici dosya oluşturur. – Mischa

İlgili konular