2009-11-04 13 views
29

आप सक्रिय रिकॉर्ड में संलग्न किए बिना रेल में फ़ाइल अपलोड कैसे संभालते हैं?
मैं बस डिस्क पर फ़ाइलों को लिखना चाहता हूं।फ़ाइल सक्रिय के बिना अपलोड करें

धन्यवाद,

+0

इस प्रयास करें http://easyrails.herokuapp.com/blogs/5/upload-file-in-rails-without-model- निर्माण – vajapravin

उत्तर

54

अगर मैं सही ढंग से समझ क्या आप तो जरूरत सबसे सरल उदाहरण यह होगा:

नियंत्रक:

class UploadController < ApplicationController 
    def new 

    end 

    def create 
    name = params[:upload][:file].original_filename 
    path = File.join("public", "images", "upload", name) 
    File.open(path, "wb") { |f| f.write(params[:upload][:file].read) } 
    flash[:notice] = "File uploaded" 
    redirect_to "/upload/new" 
    end 
end 

दृश्य:

<% flash.each do |key, msg| %> 
    <%= content_tag :div, msg, :class => [key, " message"], :id => "notice_#{key}" %> 
<% end %> 
<% form_tag '/upload/create', { :multipart => true } do %> 
    <p> 
    <%= file_field_tag 'upload[file]' %> 
    </p> 
    <p> 
     <%= submit_tag "Upload" %> 
    </p> 
<% end %> 

यह आप किसी भी अपलोड करेंगे किसी भी चेक या सत्यापन के बिना फ़ाइल जो मेरी राय में उपयोगी नहीं है।

अगर मैं इसे स्वयं करता तो मैं validatable gem या tableless gem जैसे कुछ का उपयोग करता हूं, बस टेबललेस समर्थित नहीं है। ये रत्न आपको जो अधिक अपलोड करने के लिए अपलोड कर रहे हैं उसे सत्यापित करने की अनुमति देगा।

+1

बस रेलवे में <% = form_tag ...%> का उपयोग करना सुनिश्चित करें 3. – cider

+0

सुसंगत होने के लिए आपको 'file.join (" public "," images "," upload ")' निर्देशिका बनाने के लिए उपयोग नहीं करना चाहिए '? – Crashalot

+0

निश्चित रूप से, यह एक अच्छी टिप है। यह वास्तव में बहुत समय पहले लिखा था :) मुझे नहीं लगता कि मुझे उस समय ऐसा करने के बारे में पता था :) एक पंक्ति में कोडिंग करते समय बस उदाहरणों का उपयोग किया जाता है :)) दूसरी तरफ मैं नहीं करता हूं। अभी अपडेट हो रहा है –

0

आप फ़ाइल अपलोड संभाल करने रेल प्लगइन Attachment_fu उपयोग करने का प्रयास कर सकता है। यह आपको डेटाबेस की बजाय फ़ाइल सिस्टम में अपलोड सहेजने की अनुमति देता है।

+0

attachement_fu activerecord की आवश्यकता है .... – Mike

3

Tempfile दस्तावेज़ीकरण एक उदाहरण दिखाता है जो Rytis के कोड के बराबर है, जो कि ज्यादातर समय ठीक है। लेकिन जब आप tempfile.read पर कॉल करते हैं, तो रूबी पूरी फ़ाइल को स्मृति में एक सिंगल खंड के रूप में पढ़ रही है, जो उप-इष्टतम है।

हालांकि, FileUtils एक copy_stream तरीका प्रदान करता है, और IO, रूबी 2.0 में कम से कम, एक copy_stream कार्यान्वयन कि सीधे एक filepath के लिए लिख हैंडल (FileUtils.copy_stream दोनों पक्षों पर फ़ाइल की तरह वस्तुओं की आवश्यकता है, या तो डॉक्स कहते हैं) प्रदान करता है।

मेरे मामले में, मैं AJAX के माध्यम से एक बड़ी बहु-फ़ाइल अपलोड शुरू कर रहा था, और डिस्क पर लिखने से पहले रूबी की स्मृति में पूरी फ़ाइल को पढ़ने से बचना चाहता था।

नीचे दिए गए उदाहरण में, params[:files]ActionDispatch::Http::UploadedFile उदाहरणों में से एक Array है, और local_filepath एक स्ट्रिंग एक मौजूदा निर्देशिका में गैर-मौजूद फ़ाइल की ओर इशारा करते है। संक्षिप्तता के लिए, मैं मैं केवल एक फ़ाइल को अपलोड कर रहा हूँ मान लेंगे:

IO.copy_stream(params[:files][0].tempfile, local_filepath) 

ActionDispatch::Http::UploadedFile उदाहरण एक .tempfile क्षेत्र सिर्फ एक नियमित रूप से Tempfile उदाहरण है कि है।

मुझे वास्तव में यकीन नहीं है कि रूबी अभी भी पूरी फ़ाइल को स्मृति में नहीं पढ़ रहा है- मैंने कुछ भी बेंचमार्क नहीं किया है- लेकिन यह localfile.write(tempfile.read) वाक्यविन्यास के साथ कहीं अधिक संभव है।

टीएल; डी: IO.copy_stream(your_tempfile, your_disk_filepath) अधिक तेज़ नहीं है, अगर तेज़ नहीं है।

4

तुम बस FileUtils

का उपयोग कर भाग्य पथ के लिए अस्थायी फ़ाइल स्थानांतरित कर सकते हैं
tmp = params[:my_file_field].tempfile 
destiny_file = File.join('public', 'uploads', params[:my_file_field].original_filename) 
FileUtils.move tmp.path, destiny_file 
संबंधित मुद्दे