
- 学习 Ruby on Rails
- Rails 2.1 首页
- Rails 2.1 简介
- Rails 2.1 安装
- Rails 2.1 框架
- Rails 2.1 目录结构
- Rails 2.1 示例
- Rails 2.1 数据库设置
- Rails 2.1 Active Records
- Rails 2.1 数据迁移
- Rails 2.1 控制器
- Rails 2.1 视图
- Rails 2.1 布局
- Rails 2.1 脚手架
- Rails 2.1 和 AJAX
- Rails 2.1 上传文件
- Rails 2.1 发送邮件
- 高级 Ruby on Rails 2.1
- Rails 2.1 RMagick 指南
- Rails 2.1 基本 HTTP 认证
- Rails 2.1 错误处理
- Rails 2.1 路由系统
- Rails 2.1 单元测试
- 高级 Ruby on Rails 2.1
- Rails 2.1 提示与技巧
- 快速参考指南
- 快速参考指南
- Ruby on Rails 2.1 有用资源
- Ruby on Rails 2.1 - 资源
- Ruby on Rails 2.1 - 讨论
Ruby on Rails 2.1 - 文件上传
您可能需要一个让网站访问者将文件上传到服务器的功能。Rails 使得处理此需求非常容易。现在,我们将继续进行一个简单的小型 Rails 项目。
像往常一样,让我们从一个名为 **upload** 的新 Rails 应用程序开始。让我们使用简单的 rails 命令创建一个应用程序的基本结构。
C:\ruby> rails -d mysql upload
让我们决定您希望将上传的文件保存到哪里。假设这是公共部分内的 **data** 目录。因此,请创建此目录并检查权限。
C:\ruby> cd upload C:\ruby\upload> mkdir upload\public\data
我们的下一步将是像往常一样,创建控制器和模型。
创建模型
由于这不是一个基于数据库的应用程序,我们可以保留任何我们觉得方便的名称。假设我们必须创建一个 **DataFile** 模型。
C:\ruby\upload> ruby script/generate model DataFile exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/data_file.rb create test/unit/data_file_test.rb create test/fixtures/data_files.yml create db/migrate create db/migrate/001_create_data_files.rb
现在,我们将在 **data_file.rb** 模型文件中创建一个名为 **save** 的方法。此方法将由应用程序控制器调用。
class DataFile < ActiveRecord::Base def self.save(upload) name = upload['datafile'].original_filename directory = "public/data" # create the file path path = File.join(directory, name) # write the file File.open(path, "wb") { |f| f.write(upload['datafile'].read) } end end
上述函数将接收 CGI 对象 **upload**,并使用辅助函数 **original_filename** 提取上传的文件名,最后将上传的文件存储到“public/data”目录中。您可以调用辅助函数 **content_type** 来了解上传文件的媒体类型。
这里 **File** 是一个 Ruby 对象,**join** 是一个辅助函数,它将连接目录名和文件名,并返回完整的文件路径。
接下来,要以写入模式打开文件,我们使用 **File** 对象提供的 open 辅助函数。此外,我们正在读取传递的数据文件中的数据并写入输出文件。
创建控制器
现在,让我们为我们的上传项目创建一个控制器:
C:\ruby\upload> ruby script/generate controller Upload exists app/controllers/ exists app/helpers/ create app/views/upload exists test/functional/ create app/controllers/upload_controller.rb create test/functional/upload_controller_test.rb create app/helpers/upload_helper.rb
现在,我们将创建两个控制器函数。第一个函数 **index** 将调用一个视图文件来获取用户输入,第二个函数 **uploadFile** 从用户那里获取文件信息并将其传递给“DataFile”模型。我们将上传目录设置为我们之前创建的“uploads”目录“directory = 'data'”。
class UploadController < ApplicationController def index render :file => 'app\views\upload\uploadfile.html.erb' end def uploadFile post = DataFile.save( params[:upload]) render :text => "File has been uploaded successfully" end end
在这里,我们调用了在模型文件中定义的函数。**render** 函数用于重定向到视图文件以及显示消息。
Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.
创建视图
最后,我们将创建一个视图文件 **uploadfile.rhtml**,我们在控制器中提到了它。使用以下代码填充此文件:
<h1>File Upload</h1> <% form_tag ({:action => 'uploadFile'}, :multipart => true) do %> <p><label for="upload_file">Select File</label> : <%= file_field 'upload', 'datafile' %></p> <%= submit_tag "Upload" %> <% end %>
这里所有内容都与我们在前面章节中解释的内容相同。唯一的新标签是 **file_field**,它将创建一个按钮,用于从用户的计算机中选择文件。
通过将 multipart 参数设置为 true,您可以确保您的操作正确地传递文件的二进制数据。
这里需要注意的一点是,我们在 **:action** 中将 **"uploadFile"** 指定为方法名称,当您单击 **Upload** 按钮时将调用此方法。
它将向您显示如下屏幕:

现在,您选择一个文件并上传它。此文件将以实际文件名上传到 app/public/data 目录中,并将显示一条消息,提示“文件已成功上传”。
**注意** - 如果输出目录中已存在同名文件,则将覆盖该文件。
从 Internet Explorer 上传的文件
Internet Explorer 在发送的文件名中包含文件的完整路径,因此 **original_filename** 例程将返回类似以下内容:
C:\Documents and Files\user_name\Pictures\My File.jpg
而不是:
My File.jpg
这很容易通过 **File.basename** 来处理,它会去除文件名之前的任何内容。
def sanitize_filename(file_name) # get only the filename, not the whole path (from IE) just_filename = File.basename(file_name) # replace all none alphanumeric, underscore or perioids # with underscore just_filename.sub(/[^\w\.\-]/,'_') end
删除现有文件
如果您想删除任何现有文件,这非常简单。您只需编写以下代码:
def cleanup File.delete("#{RAILS_ROOT}/dirname/#{@filename}") if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}") end
有关 **File** 对象的完整详细信息,您需要阅读我们的 **Ruby 参考手册**。