📅  最后修改于: 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在发送的文件名中包含了文件的整个路径,因此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参考手册。