iT邦幫忙

DAY 11
13

Rails 的簡單任務系列 第 12

[RoR] 簡單完成上傳功能

檔案上傳下載是用網路必要的功能,不同的需要用不同的方式對應,接下來將以上傳的相關議題,來建立適合單位用的簡易上傳下載功能的網站,並加上簡易的保護功能,來了解 RoR 可以怎麼利用。
最簡易的上傳功能完成
建立一 controller ,這次不用 scaffold 的方式自動建立程式碼:

./script/generate controller upfile index
#vi app/views/upfile/index.html.erb
<%= form_tag({:action=>'save_file'}, :multipart => true)%>
 <input type="file" name="filename" />
 <input type="submit" name="Upload" value="Upload"/>
</form>

上述的第三行是檔案傳上後,由 RoR 的 save_file 的action 來動作,上傳檔名的參數為 filename。

新增修改 upload 的 layouts ,利用之前其他的 layout 為依據修改
cd app/views/layouts/
cp bibles.html.erb upload.html.erb

編寫一下,將上傳檔案後的動作,並存到指定位置

  def save_file
   filename = params['filename'].original_filename
   filewhere = "/home/ironman/test1/public/upload/#{filename}"
   File.open("#{filewhere}", "wb") do |f|
      f.write(params['filename'].read)
   end
   flash[:notice] = "檔案上傳成功,檔名 #{filename}"
   redirect_to :action => 'index'
  end

連上 http://SITENAME/upfile 就可以看到上傳表單,

因剛才上傳的位置是在 public/upload ,對應到網址是 http://SITENAME/upload/檔名,所以只要看得到檔案所在連結,就可以被下載。

建立簡單的連結列表
編輯 app/controllers/upload/index.rb 如下的內容

  def index
    @dir = get_local_list
  end
  
  def save_file
  ...
  end 
  
private
# 將 上傳檔案的目錄中,將檔名讀成一個 array ,除了「本目錄」及「父目錄」之外
def get_local_list
        @dir = []
        dir = Dir.open('./public/upload')
        dir.sort.each do |d|
                if d !~ /^\.*$/
                        @dir << d
                end
        end
        dir.close
return @dir
end
...

再將 app/views/upfile/index.html.erb 再加入下列的行數,就可以馬上讓網頁上有檔案的連結

  <hr noshade width = "90%" color = "red" />
<ul>
<% @dir.each do |file| -%>
<li><%= link_to file, "/upload/#{file}" -%></li>
<% end -%>
</li>


待改進處
建置非常簡單,但會有這些問題:
1.檔案所有人都可看到及下載,這是優點也是缺點。
2.檔名若是中文,會有 Big5、UTF8 及 URL match 不到的問題。
3.若同樣檔名再上傳的話,會覆蓋之前同名的檔案。
4.管理端要去清除較舊的檔案,不是那麼方便,雖然可以用 find 的指令去將幾天前的檔通通刪掉。

接下來將介紹曾經如何以系統管理的方式來解決此問題,以及如何用 RoR 來改寫達到這些需求。


上一篇
[RoR] 簡單做出搜尋功能
下一篇
[RoR] 適單位內外用暫存空間的規畫
系列文
Rails 的簡單任務33

1 則留言

0
gric
iT邦高手 1 級 ‧ 2009-03-13 21:36:11

謝謝分享咯!

我要留言

立即登入留言