iThome online | iThome Blog | iThome周刊訂閱

載入中...

twtw

IT邦初學者
9級

[RoR] 以資料庫為依據的上傳下載及列檔功能

依據前一日所提及的目標用 ROR 改寫第十一日的例子,透過資料庫的結合,做出基本的檔案列表、上傳、下載的動作。



收到書籤:發佈到twitter      
分享時間:2008-09-27 04:10:08

▼ ADVERTISEMENT ▼

分享內容(
9

修改儲存檔案的動作
建立一個 model 來將上傳的檔案相關資訊存在該 table 之中:

./script/generate model upfile filename:string filetoken:string filetype:string size:string
rake db:migrate

其中的 filetoken ,是想把任何上傳的檔案另外命名為獨一無二的檔名,不致與其他名稱重覆,所以利用下面這一個 function 來做出供 URL 的獨一檔名代表,以及做為資料庫讀取哪一筆檔案的依據,其實也可以當作permalink的一種。
# vi app/controllers/upfile_controller.rb 加到 private 下面
  def gettoken
   filetoken=Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join)
   return filetoken
  end

利用 http://blog.vixiom.com/2007/12/28/hacking-attachment_fu-to-work-with-flashflex-uploads-and-crop-square-images/所提供的方式,把檔案的屬性讀出來:
# vi app/controllers/upfile_controller.rb 加到 private 下面
  def get_content_type(filewhere)
      content_type = `file -bi "#{filewhere}"`.chomp
      content_type = fallback unless $?.success?
      content_type.gsub!(/;.+$/,"") if content_type
      return content_type
  end

所上傳的檔案放在 /home/ironman/test1/FILES 裡,若檔案放在 public 目錄中則無法達到管控的目的。
修改第十一日的 save_file 的區塊為:
  def save_file
#處理上傳檔案欄是空的情況下鍵入上傳的情形
    if params['filename'].nil? or params['filename'] == ''
     flash[:error] = "沒有檔名!"
     redirect_to :action => 'index'
     return
    end
# 取一個獨一的代表檔名
    @filetoken = gettoken
# 原始檔名
    filename = params['filename'].original_filename
# 指定將存到的位置及檔名
    filewhere = "/home/ironman/test1/FILES/#{@filetoken}"
# 真正的儲存動作
    File.open("#{filewhere}", "wb") do |f|
      f.write(params['filename'].read)
    end
# 讀出該檔的格式、大小為何
    @content_type = get_content_type(filewhere)
    @size = File.size(filewhere)
# 上述所得的檔案資訊存到 table 裡
    Upfile.new
    Upfile.create(:filename => filename,
                :filetoken => @filetoken,
                :filetype => @content_type,
                :size => @size)
    flash[:notice] = "檔案上傳成功! #{@content_type} :: #{@size}"
    redirect_to :action => 'index'
  end

這時上傳成功就會出現檔案屬性及大小的數字來。

這時可看 FILES 的目錄有16進位字串的檔名存在裡面。

建立下載的動作
  def dl
# 從資料庫抓出所 query 的項目,因為不想用檔案的 id 來作參數,而改用 filetoken 做為存取依據
   @dlfile = Upfile.find_by_filetoken(params[:filetoken])
# 如果query的網址,在資料庫中沒此筆資料則中止下載動作,並導回到首頁
   if @dlfile.nil?
    flash[:error] = "沒有這個檔案"
    redirect_to :action => 'index'
    return
   end
# 若無上述中止動作則開始將檔名
     send_file("/home/ironman/test1/FILES/#{@dlfile.filetoken}",
                :filename => "#{@dlfile.filename}",
                :type => "#{@dlfile.filetype}",
                :stream => true,
# 以下的 disposition 兩種選一種用,看是要用儲存檔案的方式,或直接秀在瀏覽器中。
                :disposition => "attachment")
#                :disposition => "inline")
  end

建立檔案列表及下載連結
將所有檔案列出,並以最新上傳的檔案,最先排出來:
# vi app/controllers/upfile_controller.rb
  def index
#    @dir = get_local_list
    @files = Upfile.find(:all, :order => 'created_at desc')
  end

修改 app/views/upfile/index.html.erb 檔
<h1>Upfile#index</h1>
<%= form_tag({:action=>'save_file'}, :multipart => true)%>
 <input type="file" name="filename" />
 <input type="submit" name="Upload" value="Upload"/>
</form>
<hr noshade width = "90%" color = "red" />
<table border=1>
<tr><td>檔名</td><td>格式</td><td>大小</td><td>日期</td></tr>
<% @files.each do |file| -%>
<tr>
<td><%= link_to file.filename, :action => 'dl', :filetoken => file.filetoken -%></td>
<td><%= file.filetype -%></td>
<td><%= file.size -%></td>
<td><%= file.created_at -%></td>
<% end -%>
</tr>
</table>

這樣就可以列出所有可下載的檔案及相關資訊。

截至目前的建置,即可有最簡單的上傳,並有清楚的檔案大小、上傳日期及檔案格式;已經是與第十二日舊的作法有同樣的功能,是因為上傳的各檔都有個別 hash 的16進位的字串作為代表,所以不會有相同檔名覆蓋問題,而且 query 的參數也不致有編碼上的問題。接下來將再加上刪除功能以及改變一些呈獻的畫面。

[RoR] 以資料庫為依據的上傳下載及列檔功能

目前沒有資料

回應

請填寫您的回應,長度限為1,000個字,回應不計點數,也不限使用次數



 

檢舉違規

違規事項:

*補充檢舉理由(可省略),字數不可超過100字

推薦

推薦理由:


*給回答者的鼓勵(可不填),字數不可超過100字

▼ ADVERTISEMENT ▼

熱門標籤

 cisco   crystal   exchange   it   java   javascript   linux   m-power   mail   microsoft   msnlib   msnp15   msnsdk   msn機器人   mysql   nas   oracle   outlook   pmi   pmp   raid   report   sap   server   smartquery   sql   vista   windows   xp   倍力   倍力資訊   免費軟體   國際專案管理師   報表   專案管理   微軟   有話大聲說   活動   省錢   網路   網路儲存   網路管理   網頁安全   網頁設計   資安   資料庫   資訊安全   防毒軟體   2003   2008