我是Rails的新手,并且正在使用CRUD技术编写RESTful网站。到目前为止,我已经创建了三个页面,所有这些页面都允许用户从数据库中创建,编辑和删除一行。但是,我的第四页需要包含一个上传文件表单,但是a)我不知道文件系统如何与Rails一起使用,因此我不知道文件应该存储在哪里。该文件约为100kb,由于会不断下载,因此无法存储在临时存储中。b)我不知道如何写文件。
如果您能告诉我如何做上面提到的事情,那就太好了-在输入表单上创建上载输入,然后将文件写入单独目录中的文件路径。
Answers:
更新2018
尽管下面编写的所有内容仍然适用,但Rails 5.2现在包括active_storage
,它允许诸如直接上传到S3(或其他云存储服务),图像转换等之类的东西。您应该查看Rails指南并自己确定适合您的需求。
尽管有很多宝石可以很好地解决文件上传问题(有关列表,请参见https://www.ruby-toolbox.com/categories/rails_file_uploads),rails具有内置的帮助程序,可以轻松地实现自己的解决方案。
file_field
在您的表单中使用-form helper,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
这取决于您要实现的目标的复杂性,但这对于完成简单的文件上载/下载任务是完全足够的。本示例摘自Rails指南,您可以在此处获取更多信息:http : //guides.rubyonrails.org/form_helpers.html#uploading-files
File.open
(ruby-doc.org/core-1.9.3/File.html#method-c-open)。
wb
代替来使用w
,否则,对于包含非ascii字符的文件,上传可能会失败。
new
控制器的方法?
2018年9月
对于最近检查此问题的任何人,Rails 5.2+现在默认都有ActiveStorage,我强烈建议您检查一下。
由于它现在是核心Rails 5.2+的一部分,因此它具有很好的集成性并具有出色的开箱即用功能(尽管所有其他著名的宝石,如Carrierwave,Shrine,回形针等,都很棒,但是该宝石提供了非常出色的功能)我们可以在任何新的Rails项目中考虑的良好功能)
回形针团队不赞成使用Gems,而是使用Rails ActiveStorage。
这是ActiveStorage的github页面,并且到处都有大量资源
另外,我发现该视频对于了解Activestorage的功能非常有帮助
有一个特别适合上传文件的宝石:carrierwave。如果Wiki不能帮助您,那么RailsCast会提供很好的最佳使用方法。总而言之,file
Rails表单中有一个字段类型,它会调用文件上传对话框。您可以使用它,但是“魔术”是由carrierwave
gem完成的。
我不知道“如何写入文件”是什么意思,但我希望这是一个好的开始。
好的。如果您不想将文件存储在数据库中并存储在应用程序中,例如资产(自定义文件夹),则可以定义attr_accessor:document定义的非数据库实例变量,并用于form_for - f.file_field
获取文件,
在控制器中
@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
。