📜  Ruby on Rails 2.1-文件上传

📅  最后修改于: 2020-10-20 05:19:00             🧑  作者: Mango


您可能有一个要求,您的网站访问者必须在服务器上上传文件。 Rails使处理此要求非常容易。现在,我们将继续进行一个简单的小型Rails项目。

和往常一样,让我们从一个名为upload的新Rails应用程序开始。让我们使用简单的rails命令创建应用程序的基本结构。

C:\ruby> rails -d mysql upload

让我们决定您要保存上传文件的位置。假设这是公共部分中的数据目录。因此,创建此目录并检查权限。

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对象,并使用辅助函数original_filename提取上载的文件名,最后将上载的文件存储到“ public / data”目录中。您可以调用辅助函数content_type来了解上载文件的媒体类型。

这里的File是一个ruby对象, join是一个帮助函数,它将目录名和文件名连接起来,并返回完整的文件路径。

接下来,要以写模式打开文件,我们使用File对象提供的open helper函数。此外,我们正在从传递的数据文件中读取数据并将其写入输出文件。

创建控制器

现在,让我们为上传项目创建一个控制器-

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

现在,我们将创建两个控制器功能。第一个函数索引将调用视图文件以接受用户输入,第二个函数uploadFile从用户处获取文件信息并将其传递给’DataFile’模型。我们将上载目录设置为我们之前创建的“目录=’数据’”的“上载”目录。

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 。用以下代码填充该文件-

File Upload

'uploadFile'}, :multipart => true) do %>

:

这里的一切都与我们在前面几章中所解释的相同。唯一的新标签是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参考手册