Rails 文件上传
环境: Rails 2.0.2, ruby1.8.7
?
1. 首先在试图中显示上传文件的控件
?
?
<% form_tag({:action => 'uploadfile'}, :multipart => true) do %> Upload your file: <%= file_field("file", "file") %><br/> <%= submit_tag("Upload file") %><% end %>?
?
生成对应的HTML代码
?
?
<form action="/articles/uploadfile" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="a55e0dc95a9a22bef35e9dd4165faa36bb17b802" /></div> Upload your file: <input id="file_file" name="file[file]" size="30" type="file" /> <br/> <input name="commit" type="submit" value="Upload file" /></form>
?
?
生成对应的ation是/articles/uploadfile, 因为定义了Article??类:class Article < ActiveRecord::Base,在article的视图界面使用form_tag就会自动生成对应的action,但是rails自动生成的routes中没有对这样的action进行路由,所以需要在routes文件中添加如下代码:
?
?
map.connect '/articles/uploadfile', :controller => 'articles', :action => 'loadfile'
?
?
这样当进行表单提交的时候,就会触发loadfile,rails就会到class ArticlesController < ApplicationController中查找对应的action,因此对于文件的上传处理应该写在控制器中
?
?
def uploadFile(file) if !file.original_filename.empty? @filename = getfilename(file.original_filename) #设置目录路径,如果目录不存在,生成新目录 FileUtils.mkdir("#{RAILS_ROOT}/db/upload") unless File.exist?("#{RAILS_ROOT}/db/upload") #写入文件 File.open("#{RAILS_ROOT}/db/upload/#{Iconv.iconv("gb2312","utf-8",@filename)}", "wb") do |f| f.write(file.read) end return @filename end end #文件名 def getfilename(filename) if !filename.nil? filename.split(' ').to_s end end def loadfile unless request.get? if filename=uploadFile(params[:file]['file']) render :text=>filename end end end
?
?
如果文件名中包含中文,使用Iconv.iconv("gb2312","utf-8",@filename)进行转换,从params对象中取得上传的文件
params[:file]['file'], 两个file分别对应form_tag中的?file_field("file", "file")?
?
?