手把手学习Rails 文件上传(支持Rails2.3)

You may have a requirement in which you want your site visitors to upload a file on your server. Rails makes it very easy to handle this requirement. Now we will proceed with a simple and small Rails project. 


As usual, let's start off with a new Rails application called upload. So let's create basic structure of the application by using simple rails command. 

Ruby代码   收藏代码
  1. C:\ruby> rails upload  


Now let's decide where you would like to save your uploaded files. Assume this is data directory inside your public section. So create this directory and check the permissions. 

Ruby代码   收藏代码
  1. C:\ruby> cd upload  
  2. C:\ruby> mkdir upload\public\data  


Our next step will be as usual, to create controller and models, so let's do that: 
Creating Model: 

Because this is not a database based application so we can keep name whatever is comfortable to us. Assume we have to create a DataFile model. 

Ruby代码   收藏代码
  1. C:\ruby> ruby script/generate model DataFile  
  2.       exists  app/models/  
  3.       exists  test/unit/  
  4.       exists  test/fixtures/  
  5.       create  app/models/data_file.rb  
  6.       create  test/unit/data_file_test.rb  
  7.       create  test/fixtures/data_files.yml  
  8.       create  db/migrate  
  9.       create  db/migrate/001_create_data_files.rb  


Now we will create a method called save in data_file.rb model file. This method will be called by the application controller. 

Ruby代码   收藏代码
  1. class DataFile < ActiveRecord::Base  
  2.   def self.save(upload)  
  3.     name =  upload['datafile'].original_filename  
  4.     directory = "public/data"  
  5.     # create the file path  
  6.     path = File.join(directory, name)  
  7.     # write the file  
  8.     File.open(path, "wb") { |f| f.write(upload['datafile'].read) }  
  9.   end  
  10. end  


The above function will take CGI object upload and will extract uploaded file name using helper function original_filename and finally it will store uploaded file into "public/data" directory. You can call helper function content_type to know media type of the uploaded file. 

Here File is a ruby object and join is a helper function will concatenate directory name alongwith file name and will return full file path. 

Next, to open a file in write mode we are using open helper function provided by File object. Further we are reading data from the passed data file and writing into output file. 
Creating Controller: 

Now let's create a controller for our upload project: 

Ruby代码   收藏代码
  1. C:\ruby> ruby script/generate controller Upload  
  2.       exists  app/controllers/  
  3.       exists  app/helpers/  
  4.       create  app/views/upload  
  5.       exists  test/functional/  
  6.       create  app/controllers/upload_controller.rb  
  7.       create  test/functional/upload_controller_test.rb  
  8.       create  app/helpers/upload_helper.rb  


Now we will create two controller functions first function index will call a view file to take user input and second function uploadFile takes file information from the user and passes it to the 'DataFile' model. We set the upload directory to the 'uploads' directory we created earlier "directory = 'data'". 

Ruby代码   收藏代码
  1. class UploadController < ApplicationController  
  2.   def index  
  3.      render :file => 'app\views\upload\uploadfile.rhtml'  
  4.   end  
  5.   def uploadFile  
  6.     post = DataFile.save(params[:upload])  
  7.     render :text => "File has been uploaded successfully"  
  8.   end  
  9. end  


Here we are calling function defined in model file. The render function is being used to redirect to view file as well as to display a message. 
Creating View: 

Finally we will create a view file uploadfile.rhtml which we have mentioned in controller. Populate this file with the following code: 

Ruby代码   收藏代码
  1. <h1>File Upload</h1>  
  2. <%= start_form_tag ({:action => 'uploadFile'},   
  3.                         :multipart => true) %>  
  4. <p><label for="upload_file">Select File</label> :   
  5. <%= file_field 'upload''datafile' %></p>  
  6. <%= submit_tag "Upload" %>  
  7. <%= end_form_tag %>  

Here everything is same what we have explained in earlier chapters. Only new tag is file_field which will create a button to select a file from user's computer. 

By setting the multipart parameter to true, you ensure that your action properly passes along the binary data from the file. 

Here important point to note is that we have given uploadFile method name in :action, which will be called when your will click Upload button. 

This will show you a screen as follows: 


 


Now you select a file and upload it, this file will be uploaded into app/public/data directory with the actual file name and a message will be displayed to you saying that "File has been uploaded successfully". 

NOTE: If a file with the same name already exists in your output directory then it will be over-written. 
Files uploaded from Internet Explorer: 

Internet Explorer includes the entire path of a file in the filename sent, so the original_filename routine will return something like: 

C:\Documents and Files\user_name\Pictures\My File.jpg 

instead of just: 

My File.jpg 

This is easily handled by File.basename, which strips out everything before the filename. 

Ruby代码   收藏代码
  1. def sanitize_filename(file_name)  
  2.   # get only the filename, not the whole path (from IE)  
  3.   just_filename = File.basename(file_name)   
  4.   # replace all none alphanumeric, underscore or perioids  
  5.   # with underscore  
  6.   just_filename.sub(/[^\w\.\-]/,'_')   
  7. end  


Deleting an existing File: 

If you want to delete any existing file then its simple and need to write following code: 

Ruby代码   收藏代码
  1. def cleanup  
  2.   File.delete("#{RAILS_ROOT}/dirname/#{@filename}")   
  3.           if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}")  
  4. end  


For a complete detail on File object, you need to go through Ruby Reference Manual.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值