2010-11-03 4 views
13

Ho un file rake, che legge il contenuto via HTTP e voglio usare Paperclip per memorizzare il contenuto caricato su Amazon S3. Funziona bene quando fornisco un file locale, ma mi piacerebbe impostare il contenuto come una stringa e impostare il tipo di contenuto manualmente.Come usare Paperclip senza file, solo con una stringa?

Quanto segue non funziona. Nessun errore viene emesso, la voce del database viene aggiornato, ma nessun file viene creato nella S3:

p.attachment = "Test" 
p.attachment_file_name = "test.txt" 
p.attachment_content_type = "text/plain" 
p.attachment_file_size = "Test".size 
p.attachment_updated_at = Time.now 
p.save 

Credo che avrei potuto scrivere un file temporaneo con il mio contenuto, ma che sarebbe una soluzione piuttosto inefficiente.

risposta

2

No, è necessario creare un file con la stringa.

Basta guardare il codice sorgente Paperclip: https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/attachment.rb#L77 e https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/iostream.rb#L5

quando si assegna qualcosa usando my_model.attachment =, Paperclip vuole un oggetto file.

+0

Questo è un peccato. Pensi che dovrei usare qualcos'altro oltre a Paperclip? Vorrei mantenere la possibilità di passare facilmente da S3 a file system, ma non ho upload di file utente, quindi Paperclip potrebbe essere la scelta sbagliata. – Jan

+1

hai guardato su carrierwave: https://github.com/jnicklas/carrierwave che sembra un'ottima alternativa ... –

8

E 'un po' tardi, ma ho tirato fuori con la creazione di un File Temporanei utilizzando ruby ​​1.9.2 rotaie 3.1

file = Tempfile.new(["file_name", '.txt']) 
file.write("my test string".force_encoding('utf-8')) 
p.attachment = file 
+0

geniale .. Non so perché funzioni, ma funziona. –

+0

questo creerà effettivamente un file ... https://ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/Tempfile.html – olivervbk

40

Per evitare sporcare il filesystem con file temporanei, è possibile utilizzare StringIO come in:

p.attachment = StringIO.new(your_string) 
+1

Grande piccola soluzione. Una volta fatto, imposta il nome del file allegato con 'p.attachment_file_name = 'test.txt'' e sei pronto. –

0

simile a Aarons, ma con il metodo blocco corretto come suggerito da Ruby:

... si dovrebbe sempre chiamare scollegare o chiudere in un blocco di sicurezza.

file = Tempfile.new('test.txt') 

begin 
    file.write("Test") 

    p.attachment = file 
    p.save    

    # Whatever else you might need to do with the TempFile. 

ensure 
    file.close 
    file.unlink # Deletes the temp file. 
end 
3

Per entrambi graffetta e carierwave io alla fine la creazione di una classe come questa. Ha entrambi i metodi necessari per simulare un caricamento di file che a loro piace vedere.

class FakeFileIO < StringIO 
    attr_reader :original_filename 
    attr_reader :path 

    def initialize(filename, content) 
    super(content) 
    @original_filename = File.basename(filename) 
    @path = File.path(filename) 
    end 
end 

funziona come un sogno