2008-11-15 50 views
3

我正在研究添加一個函數到我的基於Rails的Intranet站點的可行性,允許用戶上傳文件。Rails非圖像文件上傳到數據庫而不使用服務器端臨時文件?

兩個目的: 我的用戶在地理上廣泛分佈,並且鏈接到共享網絡存儲上的文檔並不總是能夠正常工作(不同的地址,DNS條目以及我的控制或興趣之外的東西),所以我正在考慮提供面向數據庫的替代品。 我們有許多文件可以從客戶端解析數據。我寧願能夠把它推到服務器上。

我看過attachment_fu,回形針和另外一個(忘記名字!),所有這些看起來都很像圖像,儘管attachment_fu至少可以在沒有圖像處理庫的情況下工作,謝天謝地。

最大的問題是我的服務器不允許我的應用程序在本地寫文件,而且這些插件似乎都想創建一個Tempfile。

的問題(最終!)

是否有上傳的二進制數據,並在內存中處理它和/或存儲它作爲一個BLOB沒有任何服務器端的文件保存一個合理的方式?

或者我應該放棄文件分發的想法,讓用戶在可能的情況下複製並粘貼文本框的次佳選項?

(最近我能找到的SO是this這並不能真正幫助)

回答

1

最大的問題是我的服務器不允許我的應用程序在本地寫文件,而且這些插件似乎都想創建一個Tempfile。

是的,或者你根本無法上傳文件。

如果上傳的文件大於15k左右,Rails本身會創建臨時文件。

<%= f.file_field :file %> 
.... 
file_param = params[:upload][:file] 

只要你上傳的東西比15K大不久,params[:upload][:file]將是一個ActionController::UploadedTempFile

有什麼區別? Rails可能會將它的臨時文件寫入全局臨時目錄(每個人都可以寫入),但插件可能會嘗試寫入RAILS_ROOT/tmp,這是服務器不允許的。好消息是,你可以將這些東西配置爲使用不同的臨時目錄,以便他們可以編寫臨時文件,而且應該都可以工作。

例如,attachment_fu's default temp path is under rails root.。你應該能夠改變這樣的:

Technoweenie::AttachmentFu.tempfile_path = Dir::tmpdir 

** PS:拉文件數據直出則params的並將其放入數據庫中仍可能是最好的一段路要走。我個人不喜歡attachment_fu,因爲他們試圖做太多的事情,但無論哪種方式,瞭解整個上傳文件/臨時文件如何在rails中工作是非常有用的:-)

+0

啊。所以它確實如此。當然,我的測試上傳文件是13.5K ... 我想知道服務器(gulp)會發生什麼。 – 2008-11-20 13:54:24

1

HowTo爲Rails包括如何直接上傳到數據庫中的部分(靠近頁面末尾)。該部分有些搞砸了,但其要點是,您只需將上傳的文件內容讀入ActiveRecord對象的BLOB字段並保存爲正常。由於我不知道如何在應用程序中使用該文件,因此我無法就如何在數據庫中使用該文件給出任何建議,但在HowTo中也有一段關於從數據庫中下載的部分。

查看是否可以獲得寫入服務器上的單個目錄(可能位於您的Web應用程序文件夾中)的權限可能會更容易。

+0

關於許可的事情 - 它已經被要求了,但是我們的IT人員可以花費很長時間來處理這樣的事情。個月。許多個月。你不會相信建立一個數據庫實例需要多長時間。那麼,也許你會。 – 2008-11-16 11:01:46

7

您可以從params對象讀取數據,並直接寫入模型。

例如,您可以使用這種形式。

<% form_for :upload, :url => {:action=>:upload}, :html=>{:multipart=>true} do |f| %> 
    <%= f.file_field :file %> 
    <%= f.submit 'Upload' %> 
<% end %> 

然後你可以很容易地得到原始文件名和二進制數據。

class TestController < ApplicationController 

    def upload 
    file_param = params[:upload][:file] 
    filename = file_param.original_filename 
    filedata = file_param.read 

    @data = UploadedFile.create(:name => filename, :data => filedata) 

    render :text => "created #{@data.id}" 
    end 

end 

當然你的模型需要有正確的列。

class CreateUploadedFiles < ActiveRecord::Migration 
    def self.up 
    create_table :uploaded_files do |t| 
     t.string :name 
     t.binary :data 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :uploaded_files 
    end 
end 

希望這有助於!

+0

我差點把它 - 我錯過了params上的雙引用[:upload] [:file] 它的作品,應該讓事情變得有趣!謝謝。 – 2008-11-17 10:20:20

0

所以這段代碼在我的控制器:

def upload 
    file_content = params[:upload][:file] 
    render :text => [ 
     [:original_path, :content_type, :local_path, :path, :original_filename].collect {|m| file_content.send(m)}, 
     file_content.class, 
     file_content.size.to_s].flatten.join("<br/>") 
    end 

給出了這樣的一個更小的文件:

b_wib.xls 
application/vnd.ms-excel 


b_wib.xls 
ActionController::UploadedStringIO 
13824 

這對於一個較大:

a_wib.xls 
application/vnd.ms-excel 
/tmp/CGI.10029.1 
/tmp/CGI.10029.1 
a_wib.xls 
ActionController::UploadedTempfile 
27648 

......這與Orion所描述的完全相同。

0

爲別人讀這只是同時保存文件/ IO params中的數據庫是一個很好的解決方案(爲什麼問題複雜化)回形針,我會懷疑attachment_fu,都沒有具體的形象。由於上傳圖像和調整大小非常常見Paperclip附帶一個處理器來調整圖像大小,但默認情況下它未啓用,您可以輕鬆添加自己的處理器。

相關問題