Ruby-on-rails 在 Rails 中上传文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14174044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Uploading a file in Rails
提问by max_
I'm new to rails, and I'm writing a RESTful website using the CRUD technique. So far I have created three pages, all of which allow the user to create, edit, and delete a row from the database. However, my fourth page will need to include an upload file form, but a) I don't know how the filesystem works with Rails thus I don't know where files should be stored. The file would be around 100kb and couldn't be stored in temporary storage because it will be constantly downloaded. And b) I don't know how to write to a file.
我是 Rails 的新手,我正在使用 CRUD 技术编写一个 RESTful 网站。到目前为止,我已经创建了三个页面,所有页面都允许用户从数据库中创建、编辑和删除一行。但是,我的第四页需要包含一个上传文件表单,但是 a) 我不知道文件系统如何与 Rails 一起工作,因此我不知道文件应该存储在哪里。该文件将在 100kb 左右,无法存储在临时存储中,因为它会不断下载。b) 我不知道如何写入文件。
It would be great if you could tell me how to do what I mentioned above - create an upload input on an input form, and to then write the file to a filepath in a separate directory.
如果您能告诉我如何执行我上面提到的操作,那就太好了 - 在输入表单上创建上传输入,然后将文件写入单独目录中的文件路径。
回答by fabi
Update 2018
2018 年更新
While everything written below still holds true, Rails 5.2 now includes active_storage, which allows stuff like uploading directly to S3 (or other cloud storage services), image transformations, etc. You should check out the rails guideand decide for yourself what fits your needs.
虽然下面写的所有内容仍然适用,但 Rails 5.2 现在包括active_storage,它允许直接上传到 S3(或其他云存储服务)、图像转换等。您应该查看Rails 指南并自行决定适合您的需求。
While there are plenty of gems that solve file uploading pretty nicely (see https://www.ruby-toolbox.com/categories/rails_file_uploadsfor a list), rails has built-in helpers which make it easy to roll your own solution.
虽然有很多 gem 可以很好地解决文件上传问题(请参阅https://www.ruby-toolbox.com/categories/rails_file_uploads以获取列表),rails 具有内置帮助程序,可以轻松推出您自己的解决方案。
Use the file_field-form helper in your form, and rails handles the uploading for you:
file_field在表单中使用-form 助手,rails 会为您处理上传:
<%= form_for @person do |f| %>
<%= f.file_field :picture %>
<% end %>
You will have access in the controller to the uploaded file as follows:
您将可以在控制器中访问上传的文件,如下所示:
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
It depends on the complexity of what you want to achieve, but this is totally sufficient for easy file uploading/downloading tasks. This example is taken from the rails guides, you can go there for further information: http://guides.rubyonrails.org/form_helpers.html#uploading-files
这取决于您想要实现的复杂性,但这对于简单的文件上传/下载任务来说已经足够了。这个例子取自 rails 指南,你可以去那里了解更多信息:http: //guides.rubyonrails.org/form_helpers.html#uploading-files
回答by Ahmed Elkoussy
Sept 2018
2018 年 9 月
For anyone checking this question recently, Rails 5.2+ now has ActiveStorage by default & I highly recommend checking it out.
对于最近检查此问题的任何人,Rails 5.2+ 现在默认具有 ActiveStorage,我强烈建议您检查一下。
Since it is part of the core Rails 5.2+ now, it is very well integrated & has excellent capabilities out of the box (still all other well-known gems like Carrierwave, Shrine, paperclip,... are great but this one offers very good features that we can consider for any new Rails project)
由于它现在是核心 Rails 5.2+ 的一部分,因此它集成得非常好并且开箱即用具有出色的功能(还有所有其他著名的宝石,如 Carrierwave、Shrine、回形针……都很棒,但这个提供了非常我们可以为任何新的 Rails 项目考虑的好特性)
Paperclip team deprecated the gem in favor of the Rails ActiveStorage.
Paperclip 团队弃用了 gem 以支持 Rails ActiveStorage。
Here is the github page for the ActiveStorage& plenty of resources are available everywhere
这是 ActiveStorage 的 github 页面,到处都有大量资源
Also I found this videoto be very helpful to understand the features of Activestorage
我还发现这个视频对理解 Activestorage 的功能非常有帮助
回答by R Milushev
There is a nice gem especially for uploading files : carrierwave. If the wiki does not help , there is a nice RailsCastabout the best way to use it . Summarizing , there is a field type filein Rails forms , which invokes the file upload dialog. You can use it , but the 'magic' is done by carrierwavegem .
有一个很好的 gem,特别是用于上传文件:carrierwave。如果 wiki 没有帮助,有一个很好的 RailsCast关于使用它的最佳方法。总之,fileRails 表单中有一个字段类型,它调用文件上传对话框。您可以使用它,但“魔法”是由carrierwavegem完成的。
I don't know what do you mean with "how to write to a file" , but I hope this is a nice start.
我不知道“如何写入文件”是什么意思,但我希望这是一个好的开始。
回答by ray
Okay. If you do not want to store the file in database and store in the application, like assets (custom folder), you can define non-db instance variable defined by attr_accessor: document and use form_for - f.file_fieldto get the file,
好的。如果您不想将文件存储在数据库中并存储在应用程序中,例如资产(自定义文件夹),您可以定义由 attr_accessor: document 定义的非数据库实例变量并用于form_for - f.file_field获取文件,
In controller,
在控制器中,
@person = Person.new(person_params)
Here person_paramsreturn whitelisted params[:person](define yourself)
这里person_params返回白名单params[:person](定义你自己)
Save file as,
将文件另存为,
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}")
Note, Add this path in .gitignore& if you want to use this file again add this path asset_pathan of application by application.rb
注意,.gitignore如果你想再次使用这个文件,在&添加这个路径,添加这个asset_path应用程序的路径application.rb
Whenever form read file field, it get store in tmp folder, later you can store at your place, I gave example to store at assets
每当表单读取文件字段时,它都会存储在 tmp 文件夹中,稍后您可以存储在您的位置,我举了一个例子来存储在资产
note: Storing files like this will increase the size of the application, better to store in the database using paperclip.
注意:像这样存储文件会增加应用程序的大小,最好使用paperclip.
回答by Saif chaudhry
In your intiallizer/carrierwave.rb
在你的初始化器/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
use this to store in a file while running on local
在本地运行时使用它来存储在文件中

