- 学习 Ruby on Rails
- Rails 2.1 主页
- Rails 2.1 简介
- 导轨 2.1 安装
- Rails 2.1 框架
- Rails 2.1 目录结构
- Rails 2.1 示例
- Rails 2.1 数据库设置
- Rails 2.1 活动记录
- 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
让我们决定您要保存上传的文件的位置。假设这是您的公共部分中的数据目录。因此,创建该目录并检查权限。
C:\ruby> cd upload C:\ruby\upload> mkdir upload\public\data
我们的下一步将像往常一样,创建控制器和模型。
创建模型
由于这不是基于数据库的应用程序,因此我们可以保留任何适合我们的名称。假设我们必须创建一个数据文件模型。
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 对象,并使用辅助函数original_filename提取上传的文件名,最后将上传的文件存储到“public/data”目录中。您可以调用辅助函数content_type来了解上传文件的媒体类型。
这里File是一个 ruby 对象,join是一个辅助函数,它将连接目录名和文件名,并返回完整的文件路径。
接下来,要以写入模式打开文件,我们使用File对象提供的打开辅助函数。此外,我们从传递的数据文件中读取数据并写入输出文件。
创建控制器
现在,让我们为我们的上传项目创建一个控制器 -
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
在这里,我们调用模型文件中定义的函数。渲染函数用于重定向到查看文件以及显示消息。
创建视图
最后,我们将创建一个视图文件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”作为方法名称,当您单击“上传”按钮时将调用该方法。
它将向您显示如下屏幕 -
现在,您选择一个文件并上传。该文件将以实际文件名上传到 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 参考手册。