在Rails中上传文件

时间:2013-01-05 16:53:18

标签: ruby-on-rails ruby file-upload file-io

我是rails的新手,我正在使用CRUD技术编写一个RESTful网站。到目前为止,我已经创建了三个页面,所有这些页面都允许用户从数据库中创建,编辑和删除行。但是,我的第四页需要包含一个上传文件表单,但是a)我不知道文件系统如何与Rails一起工作,因此我不知道文件应该存储在哪里。该文件大约为100kb,无法存储在临时存储中,因为它会不断下载。并且b)我不知道如何写入文件。

如果您能告诉我如何执行上面提到的操作 - 在输入表单上创建上传输入,然后将文件写入单独目录中的文件路径,那将会很棒。

5 个答案:

答案 0 :(得分:116)

更新2018年

虽然下面写的所有内容仍然适用,但Rails 5.2现在包含active_storage,它允许直接上传到S3(或其他云存储服务),图像转换等内容。您应该查看{{3并自己决定什么符合你的需求。


虽然有很多宝石可以很好地解决文件上传问题(请参阅rails guide获取列表),但rails内置了帮助程序,可以轻松推出自己的解决方案。

在表单中使用file_field - 表单助手,rails会为您处理上传:

<%= form_for @person do |f| %>
  <%= f.file_field :picture %>
<% end %>

您将在控制器中访问上传的文件,如下所示:

uploaded_io = params[:person][:picture]
File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
  file.write(uploaded_io.read)
end

这取决于您希望实现的复杂程度,但这足以轻松上传/下载文件。此示例取自导轨指南,您可以访问此处获取更多信息:https://www.ruby-toolbox.com/categories/rails_file_uploads

答案 1 :(得分:4)

2018年9月

对于最近检查此问题的任何人,Rails 5.2+ now has ActiveStorage by default & I highly recommend checking it out.

由于它现在是Rails 5.2+核心的一部分,因此它具有很好的集成性并具有出色的开箱即用功能(仍然,所有其他著名的宝石,如Carrierwave,Shrine,回形针等,都很棒,但这一个提供了非常好的功能,我们可以在任何新的Rails项目中考虑这些功能

Paperclip团队不赞成使用Gem,而是使用Rails ActiveStorage。

Here is the github page for the ActiveStorage和大量资源随处可见

Also I found this video对于了解Activestorage的功能很有帮助

答案 2 :(得分:3)

有一个很好的宝石,特别是上传文件:carrierwave。如果wiki没有帮助,那么有nice RailsCast关于使用它的最佳方式。总而言之,Rails表单中有一个字段类型file,它调用文件上载对话框。你可以使用它,但'魔术'是由carrierwave gem完成的。

我不知道“如何写入文件”是什么意思,但我希望这是一个不错的开始。

答案 3 :(得分:0)

好的。如果您不想将文件存储在数据库中并存储在应用程序中,例如资产(自定义文件夹),则可以定义attr_accessor:document定义的非数据库实例变量,并使用form_for - f.file_field来获取文件,< / p>

在控制器中,

 @person = Person.new(person_params)

这里person_params返回列入白名单的params[:person](定义自己)

将文件另存为,

dir = "#{Rails.root}/app/assets/custom_path"
FileUtils.mkdir(dir) unless File.directory? dir
document = @person.document.document_file_name # check document uploaded params
File.copy_stream(@font.document, "#{dir}/#{document}")

请注意,在.gitignore中添加此路径,如果您想再次使用此文件,请asset_path将此路径application.rb添加到应用程序中

每当表单读取文件字段时,它将存储在tmp文件夹中,以后您可以在自己的位置存储,我举了一个示例来存储在资产中

注释:像这样存储文件会增加应用程序的大小,最好使用paperclip存储在数据库中。

答案 4 :(得分:0)

在您的初始化器/carrierwave.rb中

if Rails.env.development? || Rails.env.test?
    config.storage = :file
    config.root = "#{Rails.root}/public"
    if Rails.env.test?
      CarrierWave.configure do |config|
        config.storage = :file
        config.enable_processing = false
      end
    end
 end

在本地运行时使用它存储在文件中